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/fcfs-wifi-queue-scheduler.h"
21#include "ns3/he-configuration.h"
22#include "ns3/ht-configuration.h"
23#include "ns3/ht-frame-exchange-manager.h"
24#include "ns3/interference-helper.h"
25#include "ns3/mac-tx-middle.h"
26#include "ns3/mobility-helper.h"
27#include "ns3/mpdu-aggregator.h"
28#include "ns3/msdu-aggregator.h"
29#include "ns3/node-container.h"
30#include "ns3/packet-socket-client.h"
31#include "ns3/packet-socket-helper.h"
32#include "ns3/packet-socket-server.h"
33#include "ns3/pointer.h"
34#include "ns3/simulator.h"
35#include "ns3/sta-wifi-mac.h"
36#include "ns3/string.h"
37#include "ns3/test.h"
38#include "ns3/vht-configuration.h"
39#include "ns3/wifi-default-ack-manager.h"
40#include "ns3/wifi-default-protection-manager.h"
41#include "ns3/wifi-mac-queue.h"
42#include "ns3/wifi-net-device.h"
43#include "ns3/wifi-psdu.h"
44#include "ns3/yans-wifi-helper.h"
45#include "ns3/yans-wifi-phy.h"
46#include <ns3/attribute-container.h>
47
48#include <algorithm>
49#include <iterator>
50
51using namespace ns3;
52
60{
61 public:
63
64 private:
72
73 void DoRun() override;
80};
81
83 : TestCase("Check the correctness of MPDU aggregation operations"),
84 m_discarded(false)
85{
86}
87
88void
90{
91 m_discarded = true;
92}
93
94void
96{
97 /*
98 * Create device and attach HT configuration.
99 */
100 m_device = CreateObject<WifiNetDevice>();
101 Ptr<HtConfiguration> htConfiguration = CreateObject<HtConfiguration>();
102 m_device->SetHtConfiguration(htConfiguration);
103
104 /*
105 * Create and configure phy layer.
106 */
107 m_phy = CreateObject<YansWifiPhy>();
108 Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper>();
109 m_phy->SetInterferenceHelper(interferenceHelper);
113
114 /*
115 * Create and configure manager.
116 */
118 m_factory.SetTypeId("ns3::ConstantRateWifiManager");
119 m_factory.Set("DataMode", StringValue("HtMcs7"));
123
124 /*
125 * Create and configure mac layer.
126 */
127 m_mac = CreateObjectWithAttributes<StaWifiMac>("QosSupported", BooleanValue(true));
130 m_mac->SetAddress(Mac48Address("00:00:00:00:00:01"));
134 Ptr<WifiProtectionManager> protectionManager = CreateObject<WifiDefaultProtectionManager>();
135 protectionManager->SetWifiMac(m_mac);
136 fem->SetProtectionManager(protectionManager);
137 Ptr<WifiAckManager> ackManager = CreateObject<WifiDefaultAckManager>();
138 ackManager->SetWifiMac(m_mac);
139 fem->SetAckManager(ackManager);
142 m_mac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
143
144 /*
145 * Configure MPDU aggregation.
146 */
147 m_mac->SetAttribute("BE_MaxAmpduSize", UintegerValue(65535));
148 HtCapabilities htCapabilities;
149 htCapabilities.SetMaxAmpduLength(65535);
150 m_manager->AddStationHtCapabilities(Mac48Address("00:00:00:00:00:02"), htCapabilities);
151 m_manager->AddStationHtCapabilities(Mac48Address("00:00:00:00:00:03"), htCapabilities);
152
153 /*
154 * Create a dummy packet of 1500 bytes and fill mac header fields.
155 */
156 Ptr<const Packet> pkt = Create<Packet>(1500);
157 Ptr<Packet> currentAggregatedPacket = Create<Packet>();
158 WifiMacHeader hdr;
159 hdr.SetAddr1(Mac48Address("00:00:00:00:00:02"));
160 hdr.SetAddr2(Mac48Address("00:00:00:00:00:01"));
162 hdr.SetQosTid(0);
163 hdr.SetFragmentNumber(0);
164 hdr.SetNoMoreFragments();
165 hdr.SetNoRetry();
166
167 /*
168 * Establish agreement.
169 */
171 reqHdr.SetImmediateBlockAck();
172 reqHdr.SetTid(0);
173 reqHdr.SetBufferSize(64);
174 reqHdr.SetTimeout(0);
175 reqHdr.SetStartingSequence(0);
176 m_mac->GetBEQueue()->GetBaManager()->CreateOriginatorAgreement(reqHdr, hdr.GetAddr1());
177
179 StatusCode code;
180 code.SetSuccess();
181 respHdr.SetStatusCode(code);
182 respHdr.SetAmsduSupport(reqHdr.IsAmsduSupported());
183 respHdr.SetImmediateBlockAck();
184 respHdr.SetTid(reqHdr.GetTid());
185 respHdr.SetBufferSize(64);
186 respHdr.SetTimeout(reqHdr.GetTimeout());
187 m_mac->GetBEQueue()->GetBaManager()->UpdateOriginatorAgreement(respHdr, hdr.GetAddr1(), 0);
188
189 //-----------------------------------------------------------------------------------------------------
190
191 /*
192 * Test behavior when no other packets are in the queue
193 */
194 Ptr<HtFrameExchangeManager> htFem = DynamicCast<HtFrameExchangeManager>(fem);
195 Ptr<MpduAggregator> mpduAggregator = htFem->GetMpduAggregator();
196
197 m_mac->GetBEQueue()->GetWifiMacQueue()->Enqueue(Create<WifiMpdu>(pkt, hdr));
198
200 WifiTxParameters txParams;
201 txParams.m_txVector =
202 m_mac->GetWifiRemoteStationManager()->GetDataTxVector(peeked->GetHeader(),
204 Ptr<WifiMpdu> item =
205 m_mac->GetBEQueue()->GetNextMpdu(SINGLE_LINK_OP_ID, peeked, txParams, Time::Min(), true);
206
207 auto mpduList = mpduAggregator->GetNextAmpdu(item, txParams, Time::Min());
208
209 NS_TEST_EXPECT_MSG_EQ(mpduList.empty(), true, "a single packet should not result in an A-MPDU");
210
211 // the packet has not been "transmitted", release its sequence number
212 m_mac->m_txMiddle->SetSequenceNumberFor(&item->GetHeader());
213 item->UnassignSeqNo();
214
215 //-----------------------------------------------------------------------------------------------------
216
217 /*
218 * Test behavior when 2 more packets are in the queue
219 */
220 Ptr<const Packet> pkt1 = Create<Packet>(1500);
221 Ptr<const Packet> pkt2 = Create<Packet>(1500);
222 WifiMacHeader hdr1;
223 WifiMacHeader hdr2;
224
225 hdr1.SetAddr1(Mac48Address("00:00:00:00:00:02"));
226 hdr1.SetAddr2(Mac48Address("00:00:00:00:00:01"));
228 hdr1.SetQosTid(0);
229
230 hdr2.SetAddr1(Mac48Address("00:00:00:00:00:02"));
231 hdr2.SetAddr2(Mac48Address("00:00:00:00:00:01"));
233 hdr2.SetQosTid(0);
234
235 m_mac->GetBEQueue()->GetWifiMacQueue()->Enqueue(Create<WifiMpdu>(pkt1, hdr1));
236 m_mac->GetBEQueue()->GetWifiMacQueue()->Enqueue(Create<WifiMpdu>(pkt2, hdr2));
237
238 item = m_mac->GetBEQueue()->GetNextMpdu(SINGLE_LINK_OP_ID, peeked, txParams, Time::Min(), true);
239 mpduList = mpduAggregator->GetNextAmpdu(item, txParams, Time::Min());
240
241 NS_TEST_EXPECT_MSG_EQ(mpduList.empty(), false, "MPDU aggregation failed");
242
243 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(mpduList);
244 htFem->DequeuePsdu(psdu);
245
246 NS_TEST_EXPECT_MSG_EQ(psdu->GetSize(), 4606, "A-MPDU size is not correct");
247 NS_TEST_EXPECT_MSG_EQ(mpduList.size(), 3, "A-MPDU should contain 3 MPDUs");
249 0,
250 "queue should be empty");
251
252 for (uint32_t i = 0; i < psdu->GetNMpdus(); i++)
253 {
254 NS_TEST_EXPECT_MSG_EQ(psdu->GetHeader(i).GetSequenceNumber(), i, "wrong sequence number");
255 }
256
257 //-----------------------------------------------------------------------------------------------------
258
259 /*
260 * Test behavior when the 802.11n station and another non-QoS station are associated to the AP.
261 * The AP sends an A-MPDU to the 802.11n station followed by the last retransmission of a
262 * non-QoS data frame to the non-QoS station. This is used to reproduce bug 2224.
263 */
264 pkt1 = Create<Packet>(1500);
265 pkt2 = Create<Packet>(1500);
266 hdr1.SetAddr1(Mac48Address("00:00:00:00:00:02"));
267 hdr1.SetAddr2(Mac48Address("00:00:00:00:00:01"));
269 hdr1.SetQosTid(0);
270 hdr1.SetSequenceNumber(3);
271 hdr2.SetAddr1(Mac48Address("00:00:00:00:00:03"));
272 hdr2.SetAddr2(Mac48Address("00:00:00:00:00:01"));
274 hdr2.SetQosTid(0);
275
276 Ptr<const Packet> pkt3 = Create<Packet>(1500);
277 WifiMacHeader hdr3;
278 hdr3.SetSequenceNumber(0);
279 hdr3.SetAddr1(Mac48Address("00:00:00:00:00:03"));
280 hdr3.SetAddr2(Mac48Address("00:00:00:00:00:01"));
282 hdr3.SetQosTid(0);
283
284 m_mac->GetBEQueue()->GetWifiMacQueue()->Enqueue(Create<WifiMpdu>(pkt1, hdr1));
285 m_mac->GetBEQueue()->GetWifiMacQueue()->Enqueue(Create<WifiMpdu>(pkt2, hdr2));
286 m_mac->GetBEQueue()->GetWifiMacQueue()->Enqueue(Create<WifiMpdu>(pkt3, hdr3));
287
289 txParams.Clear();
290 txParams.m_txVector =
291 m_mac->GetWifiRemoteStationManager()->GetDataTxVector(peeked->GetHeader(),
293 item = m_mac->GetBEQueue()->GetNextMpdu(SINGLE_LINK_OP_ID, peeked, txParams, Time::Min(), true);
294
295 mpduList = mpduAggregator->GetNextAmpdu(item, txParams, Time::Min());
296
297 NS_TEST_EXPECT_MSG_EQ(mpduList.empty(),
298 true,
299 "a single packet for this destination should not result in an A-MPDU");
300 // dequeue the MPDU
301 htFem->DequeueMpdu(item);
302
304 txParams.Clear();
305 txParams.m_txVector =
306 m_mac->GetWifiRemoteStationManager()->GetDataTxVector(peeked->GetHeader(),
308 item = m_mac->GetBEQueue()->GetNextMpdu(SINGLE_LINK_OP_ID, peeked, txParams, Time::Min(), true);
309
310 mpduList = mpduAggregator->GetNextAmpdu(item, txParams, Time::Min());
311
312 NS_TEST_EXPECT_MSG_EQ(mpduList.empty(),
313 true,
314 "no MPDU aggregation should be performed if there is no agreement");
315
317 0); // set to 0 in order to fake that the maximum number of retries has been reached
318 m_mac->TraceConnectWithoutContext("DroppedMpdu",
320 htFem->m_dcf = m_mac->GetBEQueue();
321 htFem->NormalAckTimeout(item, txParams.m_txVector);
322
323 NS_TEST_EXPECT_MSG_EQ(m_discarded, true, "packet should be discarded");
324 m_mac->GetBEQueue()->GetWifiMacQueue()->Flush();
325
327
329 m_manager = nullptr;
330
331 m_device->Dispose();
332 m_device = nullptr;
333
334 htConfiguration = nullptr;
335}
336
344{
345 public:
347
348 private:
349 void DoRun() override;
355};
356
358 : TestCase("Check the correctness of two-level aggregation operations")
359{
360}
361
362void
364{
365 /*
366 * Create device and attach HT configuration.
367 */
368 m_device = CreateObject<WifiNetDevice>();
370 Ptr<HtConfiguration> htConfiguration = CreateObject<HtConfiguration>();
371 m_device->SetHtConfiguration(htConfiguration);
372
373 /*
374 * Create and configure phy layer.
375 */
376 m_phy = CreateObject<YansWifiPhy>();
377 Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper>();
378 m_phy->SetInterferenceHelper(interferenceHelper);
382
383 /*
384 * Create and configure manager.
385 */
387 m_factory.SetTypeId("ns3::ConstantRateWifiManager");
388 m_factory.Set("DataMode", StringValue("HtMcs7"));
392
393 /*
394 * Create and configure mac layer.
395 */
396 m_mac = CreateObjectWithAttributes<StaWifiMac>("QosSupported", BooleanValue(true));
399 m_mac->SetAddress(Mac48Address("00:00:00:00:00:01"));
403 Ptr<WifiProtectionManager> protectionManager = CreateObject<WifiDefaultProtectionManager>();
404 protectionManager->SetWifiMac(m_mac);
405 fem->SetProtectionManager(protectionManager);
406 Ptr<WifiAckManager> ackManager = CreateObject<WifiDefaultAckManager>();
407 ackManager->SetWifiMac(m_mac);
408 fem->SetAckManager(ackManager);
411 m_mac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
412
413 /*
414 * Configure aggregation.
415 */
416 m_mac->SetAttribute("BE_MaxAmsduSize", UintegerValue(4095));
417 m_mac->SetAttribute("BE_MaxAmpduSize", UintegerValue(65535));
418 HtCapabilities htCapabilities;
419 htCapabilities.SetMaxAmsduLength(7935);
420 htCapabilities.SetMaxAmpduLength(65535);
421 m_manager->AddStationHtCapabilities(Mac48Address("00:00:00:00:00:02"), htCapabilities);
422
423 /*
424 * Create dummy packets of 1500 bytes and fill mac header fields that will be used for the
425 * tests.
426 */
427 Ptr<const Packet> pkt = Create<Packet>(1500);
428 WifiMacHeader hdr;
429 hdr.SetAddr1(Mac48Address("00:00:00:00:00:02"));
430 hdr.SetAddr2(Mac48Address("00:00:00:00:00:01"));
432 hdr.SetQosTid(0);
433
434 //-----------------------------------------------------------------------------------------------------
435
436 /*
437 * Test MSDU and MPDU aggregation. Three MSDUs are in the queue and the maximum A-MSDU size
438 * is such that only two MSDUs can be aggregated. Therefore, the first MPDU we get contains
439 * an A-MSDU of 2 MSDUs.
440 */
441 Ptr<HtFrameExchangeManager> htFem = DynamicCast<HtFrameExchangeManager>(fem);
442 Ptr<MsduAggregator> msduAggregator = htFem->GetMsduAggregator();
443 Ptr<MpduAggregator> mpduAggregator = htFem->GetMpduAggregator();
444
445 m_mac->GetBEQueue()->GetWifiMacQueue()->Enqueue(Create<WifiMpdu>(Create<Packet>(1500), hdr));
446 m_mac->GetBEQueue()->GetWifiMacQueue()->Enqueue(Create<WifiMpdu>(Create<Packet>(1500), hdr));
447 m_mac->GetBEQueue()->GetWifiMacQueue()->Enqueue(Create<WifiMpdu>(Create<Packet>(1500), hdr));
448
450 WifiTxParameters txParams;
451 txParams.m_txVector =
452 m_mac->GetWifiRemoteStationManager()->GetDataTxVector(peeked->GetHeader(),
454 htFem->TryAddMpdu(peeked, txParams, Time::Min());
455 Ptr<WifiMpdu> item = msduAggregator->GetNextAmsdu(peeked, txParams, Time::Min());
456
457 bool result{item};
458 NS_TEST_EXPECT_MSG_EQ(result, true, "aggregation failed");
459 NS_TEST_EXPECT_MSG_EQ(item->GetPacketSize(), 3030, "wrong packet size");
460
461 // dequeue the MSDUs
462 htFem->DequeueMpdu(item);
463
465 1,
466 "Unexpected number of MSDUs left in the EDCA queue");
467
468 //-----------------------------------------------------------------------------------------------------
469
470 /*
471 * A-MSDU aggregation fails when there is just one MSDU in the queue.
472 */
473
475 txParams.Clear();
476 txParams.m_txVector =
477 m_mac->GetWifiRemoteStationManager()->GetDataTxVector(peeked->GetHeader(),
479 htFem->TryAddMpdu(peeked, txParams, Time::Min());
480 item = msduAggregator->GetNextAmsdu(peeked, txParams, Time::Min());
481
482 NS_TEST_EXPECT_MSG_EQ(item, nullptr, "A-MSDU aggregation did not fail");
483
484 htFem->DequeueMpdu(peeked);
485
487 0,
488 "queue should be empty");
489
490 //-----------------------------------------------------------------------------------------------------
491
492 /*
493 * Aggregation of MPDUs is stopped to prevent that the PPDU duration exceeds the TXOP limit.
494 * In this test, the VI AC is used, which has a default TXOP limit of 3008 microseconds.
495 */
496
497 // Establish agreement.
498 uint8_t tid = 5;
500 reqHdr.SetImmediateBlockAck();
501 reqHdr.SetTid(tid);
502 reqHdr.SetBufferSize(64);
503 reqHdr.SetTimeout(0);
504 reqHdr.SetStartingSequence(0);
505 m_mac->GetVIQueue()->GetBaManager()->CreateOriginatorAgreement(reqHdr, hdr.GetAddr1());
506
508 StatusCode code;
509 code.SetSuccess();
510 respHdr.SetStatusCode(code);
511 respHdr.SetAmsduSupport(reqHdr.IsAmsduSupported());
512 respHdr.SetImmediateBlockAck();
513 respHdr.SetTid(reqHdr.GetTid());
514 respHdr.SetBufferSize(64);
515 respHdr.SetTimeout(reqHdr.GetTimeout());
516 m_mac->GetVIQueue()->GetBaManager()->UpdateOriginatorAgreement(respHdr, hdr.GetAddr1(), 0);
517
518 m_mac->SetAttribute("VI_MaxAmsduSize", UintegerValue(3050)); // max 2 MSDUs per A-MSDU
519 m_mac->SetAttribute("VI_MaxAmpduSize", UintegerValue(65535));
521 "TxopLimits",
522 AttributeContainerValue<TimeValue>(std::vector<Time>{MicroSeconds(3008)}));
523 m_manager->SetAttribute("DataMode", StringValue("HtMcs2")); // 19.5Mbps
524
525 hdr.SetQosTid(tid);
526
527 // Add 10 MSDUs to the EDCA queue
528 for (uint8_t i = 0; i < 10; i++)
529 {
530 m_mac->GetVIQueue()->GetWifiMacQueue()->Enqueue(
531 Create<WifiMpdu>(Create<Packet>(1300), hdr));
532 }
533
535 txParams.Clear();
536 txParams.m_txVector =
537 m_mac->GetWifiRemoteStationManager()->GetDataTxVector(peeked->GetHeader(),
539 Time txopLimit = m_mac->GetVIQueue()->GetTxopLimit(); // 3.008 ms
540
541 // Compute the first MPDU to be aggregated in an A-MPDU. It must contain an A-MSDU
542 // aggregating two MSDUs
543 item = m_mac->GetVIQueue()->GetNextMpdu(SINGLE_LINK_OP_ID, peeked, txParams, txopLimit, true);
544
545 NS_TEST_EXPECT_MSG_EQ(std::distance(item->begin(), item->end()),
546 2,
547 "There must be 2 MSDUs in the A-MSDU");
548
549 auto mpduList = mpduAggregator->GetNextAmpdu(item, txParams, txopLimit);
550
551 // The maximum number of bytes that can be transmitted in a TXOP is (approximately, as we
552 // do not consider that the preamble is transmitted at a different rate):
553 // 19.5 Mbps * 3.008 ms = 7332 bytes
554 // Given that the max A-MSDU size is set to 3050, an A-MSDU will contain two MSDUs and have
555 // a size of 2 * 1300 (MSDU size) + 2 * 14 (A-MSDU subframe header size) + 2 (one padding field)
556 // = 2630 bytes Hence, we expect that the A-MPDU will consist of:
557 // - 2 MPDUs containing each an A-MSDU. The size of each MPDU is 2630 (A-MSDU) + 30
558 // (header+trailer) = 2660
559 // - 1 MPDU containing a single MSDU. The size of such MPDU is 1300 (MSDU) + 30 (header+trailer)
560 // = 1330 The size of the A-MPDU is 4 + 2660 + 4 + 2660 + 4 + 1330 = 6662
561 NS_TEST_EXPECT_MSG_EQ(mpduList.empty(), false, "aggregation failed");
562 NS_TEST_EXPECT_MSG_EQ(mpduList.size(), 3, "Unexpected number of MPDUs in the A-MPDU");
563 NS_TEST_EXPECT_MSG_EQ(mpduList.at(0)->GetSize(), 2660, "Unexpected size of the first MPDU");
564 NS_TEST_EXPECT_MSG_EQ(mpduList.at(1)->GetSize(), 2660, "Unexpected size of the second MPDU");
565 NS_TEST_EXPECT_MSG_EQ(mpduList.at(2)->GetSize(), 1330, "Unexpected size of the first MPDU");
566
567 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(mpduList);
568 htFem->DequeuePsdu(psdu);
569
571 5,
572 "Unexpected number of MSDUs left in the EDCA queue");
573
574 NS_TEST_EXPECT_MSG_EQ(psdu->GetSize(), 6662, "Unexpected size of the A-MPDU");
575
577
578 m_device->Dispose();
579 m_device = nullptr;
580 htConfiguration = nullptr;
581}
582
591{
592 public:
594
595 private:
596 void DoRun() override;
602 void DoRunSubTest(uint16_t bufferSize);
608};
609
611 : TestCase("Check the correctness of 802.11ax aggregation operations")
612{
613}
614
615void
617{
618 /*
619 * Create device and attach configurations.
620 */
621 m_device = CreateObject<WifiNetDevice>();
622 Ptr<HtConfiguration> htConfiguration = CreateObject<HtConfiguration>();
623 m_device->SetHtConfiguration(htConfiguration);
624 Ptr<VhtConfiguration> vhtConfiguration = CreateObject<VhtConfiguration>();
625 m_device->SetVhtConfiguration(vhtConfiguration);
626 Ptr<HeConfiguration> heConfiguration = CreateObject<HeConfiguration>();
627 m_device->SetHeConfiguration(heConfiguration);
628
629 /*
630 * Create and configure phy layer.
631 */
632 m_phy = CreateObject<YansWifiPhy>();
633 Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper>();
634 m_phy->SetInterferenceHelper(interferenceHelper);
638
639 /*
640 * Create and configure manager.
641 */
643 m_factory.SetTypeId("ns3::ConstantRateWifiManager");
644 m_factory.Set("DataMode", StringValue("HeMcs11"));
648
649 /*
650 * Create and configure mac layer.
651 */
652 m_mac = CreateObjectWithAttributes<StaWifiMac>("QosSupported", BooleanValue(true));
655 m_mac->SetAddress(Mac48Address("00:00:00:00:00:01"));
659 Ptr<WifiProtectionManager> protectionManager = CreateObject<WifiDefaultProtectionManager>();
660 protectionManager->SetWifiMac(m_mac);
661 fem->SetProtectionManager(protectionManager);
662 Ptr<WifiAckManager> ackManager = CreateObject<WifiDefaultAckManager>();
663 ackManager->SetWifiMac(m_mac);
664 fem->SetAckManager(ackManager);
667 m_mac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
668
669 /*
670 * Configure aggregation.
671 */
672 HeCapabilities heCapabilities;
673 m_manager->AddStationHeCapabilities(Mac48Address("00:00:00:00:00:02"), heCapabilities);
674
675 /*
676 * Fill mac header fields.
677 */
678 WifiMacHeader hdr;
679 hdr.SetAddr1(Mac48Address("00:00:00:00:00:02"));
680 hdr.SetAddr2(Mac48Address("00:00:00:00:00:01"));
682 hdr.SetQosTid(0);
683 uint16_t sequence = m_mac->m_txMiddle->PeekNextSequenceNumberFor(&hdr);
684 hdr.SetSequenceNumber(sequence);
685 hdr.SetFragmentNumber(0);
686 hdr.SetNoMoreFragments();
687 hdr.SetNoRetry();
688
689 /*
690 * Establish agreement.
691 */
693 reqHdr.SetImmediateBlockAck();
694 reqHdr.SetTid(0);
695 reqHdr.SetBufferSize(bufferSize);
696 reqHdr.SetTimeout(0);
697 reqHdr.SetStartingSequence(0);
698 m_mac->GetBEQueue()->GetBaManager()->CreateOriginatorAgreement(reqHdr, hdr.GetAddr1());
699
701 StatusCode code;
702 code.SetSuccess();
703 respHdr.SetStatusCode(code);
704 respHdr.SetAmsduSupport(reqHdr.IsAmsduSupported());
705 respHdr.SetImmediateBlockAck();
706 respHdr.SetTid(reqHdr.GetTid());
707 respHdr.SetBufferSize(bufferSize);
708 respHdr.SetTimeout(reqHdr.GetTimeout());
709 m_mac->GetBEQueue()->GetBaManager()->UpdateOriginatorAgreement(respHdr, hdr.GetAddr1(), 0);
710
711 /*
712 * Test behavior when 300 packets are ready for transmission but negotiated buffer size is 64
713 */
714 Ptr<HtFrameExchangeManager> htFem = DynamicCast<HtFrameExchangeManager>(fem);
715 Ptr<MpduAggregator> mpduAggregator = htFem->GetMpduAggregator();
716
717 for (uint16_t i = 0; i < 300; i++)
718 {
719 Ptr<const Packet> pkt = Create<Packet>(100);
720 WifiMacHeader hdr;
721
722 hdr.SetAddr1(Mac48Address("00:00:00:00:00:02"));
723 hdr.SetAddr2(Mac48Address("00:00:00:00:00:01"));
725 hdr.SetQosTid(0);
726
727 m_mac->GetBEQueue()->GetWifiMacQueue()->Enqueue(Create<WifiMpdu>(pkt, hdr));
728 }
729
731 WifiTxParameters txParams;
732 txParams.m_txVector =
733 m_mac->GetWifiRemoteStationManager()->GetDataTxVector(peeked->GetHeader(),
735 Ptr<WifiMpdu> item =
736 m_mac->GetBEQueue()->GetNextMpdu(SINGLE_LINK_OP_ID, peeked, txParams, Time::Min(), true);
737
738 auto mpduList = mpduAggregator->GetNextAmpdu(item, txParams, Time::Min());
739 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(mpduList);
740 htFem->DequeuePsdu(psdu);
741
742 NS_TEST_EXPECT_MSG_EQ(mpduList.empty(), false, "MPDU aggregation failed");
743 NS_TEST_EXPECT_MSG_EQ(mpduList.size(),
744 bufferSize,
745 "A-MPDU should contain " << bufferSize << " MPDUs");
746 uint16_t expectedRemainingPacketsInQueue = 300 - bufferSize;
748 expectedRemainingPacketsInQueue,
749 "queue should contain 300 - " << bufferSize << " = "
750 << expectedRemainingPacketsInQueue
751 << " packets");
752
754
756 m_manager = nullptr;
757
758 m_device->Dispose();
759 m_device = nullptr;
760
761 htConfiguration = nullptr;
762 vhtConfiguration = nullptr;
763 heConfiguration = nullptr;
764}
765
766void
768{
769 DoRunSubTest(64);
770 DoRunSubTest(256);
771}
772
793{
794 public:
796 ~PreservePacketsInAmpdus() override;
797
798 void DoRun() override;
799
800 private:
801 std::list<Ptr<const Packet>> m_packetList;
802 std::vector<std::size_t> m_nMpdus;
803 std::vector<std::size_t> m_nMsdus;
804
816 void NotifyPsduForwardedDown(WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW);
822};
823
825 : TestCase("Test case to check that the Wifi Mac forwards up the same packets received at "
826 "sender side.")
827{
828}
829
831{
832}
833
834void
836{
837 m_packetList.push_back(packet);
838}
839
840void
842 WifiTxVector txVector,
843 double txPowerW)
844{
845 NS_TEST_EXPECT_MSG_EQ((psduMap.size() == 1 && psduMap.begin()->first == SU_STA_ID),
846 true,
847 "No DL MU PPDU expected");
848
849 if (!psduMap[SU_STA_ID]->GetHeader(0).IsQosData())
850 {
851 return;
852 }
853
854 m_nMpdus.push_back(psduMap[SU_STA_ID]->GetNMpdus());
855
856 for (auto& mpdu : *PeekPointer(psduMap[SU_STA_ID]))
857 {
858 std::size_t dist = std::distance(mpdu->begin(), mpdu->end());
859 // the list of aggregated MSDUs is empty if the MPDU includes a non-aggregated MSDU
860 m_nMsdus.push_back(dist > 0 ? dist : 1);
861 }
862}
863
864void
866{
867 auto it = std::find(m_packetList.begin(), m_packetList.end(), p);
868 NS_TEST_EXPECT_MSG_EQ((it != m_packetList.end()), true, "Packet being forwarded up not found");
869 m_packetList.erase(it);
870}
871
872void
874{
875 NodeContainer wifiStaNode;
876 wifiStaNode.Create(1);
877
878 NodeContainer wifiApNode;
879 wifiApNode.Create(1);
880
883 phy.SetChannel(channel.Create());
884
885 WifiHelper wifi;
886 wifi.SetStandard(WIFI_STANDARD_80211n);
887 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
888
889 WifiMacHelper mac;
890 Ssid ssid = Ssid("ns-3-ssid");
891 mac.SetType("ns3::StaWifiMac",
892 "BE_MaxAmsduSize",
893 UintegerValue(4500),
894 "BE_MaxAmpduSize",
895 UintegerValue(7500),
896 "Ssid",
897 SsidValue(ssid),
898 /* setting blockack threshold for sta's BE queue */
899 "BE_BlockAckThreshold",
900 UintegerValue(2),
901 "ActiveProbing",
902 BooleanValue(false));
903
904 NetDeviceContainer staDevices;
905 staDevices = wifi.Install(phy, mac, wifiStaNode);
906
907 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid), "BeaconGeneration", BooleanValue(true));
908
909 NetDeviceContainer apDevices;
910 apDevices = wifi.Install(phy, mac, wifiApNode);
911
912 MobilityHelper mobility;
913 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
914
915 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
916 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
917 mobility.SetPositionAllocator(positionAlloc);
918
919 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
920 mobility.Install(wifiApNode);
921 mobility.Install(wifiStaNode);
922
923 Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice>(apDevices.Get(0));
924 Ptr<WifiNetDevice> sta_device = DynamicCast<WifiNetDevice>(staDevices.Get(0));
925
926 PacketSocketAddress socket;
927 socket.SetSingleDevice(sta_device->GetIfIndex());
928 socket.SetPhysicalAddress(ap_device->GetAddress());
929 socket.SetProtocol(1);
930
931 // install packet sockets on nodes.
932 PacketSocketHelper packetSocket;
933 packetSocket.Install(wifiStaNode);
934 packetSocket.Install(wifiApNode);
935
936 Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient>();
937 client->SetAttribute("PacketSize", UintegerValue(1000));
938 client->SetAttribute("MaxPackets", UintegerValue(8));
939 client->SetAttribute("Interval", TimeValue(Seconds(1)));
940 client->SetRemote(socket);
941 wifiStaNode.Get(0)->AddApplication(client);
942 client->SetStartTime(Seconds(1));
943 client->SetStopTime(Seconds(3.0));
945 &PacketSocketClient::SetAttribute,
946 client,
947 "Interval",
949
950 Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer>();
951 server->SetLocal(socket);
952 wifiApNode.Get(0)->AddApplication(server);
953 server->SetStartTime(Seconds(0.0));
954 server->SetStopTime(Seconds(4.0));
955
956 sta_device->GetMac()->TraceConnectWithoutContext(
957 "MacTx",
959 sta_device->GetPhy()->TraceConnectWithoutContext(
960 "PhyTxPsduBegin",
962 ap_device->GetMac()->TraceConnectWithoutContext(
963 "MacRx",
965
968
970
971 // Two packets are transmitted. The first one is an MPDU containing a single MSDU.
972 // The second one is an A-MPDU containing two MPDUs: the first MPDU contains 4 MSDUs
973 // and the second MPDU contains 3 MSDUs
974 NS_TEST_EXPECT_MSG_EQ(m_nMpdus.size(), 2, "Unexpected number of transmitted packets");
975 NS_TEST_EXPECT_MSG_EQ(m_nMsdus.size(), 3, "Unexpected number of transmitted MPDUs");
976 NS_TEST_EXPECT_MSG_EQ(m_nMpdus[0], 1, "Unexpected number of MPDUs in the first A-MPDU");
977 NS_TEST_EXPECT_MSG_EQ(m_nMsdus[0], 1, "Unexpected number of MSDUs in the first MPDU");
978 NS_TEST_EXPECT_MSG_EQ(m_nMpdus[1], 2, "Unexpected number of MPDUs in the second A-MPDU");
979 NS_TEST_EXPECT_MSG_EQ(m_nMsdus[1], 4, "Unexpected number of MSDUs in the second MPDU");
980 NS_TEST_EXPECT_MSG_EQ(m_nMsdus[2], 3, "Unexpected number of MSDUs in the third MPDU");
981 // All the packets must have been forwarded up at the receiver
982 NS_TEST_EXPECT_MSG_EQ(m_packetList.empty(), true, "Some packets have not been forwarded up");
983}
984
992{
993 public:
995};
996
998 : TestSuite("wifi-aggregation", UNIT)
999{
1004}
1005
Ampdu Aggregation Test.
bool m_discarded
whether the packet should be discarded
Ptr< YansWifiPhy > m_phy
Phy.
ObjectFactory m_factory
factory
Ptr< WifiRemoteStationManager > m_manager
remote station manager
void DoRun() override
Implementation to actually run this TestCase.
Ptr< WifiNetDevice > m_device
WifiNetDevice.
void MpduDiscarded(WifiMacDropReason reason, Ptr< const WifiMpdu > mpdu)
Fired when the MAC discards an MPDU.
Ptr< StaWifiMac > m_mac
Mac.
802.11ax aggregation test which permits 64 or 256 MPDUs in A-MPDU according to the negotiated buffer ...
void DoRunSubTest(uint16_t bufferSize)
Run test for a given buffer size.
Ptr< StaWifiMac > m_mac
Mac.
Ptr< WifiNetDevice > m_device
WifiNetDevice.
ObjectFactory m_factory
factory
void DoRun() override
Implementation to actually run this TestCase.
Ptr< WifiRemoteStationManager > m_manager
remote station manager
Ptr< YansWifiPhy > m_phy
Phy.
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.
Ptr< WifiRemoteStationManager > m_manager
remote station manager
void DoRun() override
Implementation to actually run this TestCase.
Ptr< YansWifiPhy > m_phy
Phy.
ObjectFactory m_factory
factory
Ptr< StaWifiMac > m_mac
Mac.
Ptr< WifiNetDevice > m_device
WifiNetDevice.
Wifi Aggregation Test Suite.
A container for one type of attribute.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
The IEEE 802.11ax HE Capabilities.
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.
Definition: mgt-headers.h:795
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.
Definition: mgt-headers.h:926
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:311
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:200
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.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Ptr< BlockAckManager > GetBaManager()
Get the Block Ack Manager associated with this QosTxop.
Definition: qos-txop.cc:273
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:365
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:482
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
static void Run()
Run the simulation.
Definition: simulator.cc:176
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:184
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
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
@ QUICK
Fast test.
Definition: test.h:1065
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
static Time Min()
Minimum representable Time Not to be confused with Min(Time,Time).
Definition: nstime.h:286
AttributeValue implementation for Time.
Definition: nstime.h:1423
Time GetTxopLimit() const
Return the TXOP limit.
Definition: txop.cc:469
Ptr< WifiMacQueue > GetWifiMacQueue() const
Return the packet queue associated with this Txop.
Definition: txop.cc:216
Hold an unsigned integer type.
Definition: uinteger.h:45
helps to create WifiNetDevice objects
Definition: wifi-helper.h:324
Implements the IEEE 802.11 MAC header.
Mac48Address GetAddr1() const
Return the address in the Address 1 field.
void SetNoMoreFragments()
Un-set the More Fragment bit in the Frame Control Field.
void SetSequenceNumber(uint16_t seq)
Set the sequence number of the header.
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
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.
void SetFragmentNumber(uint8_t frag)
Set the fragment number of the header.
void SetNoRetry()
Un-set the Retry bit in the Frame Control field.
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:531
virtual void SetMacQueueScheduler(Ptr< WifiMacQueueScheduler > scheduler)
Set the wifi MAC queue scheduler.
Definition: wifi-mac.cc:567
virtual void SetAddress(Mac48Address address)
Definition: wifi-mac.cc:443
virtual void ConfigureStandard(WifiStandard standard)
Definition: wifi-mac.cc:748
void SetWifiRemoteStationManager(Ptr< WifiRemoteStationManager > stationManager)
Definition: wifi-mac.cc:876
Ptr< MacTxMiddle > m_txMiddle
TX middle (aggregation etc.)
Definition: wifi-mac.h:785
Ptr< QosTxop > GetVIQueue() const
Accessor for the AC_VI channel access function.
Definition: wifi-mac.cc:525
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(uint8_t linkId=0) const
Definition: wifi-mac.cc:910
void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-mac.cc:431
void SetMac(const Ptr< WifiMac > mac)
void SetHeConfiguration(Ptr< HeConfiguration > heConfiguration)
void SetHtConfiguration(Ptr< HtConfiguration > htConfiguration)
void SetVhtConfiguration(Ptr< VhtConfiguration > vhtConfiguration)
void SetRemoteStationManager(const Ptr< WifiRemoteStationManager > manager)
void SetStandard(WifiStandard standard)
Set the Wifi standard.
void SetPhy(const Ptr< WifiPhy > phy)
uint16_t GetChannelWidth() const
Definition: wifi-phy.cc:1035
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:950
virtual void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:609
hold a list of per-remote-station state.
void AddStationHeCapabilities(Mac48Address from, HeCapabilities heCapabilities)
Records HE capabilities of the remote station.
void SetMaxSsrc(uint32_t maxSsrc)
Sets the maximum STA short retry count (SSRC).
virtual void SetupPhy(const Ptr< WifiPhy > phy)
Set up PHY associated with this device since it is the object that knows the full set of transmit rat...
WifiTxVector GetDataTxVector(const WifiMacHeader &header, uint16_t allowedWidth)
void AddStationHtCapabilities(Mac48Address from, HtCapabilities htCapabilities)
Records HT capabilities of the remote station.
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.
void SetInterferenceHelper(const Ptr< InterferenceHelper > helper) override
Sets the interference helper.
#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:1360
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
WifiMacDropReason
The reason why an MPDU was dropped.
Definition: wifi-mac.h:75
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211ax
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:488
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:702
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:140
@ WIFI_MAC_QOSDATA
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Definition: wifi-mode.h:35
static WifiAggregationTestSuite g_wifiAggregationTestSuite
the test suite