A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2006 INRIA
3 * 2010 NICTA
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19 * Quincy Tse <quincy.tse@nicta.com.au>
20 * Sébastien Deronne <sebastien.deronne@gmail.com>
21 */
22
23#include "ns3/adhoc-wifi-mac.h"
24#include "ns3/ap-wifi-mac.h"
25#include "ns3/config.h"
26#include "ns3/constant-position-mobility-model.h"
27#include "ns3/error-model.h"
28#include "ns3/fcfs-wifi-queue-scheduler.h"
29#include "ns3/he-frame-exchange-manager.h"
30#include "ns3/header-serialization-test.h"
31#include "ns3/ht-configuration.h"
32#include "ns3/interference-helper.h"
33#include "ns3/mgt-headers.h"
34#include "ns3/mobility-helper.h"
35#include "ns3/multi-model-spectrum-channel.h"
36#include "ns3/packet-socket-client.h"
37#include "ns3/packet-socket-helper.h"
38#include "ns3/packet-socket-server.h"
39#include "ns3/pointer.h"
40#include "ns3/propagation-loss-model.h"
41#include "ns3/rng-seed-manager.h"
42#include "ns3/socket.h"
43#include "ns3/spectrum-wifi-helper.h"
44#include "ns3/string.h"
45#include "ns3/test.h"
46#include "ns3/vht-phy.h"
47#include "ns3/waypoint-mobility-model.h"
48#include "ns3/wifi-default-ack-manager.h"
49#include "ns3/wifi-default-assoc-manager.h"
50#include "ns3/wifi-default-protection-manager.h"
51#include "ns3/wifi-mgt-header.h"
52#include "ns3/wifi-net-device.h"
53#include "ns3/wifi-ppdu.h"
54#include "ns3/wifi-psdu.h"
55#include "ns3/wifi-spectrum-signal-parameters.h"
56#include "ns3/yans-error-rate-model.h"
57#include "ns3/yans-wifi-helper.h"
58#include "ns3/yans-wifi-phy.h"
59
60#include <optional>
61
62using namespace ns3;
63
64// Helper function to assign streams to random variables, to control
65// randomness in the tests
66static void
68{
69 int64_t currentStream = stream;
70 PointerValue ptr;
71 if (!mac->GetQosSupported())
72 {
73 mac->GetAttribute("Txop", ptr);
74 Ptr<Txop> txop = ptr.Get<Txop>();
75 currentStream += txop->AssignStreams(currentStream);
76 }
77 else
78 {
79 mac->GetAttribute("VO_Txop", ptr);
80 Ptr<QosTxop> vo_txop = ptr.Get<QosTxop>();
81 currentStream += vo_txop->AssignStreams(currentStream);
82
83 mac->GetAttribute("VI_Txop", ptr);
84 Ptr<QosTxop> vi_txop = ptr.Get<QosTxop>();
85 currentStream += vi_txop->AssignStreams(currentStream);
86
87 mac->GetAttribute("BE_Txop", ptr);
88 Ptr<QosTxop> be_txop = ptr.Get<QosTxop>();
89 currentStream += be_txop->AssignStreams(currentStream);
90
91 mac->GetAttribute("BK_Txop", ptr);
92 Ptr<QosTxop> bk_txop = ptr.Get<QosTxop>();
93 bk_txop->AssignStreams(currentStream);
94 }
95}
96
97/**
98 * \ingroup wifi-test
99 * \ingroup tests
100 *
101 * \brief Wifi Test
102 */
103class WifiTest : public TestCase
104{
105 public:
106 WifiTest();
107
108 void DoRun() override;
109
110 private:
111 /// Run one function
112 void RunOne();
113 /**
114 * Create one function
115 * \param pos the position
116 * \param channel the wifi channel
117 */
118 void CreateOne(Vector pos, Ptr<YansWifiChannel> channel);
119 /**
120 * Send one packet function
121 * \param dev the device
122 */
124
127 ObjectFactory m_propDelay; ///< propagation delay
128};
129
131 : TestCase("Wifi")
132{
133}
134
135void
137{
138 Ptr<Packet> p = Create<Packet>();
139 dev->Send(p, dev->GetBroadcast(), 1);
140}
141
142void
144{
145 Ptr<Node> node = CreateObject<Node>();
146 Ptr<WifiNetDevice> dev = CreateObject<WifiNetDevice>();
147 node->AddDevice(dev);
148
149 auto mobility = CreateObject<ConstantPositionMobilityModel>();
150 auto phy = CreateObject<YansWifiPhy>();
151 Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper>();
152 phy->SetInterferenceHelper(interferenceHelper);
153 auto error = CreateObject<YansErrorRateModel>();
154 phy->SetErrorRateModel(error);
155 phy->SetChannel(channel);
156 phy->SetDevice(dev);
157 phy->ConfigureStandard(WIFI_STANDARD_80211a);
158 dev->SetPhy(phy);
159 auto manager = m_manager.Create<WifiRemoteStationManager>();
160 dev->SetRemoteStationManager(manager);
161
162 auto txop = CreateObjectWithAttributes<Txop>("AcIndex", StringValue("AC_BE_NQOS"));
163 m_mac.Set("Txop", PointerValue(txop));
164 auto mac = m_mac.Create<WifiMac>();
165 mac->SetDevice(dev);
166 mac->SetAddress(Mac48Address::Allocate());
167 dev->SetMac(mac);
168 mac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
169 mac->SetFrameExchangeManagers({CreateObject<FrameExchangeManager>()});
170 if (mac->GetTypeOfStation() == STA)
171 {
172 StaticCast<StaWifiMac>(mac)->SetAssocManager(CreateObject<WifiDefaultAssocManager>());
173 }
174 mac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
175 Ptr<FrameExchangeManager> fem = mac->GetFrameExchangeManager();
176 fem->SetAddress(mac->GetAddress());
177 Ptr<WifiProtectionManager> protectionManager = CreateObject<WifiDefaultProtectionManager>();
178 protectionManager->SetWifiMac(mac);
179 fem->SetProtectionManager(protectionManager);
180 Ptr<WifiAckManager> ackManager = CreateObject<WifiDefaultAckManager>();
181 ackManager->SetWifiMac(mac);
182 fem->SetAckManager(ackManager);
183
184 mobility->SetPosition(pos);
185 node->AggregateObject(mobility);
186
188}
189
190void
192{
193 Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel>();
195 Ptr<PropagationLossModel> propLoss = CreateObject<RandomPropagationLossModel>();
196 channel->SetPropagationDelayModel(propDelay);
197 channel->SetPropagationLossModel(propLoss);
198
199 CreateOne(Vector(0.0, 0.0, 0.0), channel);
200 CreateOne(Vector(5.0, 0.0, 0.0), channel);
201 CreateOne(Vector(5.0, 0.0, 0.0), channel);
202
204
207}
208
209void
211{
212 m_mac.SetTypeId("ns3::AdhocWifiMac");
213 m_propDelay.SetTypeId("ns3::ConstantSpeedPropagationDelayModel");
214
215 m_manager.SetTypeId("ns3::ArfWifiManager");
216 RunOne();
217 m_manager.SetTypeId("ns3::AarfWifiManager");
218 RunOne();
219 m_manager.SetTypeId("ns3::ConstantRateWifiManager");
220 RunOne();
221 m_manager.SetTypeId("ns3::OnoeWifiManager");
222 RunOne();
223 m_manager.SetTypeId("ns3::AmrrWifiManager");
224 RunOne();
225 m_manager.SetTypeId("ns3::IdealWifiManager");
226 RunOne();
227
228 m_mac.SetTypeId("ns3::AdhocWifiMac");
229 RunOne();
230 m_mac.SetTypeId("ns3::ApWifiMac");
231 RunOne();
232 m_mac.SetTypeId("ns3::StaWifiMac");
233 RunOne();
234
235 m_propDelay.SetTypeId("ns3::RandomPropagationDelayModel");
236 m_mac.SetTypeId("ns3::AdhocWifiMac");
237 RunOne();
238}
239
240/**
241 * \ingroup wifi-test
242 * \ingroup tests
243 *
244 * \brief Qos Utils Is Old Packet Test
245 */
247{
248 public:
250 : TestCase("QosUtilsIsOldPacket")
251 {
252 }
253
254 void DoRun() override
255 {
256 // startingSeq=0, seqNum=2047
258 false,
259 "2047 is new in comparison to 0");
260 // startingSeq=0, seqNum=2048
261 NS_TEST_EXPECT_MSG_EQ(QosUtilsIsOldPacket(0, 2048), true, "2048 is old in comparison to 0");
262 // startingSeq=2048, seqNum=0
263 NS_TEST_EXPECT_MSG_EQ(QosUtilsIsOldPacket(2048, 0), true, "0 is old in comparison to 2048");
264 // startingSeq=4095, seqNum=0
266 false,
267 "0 is new in comparison to 4095");
268 // startingSeq=0, seqNum=4095
269 NS_TEST_EXPECT_MSG_EQ(QosUtilsIsOldPacket(0, 4095), true, "4095 is old in comparison to 0");
270 // startingSeq=4095 seqNum=2047
272 true,
273 "2047 is old in comparison to 4095");
274 // startingSeq=2048 seqNum=4095
276 false,
277 "4095 is new in comparison to 2048");
278 // startingSeq=2049 seqNum=0
280 false,
281 "0 is new in comparison to 2049");
282 }
283};
284
285/**
286 * See \bugid{991}
287 */
289{
290 public:
292
293 void DoRun() override;
294
295 private:
296 /**
297 * Create one function
298 * \param pos the position
299 * \param channel the wifi channel
300 * \returns the node
301 */
302 Ptr<Node> CreateOne(Vector pos, Ptr<YansWifiChannel> channel);
303 /**
304 * Send one packet function
305 * \param dev the device
306 */
308 /**
309 * Switch channel function
310 * \param dev the device
311 */
313
316 ObjectFactory m_propDelay; ///< propagation delay
317};
318
320 : TestCase("InterferenceHelperSequence")
321{
322}
323
324void
326{
327 Ptr<Packet> p = Create<Packet>(1000);
328 dev->Send(p, dev->GetBroadcast(), 1);
329}
330
331void
333{
334 Ptr<WifiPhy> p = dev->GetPhy();
335 p->SetOperatingChannel(WifiPhy::ChannelTuple{40, 0, WIFI_PHY_BAND_5GHZ, 0});
336}
337
340{
341 Ptr<Node> node = CreateObject<Node>();
342 Ptr<WifiNetDevice> dev = CreateObject<WifiNetDevice>();
343 node->AddDevice(dev);
344
345 auto mobility = CreateObject<ConstantPositionMobilityModel>();
346 auto phy = CreateObject<YansWifiPhy>();
347 Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper>();
348 phy->SetInterferenceHelper(interferenceHelper);
349 auto error = CreateObject<YansErrorRateModel>();
350 phy->SetErrorRateModel(error);
351 phy->SetChannel(channel);
352 phy->SetDevice(dev);
353 phy->SetMobility(mobility);
354 phy->ConfigureStandard(WIFI_STANDARD_80211a);
355 dev->SetPhy(phy);
356 auto manager = m_manager.Create<WifiRemoteStationManager>();
357 dev->SetRemoteStationManager(manager);
358
359 auto txop = CreateObjectWithAttributes<Txop>("AcIndex", StringValue("AC_BE_NQOS"));
360 m_mac.Set("Txop", PointerValue(txop));
361 auto mac = m_mac.Create<WifiMac>();
362 mac->SetDevice(dev);
363 mac->SetAddress(Mac48Address::Allocate());
364 dev->SetMac(mac);
365 mac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
366 mac->SetFrameExchangeManagers({CreateObject<FrameExchangeManager>()});
367 mac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
368 Ptr<FrameExchangeManager> fem = mac->GetFrameExchangeManager();
369 fem->SetAddress(mac->GetAddress());
370 Ptr<WifiProtectionManager> protectionManager = CreateObject<WifiDefaultProtectionManager>();
371 protectionManager->SetWifiMac(mac);
372 fem->SetProtectionManager(protectionManager);
373 Ptr<WifiAckManager> ackManager = CreateObject<WifiDefaultAckManager>();
374 ackManager->SetWifiMac(mac);
375 fem->SetAckManager(ackManager);
376
377 mobility->SetPosition(pos);
378 node->AggregateObject(mobility);
379
380 return node;
381}
382
383void
385{
386 m_mac.SetTypeId("ns3::AdhocWifiMac");
387 m_propDelay.SetTypeId("ns3::ConstantSpeedPropagationDelayModel");
388 m_manager.SetTypeId("ns3::ConstantRateWifiManager");
389
390 Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel>();
392 Ptr<MatrixPropagationLossModel> propLoss = CreateObject<MatrixPropagationLossModel>();
393 channel->SetPropagationDelayModel(propDelay);
394 channel->SetPropagationLossModel(propLoss);
395
396 Ptr<Node> rxOnly = CreateOne(Vector(0.0, 0.0, 0.0), channel);
397 Ptr<Node> senderA = CreateOne(Vector(5.0, 0.0, 0.0), channel);
398 Ptr<Node> senderB = CreateOne(Vector(-5.0, 0.0, 0.0), channel);
399
400 propLoss->SetLoss(senderB->GetObject<MobilityModel>(),
401 rxOnly->GetObject<MobilityModel>(),
402 0,
403 true);
404 propLoss->SetDefaultLoss(999);
405
408 this,
409 DynamicCast<WifiNetDevice>(senderB->GetDevice(0)));
410
411 Simulator::Schedule(Seconds(1.0000001),
413 this,
414 DynamicCast<WifiNetDevice>(rxOnly->GetDevice(0)));
415
418 this,
419 DynamicCast<WifiNetDevice>(senderA->GetDevice(0)));
420
423 this,
424 DynamicCast<WifiNetDevice>(senderB->GetDevice(0)));
425
426 Simulator::Stop(Seconds(100.0));
428
430}
431
432//-----------------------------------------------------------------------------
433/**
434 * Make sure that when multiple broadcast packets are queued on the same
435 * device in a short succession, that:
436 * 1) no backoff occurs if the frame arrives and the idle time >= DIFS or AIFSn
437 * (this is 'DCF immediate access', Figure 9-3 of IEEE 802.11-2012)
438 * 2) a backoff occurs for the second frame that arrives (this is clearly
439 * stated in Sec. 9.3.4.2 of IEEE 802.11-2012, (basic access, which
440 * applies to group-addressed frames) where it states
441 * "If, under these conditions, the medium is determined by the CS
442 * mechanism to be busy when a STA desires to initiate the initial frame
443 * of a frame exchange sequence (described in Annex G), exclusive of the
444 * CF period, the random backoff procedure described in 9.3.4.3
445 * shall be followed."
446 * and from 9.3.4.3
447 * "The result of this procedure is that transmitted
448 * frames from a STA are always separated by at least one backoff interval."
449 *
450 * The observed behavior is that the first frame will be sent immediately,
451 * and the frames are spaced by (backoff + DIFS) time intervals
452 * (where backoff is a random number of slot sizes up to maximum CW)
453 *
454 * The following test case should _not_ generate virtual collision for
455 * the second frame. The seed and run numbers were pick such that the
456 * second frame gets backoff = 1 slot.
457 *
458 * frame 1, frame 2
459 * arrive DIFS = 2 x slot + SIFS
460 * | = 2 x 9us + 16us for 11a
461 * | <----------->
462 * V <-backoff->
463 * time |--------------|-------------------|-------------|----------->
464 * 0 1s 1.001408s 1.001442s |1.001451s
465 * ^ ^ ^
466 * start TX finish TX start TX
467 * frame 1 frame 1 frame 2
468 * ^
469 * frame 2
470 * backoff = 1 slot
471 *
472 * The buggy behavior observed in prior versions was shown by picking
473 * RngSeedManager::SetRun (17);
474 * which generated a 0 slot backoff for frame 2. Then, frame 2
475 * experiences a virtual collision and re-selects the backoff again.
476 * As a result, the _actual_ backoff experience by frame 2 is less likely
477 * to be 0 since that would require two successions of 0 backoff (one that
478 * generates the virtual collision and one after the virtual collision).
479 *
480 * See \bugid{555} for past behavior.
481 */
482
484{
485 public:
487
488 void DoRun() override;
489
490 private:
491 /**
492 * Send one packet function
493 * \param dev the device
494 */
496
499 ObjectFactory m_propDelay; ///< propagation delay
500
501 Time m_firstTransmissionTime; ///< first transmission time
502 Time m_secondTransmissionTime; ///< second transmission time
503 unsigned int m_numSentPackets; ///< number of sent packets
504
505 /**
506 * Notify Phy transmit begin
507 * \param p the packet
508 * \param txPowerW the tx power
509 */
510 void NotifyPhyTxBegin(Ptr<const Packet> p, double txPowerW);
511};
512
514 : TestCase("Test case for DCF immediate access with broadcast frames")
515{
516}
517
518void
520{
521 if (m_numSentPackets == 0)
522 {
525 }
526 else if (m_numSentPackets == 1)
527 {
529 }
530}
531
532void
534{
535 Ptr<Packet> p = Create<Packet>(1000);
536 dev->Send(p, dev->GetBroadcast(), 1);
537}
538
539void
541{
542 m_mac.SetTypeId("ns3::AdhocWifiMac");
543 m_propDelay.SetTypeId("ns3::ConstantSpeedPropagationDelayModel");
544 m_manager.SetTypeId("ns3::ConstantRateWifiManager");
545
546 // Assign a seed and run number, and later fix the assignment of streams to
547 // WiFi random variables, so that the first backoff used is one slot
549 RngSeedManager::SetRun(40); // a value of 17 will result in zero slots
550
551 Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel>();
553 Ptr<PropagationLossModel> propLoss = CreateObject<RandomPropagationLossModel>();
554 channel->SetPropagationDelayModel(propDelay);
555 channel->SetPropagationLossModel(propLoss);
556
557 Ptr<Node> txNode = CreateObject<Node>();
558 Ptr<WifiNetDevice> txDev = CreateObject<WifiNetDevice>();
559
560 Ptr<ConstantPositionMobilityModel> txMobility = CreateObject<ConstantPositionMobilityModel>();
561 Ptr<YansWifiPhy> txPhy = CreateObject<YansWifiPhy>();
562 Ptr<InterferenceHelper> txInterferenceHelper = CreateObject<InterferenceHelper>();
563 txPhy->SetInterferenceHelper(txInterferenceHelper);
564 Ptr<ErrorRateModel> txError = CreateObject<YansErrorRateModel>();
565 txPhy->SetErrorRateModel(txError);
566 txPhy->SetChannel(channel);
567 txPhy->SetDevice(txDev);
568 txPhy->SetMobility(txMobility);
569 txPhy->ConfigureStandard(WIFI_STANDARD_80211a);
570
571 txPhy->TraceConnectWithoutContext(
572 "PhyTxBegin",
574
575 txMobility->SetPosition(Vector(0.0, 0.0, 0.0));
576 txNode->AggregateObject(txMobility);
577 txDev->SetPhy(txPhy);
578 txDev->SetRemoteStationManager(m_manager.Create<WifiRemoteStationManager>());
579 txNode->AddDevice(txDev);
580
581 auto txop = CreateObjectWithAttributes<Txop>("AcIndex", StringValue("AC_BE_NQOS"));
582 m_mac.Set("Txop", PointerValue(txop));
583 auto txMac = m_mac.Create<WifiMac>();
584 txMac->SetDevice(txDev);
585 txMac->SetAddress(Mac48Address::Allocate());
586 txDev->SetMac(txMac);
587 txMac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
588 txMac->SetFrameExchangeManagers({CreateObject<FrameExchangeManager>()});
589 txMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
590 auto fem = txMac->GetFrameExchangeManager();
591 fem->SetAddress(txMac->GetAddress());
592 auto protectionManager = CreateObject<WifiDefaultProtectionManager>();
593 protectionManager->SetWifiMac(txMac);
594 fem->SetProtectionManager(protectionManager);
595 auto ackManager = CreateObject<WifiDefaultAckManager>();
596 ackManager->SetWifiMac(txMac);
597 fem->SetAckManager(ackManager);
598
599 // Fix the stream assignment to the Dcf Txop objects (backoffs)
600 // The below stream assignment will result in the Txop object
601 // using a backoff value of zero for this test when the
602 // Txop::EndTxNoAck() calls to StartBackoffNow()
603 AssignWifiRandomStreams(txMac, 23);
604
608
611 this,
612 txDev);
615 this,
616 txDev);
617
621
622 // First packet is transmitted a DIFS after the packet is queued. A DIFS
623 // is 2 slots (2 * 9 = 18 us) plus a SIFS (16 us), i.e., 34 us
624 Time expectedFirstTransmissionTime = Seconds(1.0) + MicroSeconds(34);
625
626 // First packet has 1408 us of transmit time. Slot time is 9 us.
627 // Backoff is 1 slots. SIFS is 16 us. DIFS is 2 slots = 18 us.
628 // Should send next packet at 1408 us + (1 * 9 us) + 16 us + (2 * 9) us
629 // 1451 us after the first one.
630 uint32_t expectedWait1 = 1408 + (1 * 9) + 16 + (2 * 9);
631 Time expectedSecondTransmissionTime =
632 expectedFirstTransmissionTime + MicroSeconds(expectedWait1);
634 expectedFirstTransmissionTime,
635 "The first transmission time not correct!");
636
638 expectedSecondTransmissionTime,
639 "The second transmission time not correct!");
640}
641
642//-----------------------------------------------------------------------------
643/**
644 * Make sure that when changing the fragmentation threshold during the simulation,
645 * the TCP transmission does not unexpectedly stop.
646 *
647 * The scenario considers a TCP transmission between a 802.11b station and a 802.11b
648 * access point. After the simulation has begun, the fragmentation threshold is set at
649 * a value lower than the packet size. It then checks whether the TCP transmission
650 * continues after the fragmentation threshold modification.
651 *
652 * See \bugid{730}
653 */
654
656{
657 public:
659 ~Bug730TestCase() override;
660
661 void DoRun() override;
662
663 private:
664 uint32_t m_received; ///< received
665
666 /**
667 * Receive function
668 * \param context the context
669 * \param p the packet
670 * \param adr the address
671 */
672 void Receive(std::string context, Ptr<const Packet> p, const Address& adr);
673};
674
676 : TestCase("Test case for Bug 730"),
677 m_received(0)
678{
679}
680
682{
683}
684
685void
686Bug730TestCase::Receive(std::string context, Ptr<const Packet> p, const Address& adr)
687{
688 if ((p->GetSize() == 1460) && (Simulator::Now() > Seconds(20)))
689 {
690 m_received++;
691 }
692}
693
694void
696{
697 m_received = 0;
698
699 NodeContainer wifiStaNode;
700 wifiStaNode.Create(1);
701
702 NodeContainer wifiApNode;
703 wifiApNode.Create(1);
704
707 phy.SetChannel(channel.Create());
708
709 WifiHelper wifi;
710 wifi.SetStandard(WIFI_STANDARD_80211b);
711 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
712 "DataMode",
713 StringValue("DsssRate1Mbps"),
714 "ControlMode",
715 StringValue("DsssRate1Mbps"));
716
717 WifiMacHelper mac;
718 Ssid ssid = Ssid("ns-3-ssid");
719 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid), "ActiveProbing", BooleanValue(false));
720
721 NetDeviceContainer staDevices;
722 staDevices = wifi.Install(phy, mac, wifiStaNode);
723
724 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid), "BeaconGeneration", BooleanValue(true));
725
726 NetDeviceContainer apDevices;
727 apDevices = wifi.Install(phy, mac, wifiApNode);
728
729 MobilityHelper mobility;
730 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
731
732 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
733 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
734 mobility.SetPositionAllocator(positionAlloc);
735
736 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
737 mobility.Install(wifiApNode);
738 mobility.Install(wifiStaNode);
739
740 Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice>(apDevices.Get(0));
741 Ptr<WifiNetDevice> sta_device = DynamicCast<WifiNetDevice>(staDevices.Get(0));
742
743 PacketSocketAddress socket;
744 socket.SetSingleDevice(sta_device->GetIfIndex());
745 socket.SetPhysicalAddress(ap_device->GetAddress());
746 socket.SetProtocol(1);
747
748 // give packet socket powers to nodes.
749 PacketSocketHelper packetSocket;
750 packetSocket.Install(wifiStaNode);
751 packetSocket.Install(wifiApNode);
752
753 Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient>();
754 client->SetAttribute("PacketSize", UintegerValue(1460));
755 client->SetRemote(socket);
756 wifiStaNode.Get(0)->AddApplication(client);
757 client->SetStartTime(Seconds(1));
758 client->SetStopTime(Seconds(51.0));
759
760 Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer>();
761 server->SetLocal(socket);
762 wifiApNode.Get(0)->AddApplication(server);
763 server->SetStartTime(Seconds(0.0));
764 server->SetStopTime(Seconds(52.0));
765
766 Config::Connect("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx",
768
771 "/NodeList/0/DeviceList/0/RemoteStationManager/FragmentationThreshold",
772 StringValue("800"));
773
776
778
779 bool result = (m_received > 0);
781 result,
782 true,
783 "packet reception unexpectedly stopped after adapting fragmentation threshold!");
784}
785
786//-----------------------------------------------------------------------------
787/**
788 * Make sure that fragmentation works with QoS stations.
789 *
790 * The scenario considers a TCP transmission between an 802.11n station and an 802.11n
791 * access point.
792 */
793
795{
796 public:
798 ~QosFragmentationTestCase() override;
799
800 void DoRun() override;
801
802 private:
803 uint32_t m_received; ///< received packets
804 uint32_t m_fragments; ///< transmitted fragments
805
806 /**
807 * Receive function
808 * \param context the context
809 * \param p the packet
810 * \param adr the address
811 */
812 void Receive(std::string context, Ptr<const Packet> p, const Address& adr);
813
814 /**
815 * Callback invoked when PHY transmits a packet
816 * \param context the context
817 * \param p the packet
818 * \param power the tx power
819 */
820 void Transmit(std::string context, Ptr<const Packet> p, double power);
821};
822
824 : TestCase("Test case for fragmentation with QoS stations"),
825 m_received(0),
826 m_fragments(0)
827{
828}
829
831{
832}
833
834void
836{
837 if (p->GetSize() == 1400)
838 {
839 m_received++;
840 }
841}
842
843void
844QosFragmentationTestCase::Transmit(std::string context, Ptr<const Packet> p, double power)
845{
846 WifiMacHeader hdr;
847 p->PeekHeader(hdr);
848 if (hdr.IsQosData())
849 {
850 NS_TEST_EXPECT_MSG_LT_OR_EQ(p->GetSize(), 400, "Unexpected fragment size");
851 m_fragments++;
852 }
853}
854
855void
857{
858 NodeContainer wifiStaNode;
859 wifiStaNode.Create(1);
860
861 NodeContainer wifiApNode;
862 wifiApNode.Create(1);
863
866 phy.SetChannel(channel.Create());
867
868 WifiHelper wifi;
869 wifi.SetStandard(WIFI_STANDARD_80211n);
870 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", "DataMode", StringValue("HtMcs7"));
871
872 WifiMacHelper mac;
873 Ssid ssid = Ssid("ns-3-ssid");
874 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid), "ActiveProbing", BooleanValue(false));
875
876 NetDeviceContainer staDevices;
877 staDevices = wifi.Install(phy, mac, wifiStaNode);
878
879 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid), "BeaconGeneration", BooleanValue(true));
880
881 NetDeviceContainer apDevices;
882 apDevices = wifi.Install(phy, mac, wifiApNode);
883
884 MobilityHelper mobility;
885 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
886
887 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
888 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
889 mobility.SetPositionAllocator(positionAlloc);
890
891 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
892 mobility.Install(wifiApNode);
893 mobility.Install(wifiStaNode);
894
895 Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice>(apDevices.Get(0));
896 Ptr<WifiNetDevice> sta_device = DynamicCast<WifiNetDevice>(staDevices.Get(0));
897
898 // set the TXOP limit on BE AC
899 PointerValue ptr;
900 sta_device->GetMac()->GetAttribute("BE_Txop", ptr);
901 ptr.Get<QosTxop>()->SetTxopLimit(MicroSeconds(3008));
902
903 PacketSocketAddress socket;
904 socket.SetSingleDevice(sta_device->GetIfIndex());
905 socket.SetPhysicalAddress(ap_device->GetAddress());
906 socket.SetProtocol(1);
907
908 // give packet socket powers to nodes.
909 PacketSocketHelper packetSocket;
910 packetSocket.Install(wifiStaNode);
911 packetSocket.Install(wifiApNode);
912
913 Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient>();
914 client->SetAttribute("PacketSize", UintegerValue(1400));
915 client->SetAttribute("MaxPackets", UintegerValue(1));
916 client->SetRemote(socket);
917 wifiStaNode.Get(0)->AddApplication(client);
918 client->SetStartTime(Seconds(1));
919 client->SetStopTime(Seconds(3.0));
920
921 Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer>();
922 server->SetLocal(socket);
923 wifiApNode.Get(0)->AddApplication(server);
924 server->SetStartTime(Seconds(0.0));
925 server->SetStopTime(Seconds(4.0));
926
927 Config::Connect("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx",
929
930 Config::Set("/NodeList/0/DeviceList/0/RemoteStationManager/FragmentationThreshold",
931 StringValue("400"));
932 Config::Connect("/NodeList/0/DeviceList/0/Phy/PhyTxBegin",
934
937
939
940 NS_TEST_ASSERT_MSG_EQ(m_received, 1, "Unexpected number of received packets");
941 NS_TEST_ASSERT_MSG_EQ(m_fragments, 4, "Unexpected number of transmitted fragments");
942}
943
944/**
945 * \ingroup wifi-test
946 * \ingroup tests
947 *
948 * \brief Set Channel Frequency Test
949 */
951{
952 public:
954
955 void DoRun() override;
956
957 private:
958 /**
959 * Get yans wifi phy function
960 * \param nc the device collection
961 * \returns the wifi phy
962 */
964};
965
967 : TestCase("Test case for setting WifiPhy channel and frequency")
968{
969}
970
973{
974 Ptr<WifiNetDevice> wnd = nc.Get(0)->GetObject<WifiNetDevice>();
975 Ptr<WifiPhy> wp = wnd->GetPhy();
976 return wp->GetObject<YansWifiPhy>();
977}
978
979void
981{
982 NodeContainer wifiStaNode;
983 wifiStaNode.Create(1);
984 NodeContainer wifiApNode;
985 wifiApNode.Create(1);
986
989 phy.SetChannel(channel.Create());
990
991 // Configure and declare other generic components of this example
992 Ssid ssid;
993 ssid = Ssid("wifi-phy-configuration");
994 WifiMacHelper macSta;
995 macSta.SetType("ns3::StaWifiMac",
996 "Ssid",
997 SsidValue(ssid),
998 "ActiveProbing",
999 BooleanValue(false));
1000 NetDeviceContainer staDevice;
1001 Ptr<YansWifiPhy> phySta;
1002
1003 // Cases taken from src/wifi/examples/wifi-phy-configuration.cc example
1004 {
1005 // case 0:
1006 // Default configuration, without WifiHelper::SetStandard or WifiHelper
1007 phySta = CreateObject<YansWifiPhy>();
1008 // The default results in an invalid configuration
1009 NS_TEST_ASSERT_MSG_EQ(phySta->GetOperatingChannel().IsSet(),
1010 false,
1011 "default configuration");
1012 }
1013 {
1014 // case 1:
1015 WifiHelper wifi;
1016 wifi.SetStandard(WIFI_STANDARD_80211a);
1017 wifi.SetRemoteStationManager("ns3::ArfWifiManager");
1018 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1019 phySta = GetYansWifiPhyPtr(staDevice);
1020 // We expect channel 36, width 20, frequency 5180
1021 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "default configuration");
1022 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "default configuration");
1023 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "default configuration");
1024 }
1025 {
1026 // case 2:
1027 WifiHelper wifi;
1028 wifi.SetStandard(WIFI_STANDARD_80211b);
1029 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1030 phySta = GetYansWifiPhyPtr(staDevice);
1031 // We expect channel 1, width 22, frequency 2412
1032 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 1, "802.11b configuration");
1033 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 22, "802.11b configuration");
1034 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 2412, "802.11b configuration");
1035 }
1036 {
1037 // case 3:
1038 WifiHelper wifi;
1039 wifi.SetStandard(WIFI_STANDARD_80211g);
1040 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1041 phySta = GetYansWifiPhyPtr(staDevice);
1042 // We expect channel 1, width 20, frequency 2412
1043 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 1, "802.11g configuration");
1044 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11g configuration");
1045 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 2412, "802.11g configuration");
1046 }
1047 {
1048 // case 4:
1049 WifiHelper wifi;
1050 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1051 wifi.SetStandard(WIFI_STANDARD_80211n);
1052 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_5GHZ, 0}"));
1053 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1054 phySta = GetYansWifiPhyPtr(staDevice);
1055 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11n-5GHz configuration");
1056 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11n-5GHz configuration");
1057 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11n-5GHz configuration");
1058 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1059 }
1060 {
1061 // case 5:
1062 WifiHelper wifi;
1063 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1064 wifi.SetStandard(WIFI_STANDARD_80211n);
1065 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1066 phySta = GetYansWifiPhyPtr(staDevice);
1067 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 1, "802.11n-2.4GHz configuration");
1068 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11n-2.4GHz configuration");
1069 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 2412, "802.11n-2.4GHz configuration");
1070 }
1071 {
1072 // case 6:
1073 WifiHelper wifi;
1074 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1075 wifi.SetStandard(WIFI_STANDARD_80211ac);
1076 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1077 phySta = GetYansWifiPhyPtr(staDevice);
1078 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 42, "802.11ac configuration");
1079 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 80, "802.11ac configuration");
1080 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5210, "802.11ac configuration");
1081 }
1082 {
1083 // case 7:
1084 // By default, WifiHelper will use WIFI_PHY_STANDARD_80211ax
1085 WifiHelper wifi;
1086 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1087 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_2_4GHZ, 0}"));
1088 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1089 phySta = GetYansWifiPhyPtr(staDevice);
1090 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 1, "802.11ax-2.4GHz configuration");
1091 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11ax-2.4GHz configuration");
1092 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 2412, "802.11ax-2.4GHz configuration");
1093 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1094 }
1095 {
1096 // case 8:
1097 WifiHelper wifi;
1098 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1099 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1100 phySta = GetYansWifiPhyPtr(staDevice);
1101 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 42, "802.11ax-5GHz configuration");
1102 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 80, "802.11ax-5GHz configuration");
1103 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5210, "802.11ax-5GHz configuration");
1104 }
1105 {
1106 // case 9:
1107 WifiHelper wifi;
1108 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1109 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_6GHZ, 0}"));
1110 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1111 phySta = GetYansWifiPhyPtr(staDevice);
1112 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 7, "802.11ax-6GHz configuration");
1113 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 80, "802.11ax-6GHz configuration");
1114 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5985, "802.11ax-6GHz configuration");
1115 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1116 }
1117 {
1118 // case 10:
1119 WifiHelper wifi;
1120 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1121 wifi.SetStandard(WIFI_STANDARD_80211p);
1122 phy.Set("ChannelSettings", StringValue("{0, 10, BAND_5GHZ, 0}"));
1123 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1124 phySta = GetYansWifiPhyPtr(staDevice);
1125 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 172, "802.11p 10Mhz configuration");
1126 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 10, "802.11p 10Mhz configuration");
1127 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5860, "802.11p 10Mhz configuration");
1128 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1129 }
1130 {
1131 // case 11:
1132 WifiHelper wifi;
1133 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1134 wifi.SetStandard(WIFI_STANDARD_80211p);
1135 phy.Set("ChannelSettings", StringValue("{0, 5, BAND_5GHZ, 0}"));
1136 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1137 phySta = GetYansWifiPhyPtr(staDevice);
1138 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 171, "802.11p 5Mhz configuration");
1139 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 5, "802.11p 5Mhz configuration");
1140 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5860, "802.11p 5Mhz configuration");
1141 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1142 }
1143 {
1144 // case 12:
1145 WifiHelper wifi;
1146 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1147 wifi.SetStandard(WIFI_STANDARD_80211n);
1148 phy.Set("ChannelSettings", StringValue("{44, 20, BAND_5GHZ, 0}"));
1149 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1150 phySta = GetYansWifiPhyPtr(staDevice);
1151 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 44, "802.11 5GHz configuration");
1152 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1153 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5220, "802.11 5GHz configuration");
1154 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1155 }
1156 {
1157 // case 13:
1158 WifiHelper wifi;
1159 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1160 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1161 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1162 phySta = GetYansWifiPhyPtr(staDevice);
1163 // Post-install reconfiguration to channel number 40
1164 std::ostringstream path;
1165 path << "/NodeList/*/DeviceList/" << staDevice.Get(0)->GetIfIndex()
1166 << "/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelSettings";
1167 Config::Set(path.str(), StringValue("{40, 0, BAND_5GHZ, 0}"));
1168 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 40, "802.11 5GHz configuration");
1169 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1170 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5200, "802.11 5GHz configuration");
1171 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1172 }
1173 {
1174 // case 14:
1175 WifiHelper wifi;
1176 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1177 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1178 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1179 phySta = GetYansWifiPhyPtr(staDevice);
1180 // Post-install reconfiguration to a 40 MHz channel
1181 std::ostringstream path;
1182 path << "/NodeList/*/DeviceList/" << staDevice.Get(0)->GetIfIndex()
1183 << "/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelSettings";
1184 Config::Set(path.str(), StringValue("{46, 0, BAND_5GHZ, 0}"));
1185 // Although channel 44 is configured originally for 20 MHz, we
1186 // allow it to be used for 40 MHz here
1187 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 46, "802.11 5GHz configuration");
1188 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 40, "802.11 5GHz configuration");
1189 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5230, "802.11 5GHz configuration");
1190 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1191 }
1192 {
1193 // case 15:
1194 WifiHelper wifi;
1195 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1196 wifi.SetStandard(WIFI_STANDARD_80211n);
1197 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1198 phySta = GetYansWifiPhyPtr(staDevice);
1199 phySta->SetAttribute("ChannelSettings", StringValue("{3, 20, BAND_2_4GHZ, 0}"));
1200 // Post-install reconfiguration to a 40 MHz channel
1201 std::ostringstream path;
1202 path << "/NodeList/*/DeviceList/" << staDevice.Get(0)->GetIfIndex()
1203 << "/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelSettings";
1204 Config::Set(path.str(), StringValue("{4, 40, BAND_2_4GHZ, 0}"));
1205 // Although channel 44 is configured originally for 20 MHz, we
1206 // allow it to be used for 40 MHz here
1207 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 4, "802.11 5GHz configuration");
1208 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 40, "802.11 5GHz configuration");
1209 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 2427, "802.11 5GHz configuration");
1210 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1211 }
1212 {
1213 // case 16:
1214 WifiHelper wifi;
1215 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1216 // Test that setting Frequency to a non-standard value will throw an exception
1217 wifi.SetStandard(WIFI_STANDARD_80211n);
1218 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1219 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1220 phySta = GetYansWifiPhyPtr(staDevice);
1221 bool exceptionThrown = false;
1222 try
1223 {
1224 phySta->SetAttribute("ChannelSettings", StringValue("{45, 0, BAND_5GHZ, 0}"));
1225 }
1226 catch (const std::runtime_error&)
1227 {
1228 exceptionThrown = true;
1229 }
1230 // We expect that an exception is thrown
1231 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1232 }
1233 {
1234 // case 17:
1235 WifiHelper wifi;
1236 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1237 wifi.SetStandard(WIFI_STANDARD_80211n);
1238 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1239 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1240 phySta = GetYansWifiPhyPtr(staDevice);
1241 // Test that setting channel to a standard value will set the
1242 // frequency correctly
1243 phySta->SetAttribute("ChannelSettings", StringValue("{100, 0, BAND_5GHZ, 0}"));
1244 // We expect frequency to be 5500 due to channel number being 100
1245 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 100, "802.11 5GHz configuration");
1246 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1247 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5500, "802.11 5GHz configuration");
1248 }
1249 {
1250 // case 18:
1251 // Set a wrong channel after initialization
1252 WifiHelper wifi;
1253 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1254 wifi.SetStandard(WIFI_STANDARD_80211n);
1255 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1256 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1257 phySta = GetYansWifiPhyPtr(staDevice);
1258 bool exceptionThrown = false;
1259 try
1260 {
1261 phySta->SetOperatingChannel(WifiPhy::ChannelTuple{99, 40, WIFI_PHY_BAND_5GHZ, 0});
1262 }
1263 catch (const std::runtime_error&)
1264 {
1265 exceptionThrown = true;
1266 }
1267 // We expect that an exception is thrown
1268 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1269 }
1270 {
1271 // case 19:
1272 WifiHelper wifi;
1273 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1274 // Test how channel number behaves when frequency is non-standard
1275 wifi.SetStandard(WIFI_STANDARD_80211n);
1276 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1277 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1278 phySta = GetYansWifiPhyPtr(staDevice);
1279 bool exceptionThrown = false;
1280 try
1281 {
1282 phySta->SetAttribute("ChannelSettings", StringValue("{45, 0, BAND_5GHZ, 0}"));
1283 }
1284 catch (const std::runtime_error&)
1285 {
1286 exceptionThrown = true;
1287 }
1288 // We expect that an exception is thrown due to unknown channel number 45
1289 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1290 phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1291 // We expect channel number to be 36 due to known center frequency 5180
1292 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1293 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1294 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11 5GHz configuration");
1295 exceptionThrown = false;
1296 try
1297 {
1298 phySta->SetAttribute("ChannelSettings", StringValue("{43, 0, BAND_5GHZ, 0}"));
1299 }
1300 catch (const std::runtime_error&)
1301 {
1302 exceptionThrown = true;
1303 }
1304 // We expect that an exception is thrown due to unknown channel number 43
1305 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1306 phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1307 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1308 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1309 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11 5GHz configuration");
1310 }
1311 {
1312 // case 20:
1313 WifiHelper wifi;
1314 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1315 phy.Set("ChannelSettings", StringValue("{40, 0, BAND_5GHZ, 0}"));
1316 wifi.SetStandard(WIFI_STANDARD_80211n);
1317 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1318 phySta = GetYansWifiPhyPtr(staDevice);
1319 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 40, "802.11 5GHz configuration");
1320 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1321 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5200, "802.11 5GHz configuration");
1322 // Set both channel and frequency to consistent values after initialization
1323 wifi.SetStandard(WIFI_STANDARD_80211n);
1324 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1325 phySta = GetYansWifiPhyPtr(staDevice);
1326 phySta->SetAttribute("ChannelSettings", StringValue("{40, 0, BAND_5GHZ, 0}"));
1327 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 40, "802.11 5GHz configuration");
1328 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1329 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5200, "802.11 5GHz configuration");
1330
1331 phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1332 // We expect channel number to be 36
1333 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1334 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1335 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11 5GHz configuration");
1336 phySta->SetAttribute("ChannelSettings", StringValue("{40, 0, BAND_5GHZ, 0}"));
1337 // We expect channel number to be 40
1338 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 40, "802.11 5GHz configuration");
1339 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1340 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5200, "802.11 5GHz configuration");
1341 bool exceptionThrown = false;
1342 try
1343 {
1344 phySta->SetAttribute("ChannelSettings", StringValue("{45, 0, BAND_5GHZ, 0}"));
1345 }
1346 catch (const std::runtime_error&)
1347 {
1348 exceptionThrown = true;
1349 }
1350 phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1351 // We expect channel number to be 36 and an exception to be thrown
1352 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1353 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1354 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11 5GHz configuration");
1355 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1356 phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1357 exceptionThrown = false;
1358 try
1359 {
1360 phySta->SetAttribute("ChannelSettings", StringValue("{43, 0, BAND_5GHZ, 0}"));
1361 }
1362 catch (const std::runtime_error&)
1363 {
1364 exceptionThrown = true;
1365 }
1366 // We expect channel number to be 36 and an exception to be thrown
1367 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1368 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1369 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11 5GHz configuration");
1370 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1371 }
1372
1374}
1375
1376//-----------------------------------------------------------------------------
1377/**
1378 * Make sure that when virtual collision occurs the wifi remote station manager
1379 * is triggered and the retry counter is increased.
1380 *
1381 * See \bugid{2222}
1382 */
1383
1385{
1386 public:
1388 ~Bug2222TestCase() override;
1389
1390 void DoRun() override;
1391
1392 private:
1393 uint32_t m_countInternalCollisions; ///< count internal collisions
1394
1395 /**
1396 * Transmit data failed function
1397 * \param context the context
1398 * \param adr the MAC address
1399 */
1400 void TxDataFailedTrace(std::string context, Mac48Address adr);
1401};
1402
1404 : TestCase("Test case for Bug 2222"),
1405 m_countInternalCollisions(0)
1406{
1407}
1408
1410{
1411}
1412
1413void
1415{
1416 // Indicate the long retry counter has been increased in the wifi remote station manager
1418}
1419
1420void
1422{
1424
1425 // Generate same backoff for AC_VI and AC_VO
1426 // The below combination will work
1429 int64_t streamNumber = 100;
1430
1431 NodeContainer wifiNodes;
1432 wifiNodes.Create(2);
1433
1436 phy.SetChannel(channel.Create());
1437
1438 WifiHelper wifi;
1439 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
1440 "DataMode",
1441 StringValue("OfdmRate54Mbps"),
1442 "ControlMode",
1443 StringValue("OfdmRate24Mbps"));
1444 WifiMacHelper mac;
1445 Ssid ssid = Ssid("ns-3-ssid");
1446 mac.SetType("ns3::AdhocWifiMac", "QosSupported", BooleanValue(true));
1447
1448 NetDeviceContainer wifiDevices;
1449 wifiDevices = wifi.Install(phy, mac, wifiNodes);
1450
1451 // Assign fixed streams to random variables in use
1452 wifi.AssignStreams(wifiDevices, streamNumber);
1453
1454 MobilityHelper mobility;
1455 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
1456
1457 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
1458 positionAlloc->Add(Vector(10.0, 0.0, 0.0));
1459 mobility.SetPositionAllocator(positionAlloc);
1460
1461 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1462 mobility.Install(wifiNodes);
1463
1464 Ptr<WifiNetDevice> device1 = DynamicCast<WifiNetDevice>(wifiDevices.Get(0));
1465 Ptr<WifiNetDevice> device2 = DynamicCast<WifiNetDevice>(wifiDevices.Get(1));
1466
1467 PacketSocketAddress socket;
1468 socket.SetSingleDevice(device1->GetIfIndex());
1469 socket.SetPhysicalAddress(device2->GetAddress());
1470 socket.SetProtocol(1);
1471
1472 PacketSocketHelper packetSocket;
1473 packetSocket.Install(wifiNodes);
1474
1475 Ptr<PacketSocketClient> clientLowPriority = CreateObject<PacketSocketClient>();
1476 clientLowPriority->SetAttribute("PacketSize", UintegerValue(1460));
1477 clientLowPriority->SetAttribute("MaxPackets", UintegerValue(1));
1478 clientLowPriority->SetAttribute("Priority", UintegerValue(4)); // AC_VI
1479 clientLowPriority->SetRemote(socket);
1480 wifiNodes.Get(0)->AddApplication(clientLowPriority);
1481 clientLowPriority->SetStartTime(Seconds(0.0));
1482 clientLowPriority->SetStopTime(Seconds(1.0));
1483
1484 Ptr<PacketSocketClient> clientHighPriority = CreateObject<PacketSocketClient>();
1485 clientHighPriority->SetAttribute("PacketSize", UintegerValue(1460));
1486 clientHighPriority->SetAttribute("MaxPackets", UintegerValue(1));
1487 clientHighPriority->SetAttribute("Priority", UintegerValue(6)); // AC_VO
1488 clientHighPriority->SetRemote(socket);
1489 wifiNodes.Get(0)->AddApplication(clientHighPriority);
1490 clientHighPriority->SetStartTime(Seconds(0.0));
1491 clientHighPriority->SetStopTime(Seconds(1.0));
1492
1493 Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer>();
1494 server->SetLocal(socket);
1495 wifiNodes.Get(1)->AddApplication(server);
1496 server->SetStartTime(Seconds(0.0));
1497 server->SetStopTime(Seconds(1.0));
1498
1499 Config::Connect("/NodeList/*/DeviceList/*/RemoteStationManager/MacTxDataFailed",
1501
1505
1507 1,
1508 "unexpected number of internal collisions!");
1509}
1510
1511//-----------------------------------------------------------------------------
1512/**
1513 * Make sure that the correct channel width and center frequency have been set
1514 * for OFDM basic rate transmissions and BSS channel widths larger than 20 MHz.
1515 *
1516 * The scenario considers a UDP transmission between a 40 MHz 802.11ac station and a
1517 * 40 MHz 802.11ac access point. All transmission parameters are checked so as
1518 * to ensure that only 2 {starting frequency, channelWidth, Number of subbands
1519 * in SpectrumModel, modulation type} tuples are used.
1520 *
1521 * See \bugid{2843}
1522 */
1523
1525{
1526 public:
1528 ~Bug2843TestCase() override;
1529 void DoRun() override;
1530
1531 private:
1532 /**
1533 * A tuple of {starting frequency, channelWidth, Number of subbands in SpectrumModel, modulation
1534 * type}
1535 */
1536 typedef std::tuple<double, uint16_t, uint32_t, WifiModulationClass>
1538 std::vector<FreqWidthSubbandModulationTuple>
1539 m_distinctTuples; ///< vector of distinct {starting frequency, channelWidth, Number of
1540 ///< subbands in SpectrumModel, modulation type} tuples
1541
1542 /**
1543 * Stores the distinct {starting frequency, channelWidth, Number of subbands in SpectrumModel,
1544 * modulation type} tuples that have been used during the testcase run.
1545 * \param context the context
1546 * \param txParams spectrum signal parameters set by transmitter
1547 */
1548 void StoreDistinctTuple(std::string context, Ptr<SpectrumSignalParameters> txParams);
1549 /**
1550 * Triggers the arrival of a burst of 1000 Byte-long packets in the source device
1551 * \param numPackets number of packets in burst
1552 * \param sourceDevice pointer to the source NetDevice
1553 * \param destination address of the destination device
1554 */
1555 void SendPacketBurst(uint8_t numPackets,
1556 Ptr<NetDevice> sourceDevice,
1557 Address& destination) const;
1558
1559 uint16_t m_channelWidth; ///< channel width (in MHz)
1560};
1561
1563 : TestCase("Test case for Bug 2843"),
1564 m_channelWidth(20)
1565{
1566}
1567
1569{
1570}
1571
1572void
1574{
1575 // Extract starting frequency and number of subbands
1576 Ptr<const SpectrumModel> c = txParams->psd->GetSpectrumModel();
1577 std::size_t numBands = c->GetNumBands();
1578 double startingFreq = c->Begin()->fl;
1579
1580 // Get channel bandwidth and modulation class
1582 DynamicCast<WifiSpectrumSignalParameters>(txParams);
1583
1584 Ptr<WifiPpdu> ppdu = wifiTxParams->ppdu->Copy();
1585 WifiTxVector txVector = ppdu->GetTxVector();
1586 m_channelWidth = txVector.GetChannelWidth();
1587 WifiModulationClass modulationClass = txVector.GetMode().GetModulationClass();
1588
1589 // Build a tuple and check if seen before (if so store it)
1590 FreqWidthSubbandModulationTuple tupleForCurrentTx =
1591 std::make_tuple(startingFreq, m_channelWidth, numBands, modulationClass);
1592 bool found = false;
1593 for (auto it = m_distinctTuples.begin(); it != m_distinctTuples.end(); it++)
1594 {
1595 if (*it == tupleForCurrentTx)
1596 {
1597 found = true;
1598 }
1599 }
1600 if (!found)
1601 {
1602 m_distinctTuples.push_back(tupleForCurrentTx);
1603 }
1604}
1605
1606void
1608 Ptr<NetDevice> sourceDevice,
1609 Address& destination) const
1610{
1611 for (uint8_t i = 0; i < numPackets; i++)
1612 {
1613 Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
1614 sourceDevice->Send(pkt, destination, 0);
1615 }
1616}
1617
1618void
1620{
1621 uint16_t channelWidth = 40; // at least 40 MHz expected here
1622
1623 NodeContainer wifiStaNode;
1624 wifiStaNode.Create(1);
1625
1626 NodeContainer wifiApNode;
1627 wifiApNode.Create(1);
1628
1629 SpectrumWifiPhyHelper spectrumPhy;
1630 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
1631 Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel>();
1632 lossModel->SetFrequency(5.190e9);
1633 spectrumChannel->AddPropagationLossModel(lossModel);
1634
1636 CreateObject<ConstantSpeedPropagationDelayModel>();
1637 spectrumChannel->SetPropagationDelayModel(delayModel);
1638
1639 spectrumPhy.SetChannel(spectrumChannel);
1640 spectrumPhy.SetErrorRateModel("ns3::NistErrorRateModel");
1641 spectrumPhy.Set("ChannelSettings", StringValue("{38, 40, BAND_5GHZ, 0}"));
1642 spectrumPhy.Set("TxPowerStart", DoubleValue(10));
1643 spectrumPhy.Set("TxPowerEnd", DoubleValue(10));
1644
1645 WifiHelper wifi;
1646 wifi.SetStandard(WIFI_STANDARD_80211ac);
1647 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
1648 "DataMode",
1649 StringValue("VhtMcs8"),
1650 "ControlMode",
1651 StringValue("VhtMcs8"),
1652 "RtsCtsThreshold",
1653 StringValue("500")); // so as to force RTS/CTS for data frames
1654
1655 WifiMacHelper mac;
1656 mac.SetType("ns3::StaWifiMac");
1657 NetDeviceContainer staDevice;
1658 staDevice = wifi.Install(spectrumPhy, mac, wifiStaNode);
1659
1660 mac.SetType("ns3::ApWifiMac");
1661 NetDeviceContainer apDevice;
1662 apDevice = wifi.Install(spectrumPhy, mac, wifiApNode);
1663
1664 MobilityHelper mobility;
1665 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
1666 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
1667 positionAlloc->Add(Vector(1.0, 0.0, 0.0)); // put close enough in order to use MCS
1668 mobility.SetPositionAllocator(positionAlloc);
1669
1670 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1671 mobility.Install(wifiApNode);
1672 mobility.Install(wifiStaNode);
1673
1674 // Send two 5 packet-bursts
1677 this,
1678 5,
1679 apDevice.Get(0),
1680 staDevice.Get(0)->GetAddress());
1683 this,
1684 5,
1685 apDevice.Get(0),
1686 staDevice.Get(0)->GetAddress());
1687
1688 Config::Connect("/ChannelList/*/$ns3::MultiModelSpectrumChannel/TxSigParams",
1690
1693
1695
1696 // {starting frequency, channelWidth, Number of subbands in SpectrumModel, modulation type}
1697 // tuples
1698 std::size_t numberTuples = m_distinctTuples.size();
1699 NS_TEST_ASSERT_MSG_EQ(numberTuples, 2, "Only two distinct tuples expected");
1700 NS_TEST_ASSERT_MSG_EQ(std::get<0>(m_distinctTuples[0]) - 20e6,
1701 std::get<0>(m_distinctTuples[1]),
1702 "The starting frequency of the first tuple should be shifted 20 MHz to "
1703 "the right wrt second tuple");
1704 // Note that the first tuple should the one initiated by the beacon, i.e. non-HT OFDM (20 MHz)
1706 20,
1707 "First tuple's channel width should be 20 MHz");
1709 193,
1710 "First tuple should have 193 subbands (64+DC, 20MHz+DC, inband and 64*2 "
1711 "out-of-band, 20MHz on each side)");
1713 WifiModulationClass::WIFI_MOD_CLASS_OFDM,
1714 "First tuple should be OFDM");
1715 // Second tuple
1717 channelWidth,
1718 "Second tuple's channel width should be 40 MHz");
1720 385,
1721 "Second tuple should have 385 subbands (128+DC, 40MHz+DC, inband and "
1722 "128*2 out-of-band, 40MHz on each side)");
1724 WifiModulationClass::WIFI_MOD_CLASS_VHT,
1725 "Second tuple should be VHT_OFDM");
1726}
1727
1728//-----------------------------------------------------------------------------
1729/**
1730 * Make sure that the channel width and the channel number can be changed at runtime.
1731 *
1732 * The scenario considers an access point and a station using a 20 MHz channel width.
1733 * After 1s, we change the channel width and the channel number to use a 40 MHz channel.
1734 * The tests checks the operational channel width sent in Beacon frames
1735 * and verify that the association procedure is executed twice.
1736 *
1737 * See \bugid{2831}
1738 */
1739
1741{
1742 public:
1744 ~Bug2831TestCase() override;
1745 void DoRun() override;
1746
1747 private:
1748 /**
1749 * Function called to change the supported channel width at runtime
1750 */
1752 /**
1753 * Callback triggered when a packet is received by the PHYs
1754 * \param context the context
1755 * \param p the received packet
1756 * \param rxPowersW the received power per channel band in watts
1757 */
1758 void RxCallback(std::string context, Ptr<const Packet> p, RxPowerWattPerChannelBand rxPowersW);
1759
1762
1763 uint16_t m_assocReqCount; ///< count number of association requests
1764 uint16_t m_assocRespCount; ///< count number of association responses
1765 uint16_t m_countOperationalChannelWidth20; ///< count number of beacon frames announcing a 20
1766 ///< MHz operating channel width
1767 uint16_t m_countOperationalChannelWidth40; ///< count number of beacon frames announcing a 40
1768 ///< MHz operating channel width
1769};
1770
1772 : TestCase("Test case for Bug 2831"),
1773 m_assocReqCount(0),
1774 m_assocRespCount(0),
1775 m_countOperationalChannelWidth20(0),
1776 m_countOperationalChannelWidth40(0)
1777{
1778}
1779
1781{
1782}
1783
1784void
1786{
1789}
1790
1791void
1794 RxPowerWattPerChannelBand rxPowersW)
1795{
1796 Ptr<Packet> packet = p->Copy();
1797 WifiMacHeader hdr;
1798 packet->RemoveHeader(hdr);
1799 if (hdr.IsAssocReq())
1800 {
1802 }
1803 else if (hdr.IsAssocResp())
1804 {
1806 }
1807 else if (hdr.IsBeacon())
1808 {
1809 MgtBeaconHeader beacon;
1810 packet->RemoveHeader(beacon);
1811 const auto& htOperation = beacon.Get<HtOperation>();
1812 if (htOperation.has_value() && htOperation->GetStaChannelWidth() > 0)
1813 {
1815 }
1816 else
1817 {
1819 }
1820 }
1821}
1822
1823void
1825{
1826 Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel>();
1827 ObjectFactory propDelay;
1828 propDelay.SetTypeId("ns3::ConstantSpeedPropagationDelayModel");
1829 Ptr<PropagationDelayModel> propagationDelay = propDelay.Create<PropagationDelayModel>();
1830 Ptr<PropagationLossModel> propagationLoss = CreateObject<FriisPropagationLossModel>();
1831 channel->SetPropagationDelayModel(propagationDelay);
1832 channel->SetPropagationLossModel(propagationLoss);
1833
1834 Ptr<Node> apNode = CreateObject<Node>();
1835 Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice>();
1836 apNode->AddDevice(apDev);
1837 apDev->SetStandard(WIFI_STANDARD_80211ax);
1838 Ptr<HtConfiguration> apHtConfiguration = CreateObject<HtConfiguration>();
1839 apDev->SetHtConfiguration(apHtConfiguration);
1840 ObjectFactory manager;
1841 manager.SetTypeId("ns3::ConstantRateWifiManager");
1842 apDev->SetRemoteStationManager(manager.Create<WifiRemoteStationManager>());
1843
1844 auto apMobility = CreateObject<ConstantPositionMobilityModel>();
1845 apMobility->SetPosition(Vector(0.0, 0.0, 0.0));
1846 apNode->AggregateObject(apMobility);
1847
1848 auto error = CreateObject<YansErrorRateModel>();
1849 m_apPhy = CreateObject<YansWifiPhy>();
1850 apDev->SetPhy(m_apPhy);
1851 Ptr<InterferenceHelper> apInterferenceHelper = CreateObject<InterferenceHelper>();
1852 m_apPhy->SetInterferenceHelper(apInterferenceHelper);
1853 m_apPhy->SetErrorRateModel(error);
1854 m_apPhy->SetChannel(channel);
1855 m_apPhy->SetMobility(apMobility);
1856 m_apPhy->SetDevice(apDev);
1859
1860 ObjectFactory mac;
1861 mac.SetTypeId("ns3::ApWifiMac");
1862 mac.Set("EnableBeaconJitter", BooleanValue(false));
1863 mac.Set("QosSupported", BooleanValue(true));
1864 for (const std::string ac : {"BE", "BK", "VI", "VO"})
1865 {
1866 auto qosTxop =
1867 CreateObjectWithAttributes<QosTxop>("AcIndex", StringValue(std::string("AC_") + ac));
1868 mac.Set(ac + "_Txop", PointerValue(qosTxop));
1869 }
1870 auto apMac = mac.Create<WifiMac>();
1871 apMac->SetDevice(apDev);
1872 apMac->SetAddress(Mac48Address::Allocate());
1873 apDev->SetMac(apMac);
1874 apMac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
1875 apMac->SetFrameExchangeManagers({CreateObject<HeFrameExchangeManager>()});
1876 apMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
1877 Ptr<FrameExchangeManager> fem = apMac->GetFrameExchangeManager();
1878 fem->SetAddress(apMac->GetAddress());
1879 Ptr<WifiProtectionManager> protectionManager = CreateObject<WifiDefaultProtectionManager>();
1880 protectionManager->SetWifiMac(apMac);
1881 fem->SetProtectionManager(protectionManager);
1882 Ptr<WifiAckManager> ackManager = CreateObject<WifiDefaultAckManager>();
1883 ackManager->SetWifiMac(apMac);
1884 fem->SetAckManager(ackManager);
1885
1886 Ptr<Node> staNode = CreateObject<Node>();
1887 Ptr<WifiNetDevice> staDev = CreateObject<WifiNetDevice>();
1888 staNode->AddDevice(staDev);
1889 staDev->SetStandard(WIFI_STANDARD_80211ax);
1890 Ptr<HtConfiguration> staHtConfiguration = CreateObject<HtConfiguration>();
1891 staDev->SetHtConfiguration(staHtConfiguration);
1892 staDev->SetRemoteStationManager(manager.Create<WifiRemoteStationManager>());
1893
1894 Ptr<ConstantPositionMobilityModel> staMobility = CreateObject<ConstantPositionMobilityModel>();
1895 staMobility->SetPosition(Vector(1.0, 0.0, 0.0));
1896 staNode->AggregateObject(staMobility);
1897
1898 m_staPhy = CreateObject<YansWifiPhy>();
1899 staDev->SetPhy(m_staPhy);
1900 Ptr<InterferenceHelper> staInterferenceHelper = CreateObject<InterferenceHelper>();
1901 m_staPhy->SetInterferenceHelper(staInterferenceHelper);
1903 m_staPhy->SetChannel(channel);
1904 m_staPhy->SetMobility(staMobility);
1905 m_staPhy->SetDevice(apDev);
1908
1909 mac.SetTypeId("ns3::StaWifiMac");
1910 for (const std::string ac : {"BE", "BK", "VI", "VO"})
1911 {
1912 auto qosTxop =
1913 CreateObjectWithAttributes<QosTxop>("AcIndex", StringValue(std::string("AC_") + ac));
1914 mac.Set(ac + "_Txop", PointerValue(qosTxop));
1915 }
1916 auto staMac = mac.Create<WifiMac>();
1917 staDev->SetMac(staMac);
1918 staMac->SetDevice(staDev);
1919 staMac->SetAddress(Mac48Address::Allocate());
1920 staMac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
1921 staMac->SetFrameExchangeManagers({CreateObject<HeFrameExchangeManager>()});
1922 StaticCast<StaWifiMac>(staMac)->SetAssocManager(CreateObject<WifiDefaultAssocManager>());
1923 staMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
1924 fem = staMac->GetFrameExchangeManager();
1925 fem->SetAddress(staMac->GetAddress());
1926 protectionManager = CreateObject<WifiDefaultProtectionManager>();
1927 protectionManager->SetWifiMac(staMac);
1928 fem->SetProtectionManager(protectionManager);
1929 ackManager = CreateObject<WifiDefaultAckManager>();
1930 ackManager->SetWifiMac(staMac);
1931 fem->SetAckManager(ackManager);
1932
1933 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxBegin",
1935
1937
1941
1942 NS_TEST_ASSERT_MSG_EQ(m_assocReqCount, 2, "Second Association request not received");
1943 NS_TEST_ASSERT_MSG_EQ(m_assocRespCount, 2, "Second Association response not received");
1945 10,
1946 "Incorrect operational channel width before channel change");
1948 20,
1949 "Incorrect operational channel width after channel change");
1950}
1951
1952//-----------------------------------------------------------------------------
1953/**
1954 * Make sure that Wifi STA is correctly associating to the best AP (i.e.,
1955 * nearest from STA). We consider 3 AP and 1 STA. This test case consisted of
1956 * three sub tests:
1957 * - The best AP sends its beacon later than the other APs. STA is expected
1958 * to associate to the best AP.
1959 * - The STA is using active scanning instead of passive, the rest of the
1960 * APs works normally. STA is expected to associate to the best AP
1961 * - The nearest AP is turned off after sending beacon and while STA is
1962 * still scanning. STA is expected to associate to the second best AP.
1963 *
1964 * See \bugid{2399}
1965 * \todo Add explicit association refusal test if ns-3 implemented it.
1966 */
1967
1969{
1970 public:
1972 ~StaWifiMacScanningTestCase() override;
1973 void DoRun() override;
1974
1975 private:
1976 /**
1977 * Callback function on STA assoc event
1978 * \param context context string
1979 * \param bssid the associated AP's bssid
1980 */
1981 void AssocCallback(std::string context, Mac48Address bssid);
1982 /**
1983 * Turn beacon generation on the AP node
1984 * \param apNode the AP node
1985 */
1986 void TurnBeaconGenerationOn(Ptr<Node> apNode);
1987 /**
1988 * Turn the AP node off
1989 * \param apNode the AP node
1990 */
1991 void TurnApOff(Ptr<Node> apNode);
1992 /**
1993 * Setup test
1994 * \param nearestApBeaconGeneration set BeaconGeneration attribute of the nearest AP
1995 * \param staActiveProbe set ActiveProbing attribute of the STA
1996 * \return node container containing all nodes
1997 */
1998 NodeContainer Setup(bool nearestApBeaconGeneration, bool staActiveProbe);
1999
2000 Mac48Address m_associatedApBssid; ///< Associated AP's bssid
2001};
2002
2004 : TestCase("Test case for StaWifiMac scanning capability")
2005{
2006}
2007
2009{
2010}
2011
2012void
2014{
2015 m_associatedApBssid = bssid;
2016}
2017
2018void
2020{
2021 Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice>(apNode->GetDevice(0));
2022 Ptr<ApWifiMac> mac = DynamicCast<ApWifiMac>(netDevice->GetMac());
2023 mac->SetAttribute("BeaconGeneration", BooleanValue(true));
2024}
2025
2026void
2028{
2029 Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice>(apNode->GetDevice(0));
2030 Ptr<WifiPhy> phy = netDevice->GetPhy();
2031 phy->SetOffMode();
2032}
2033
2035StaWifiMacScanningTestCase::Setup(bool nearestApBeaconGeneration, bool staActiveProbe)
2036{
2039 int64_t streamNumber = 1;
2040
2041 NodeContainer apNodes;
2042 apNodes.Create(2);
2043
2044 Ptr<Node> apNodeNearest = CreateObject<Node>();
2045 Ptr<Node> staNode = CreateObject<Node>();
2046
2049 phy.SetChannel(channel.Create());
2050
2051 WifiHelper wifi;
2052 wifi.SetStandard(WIFI_STANDARD_80211n);
2053 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager");
2054
2055 WifiMacHelper mac;
2056 NetDeviceContainer apDevice;
2057 NetDeviceContainer apDeviceNearest;
2058 mac.SetType("ns3::ApWifiMac", "BeaconGeneration", BooleanValue(true));
2059 apDevice = wifi.Install(phy, mac, apNodes);
2060 mac.SetType("ns3::ApWifiMac", "BeaconGeneration", BooleanValue(nearestApBeaconGeneration));
2061 apDeviceNearest = wifi.Install(phy, mac, apNodeNearest);
2062
2063 NetDeviceContainer staDevice;
2064 mac.SetType("ns3::StaWifiMac", "ActiveProbing", BooleanValue(staActiveProbe));
2065 staDevice = wifi.Install(phy, mac, staNode);
2066
2067 // Assign fixed streams to random variables in use
2068 wifi.AssignStreams(apDevice, streamNumber);
2069 wifi.AssignStreams(apDeviceNearest, streamNumber + 1);
2070 wifi.AssignStreams(staDevice, streamNumber + 2);
2071
2072 MobilityHelper mobility;
2073 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
2074 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Furthest AP
2075 positionAlloc->Add(Vector(10.0, 0.0, 0.0)); // Second nearest AP
2076 positionAlloc->Add(Vector(5.0, 5.0, 0.0)); // Nearest AP
2077 positionAlloc->Add(Vector(6.0, 5.0, 0.0)); // STA
2078 mobility.SetPositionAllocator(positionAlloc);
2079
2080 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2081 mobility.Install(apNodes);
2082 mobility.Install(apNodeNearest);
2083 mobility.Install(staNode);
2084
2085 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/Assoc",
2087
2088 NodeContainer allNodes = NodeContainer(apNodes, apNodeNearest, staNode);
2089 return allNodes;
2090}
2091
2092void
2094{
2095 {
2096 NodeContainer nodes = Setup(false, false);
2097 Ptr<Node> nearestAp = nodes.Get(2);
2098 Mac48Address nearestApAddr =
2099 DynamicCast<WifiNetDevice>(nearestAp->GetDevice(0))->GetMac()->GetAddress();
2100
2103 this,
2104 nearestAp);
2105
2109
2111 nearestApAddr,
2112 "STA is associated to the wrong AP");
2113 }
2115 {
2116 NodeContainer nodes = Setup(true, true);
2117 Ptr<Node> nearestAp = nodes.Get(2);
2118 Mac48Address nearestApAddr =
2119 DynamicCast<WifiNetDevice>(nearestAp->GetDevice(0))->GetMac()->GetAddress();
2120
2124
2126 nearestApAddr,
2127 "STA is associated to the wrong AP");
2128 }
2130 {
2131 NodeContainer nodes = Setup(true, false);
2132 Ptr<Node> nearestAp = nodes.Get(2);
2133 Mac48Address secondNearestApAddr =
2134 DynamicCast<WifiNetDevice>(nodes.Get(1)->GetDevice(0))->GetMac()->GetAddress();
2135
2137
2141
2143 secondNearestApAddr,
2144 "STA is associated to the wrong AP");
2145 }
2146}
2147
2148//-----------------------------------------------------------------------------
2149/**
2150 * Make sure that the ADDBA handshake process is protected.
2151 *
2152 * The scenario considers an access point and a station. It utilizes
2153 * ReceiveListErrorModel to drop by force ADDBA request on STA or ADDBA
2154 * response on AP. The AP sends 5 packets of each 1000 bytes (thus generating
2155 * BA agreement), 2 times during the test at 0.5s and 0.8s. We only drop the
2156 * first ADDBA request/response of the first BA negotiation. Therefore, we
2157 * expect that the packets still in queue after the failed BA agreement will be
2158 * sent with normal MPDU, and packets queued after that should be sent with
2159 * A-MPDU.
2160 *
2161 * This test consider 2 cases:
2162 *
2163 * 1. ADDBA request packets are blocked on receive at STA, triggering
2164 * transmission failure at AP
2165 * 2. ADDBA response packets are blocked on receive at AP, STA stops
2166 * retransmission of ADDBA response
2167 *
2168 * See \bugid{2470}
2169 */
2170
2172{
2173 public:
2175 ~Bug2470TestCase() override;
2176 void DoRun() override;
2177
2178 private:
2179 /**
2180 * Callback when ADDBA state changed
2181 * \param context node context
2182 * \param t the time the state changed
2183 * \param recipient the MAC address of the recipient
2184 * \param tid the TID
2185 * \param state the state
2186 */
2187 void AddbaStateChangedCallback(std::string context,
2188 Time t,
2189 Mac48Address recipient,
2190 uint8_t tid,
2192 /**
2193 * Callback when a frame is transmitted.
2194 * \param rxErrorModel the post reception error model on the receiver
2195 * \param context the context
2196 * \param psduMap the PSDU map
2197 * \param txVector the TX vector
2198 * \param txPowerW the tx power in Watts
2199 */
2200 void TxCallback(Ptr<ListErrorModel> rxErrorModel,
2201 std::string context,
2202 WifiConstPsduMap psduMap,
2203 WifiTxVector txVector,
2204 double txPowerW);
2205
2206 /**
2207 * Callback when packet is received
2208 * \param context node context
2209 * \param p the received packet
2210 * \param channelFreqMhz the channel frequency in MHz
2211 * \param txVector the TX vector
2212 * \param aMpdu the A-MPDU info
2213 * \param signalNoise the signal noise in dBm
2214 * \param staId the STA-ID
2215 */
2216 void RxCallback(std::string context,
2218 uint16_t channelFreqMhz,
2219 WifiTxVector txVector,
2220 MpduInfo aMpdu,
2221 SignalNoiseDbm signalNoise,
2222 uint16_t staId);
2223 /**
2224 * Callback when packet is dropped
2225 * \param context node context
2226 * \param p the failed packet
2227 * \param snr the SNR of the failed packet in linear scale
2228 */
2229 void RxErrorCallback(std::string context, Ptr<const Packet> p, double snr);
2230 /**
2231 * Triggers the arrival of a burst of 1000 Byte-long packets in the source device
2232 * \param numPackets number of packets in burst
2233 * \param sourceDevice pointer to the source NetDevice
2234 * \param destination address of the destination device
2235 */
2236 void SendPacketBurst(uint32_t numPackets,
2237 Ptr<NetDevice> sourceDevice,
2238 Address& destination) const;
2239 /**
2240 * Run subtest for this test suite
2241 * \param rcvErrorType type of station (STA or AP) to install the post reception error model on
2242 */
2243 void RunSubtest(TypeOfStation rcvErrorType);
2244
2245 uint16_t m_receivedNormalMpduCount; ///< Count received normal MPDU packets on STA
2246 uint16_t m_receivedAmpduCount; ///< Count received A-MPDU packets on STA
2247 uint16_t m_failedActionCount; ///< Count failed ADDBA request/response
2248 uint16_t m_addbaEstablishedCount; ///< Count number of times ADDBA state machine is in
2249 ///< established state
2250 uint16_t m_addbaPendingCount; ///< Count number of times ADDBA state machine is in pending state
2251 uint16_t
2252 m_addbaRejectedCount; ///< Count number of times ADDBA state machine is in rejected state
2253 uint16_t
2254 m_addbaNoReplyCount; ///< Count number of times ADDBA state machine is in no_reply state
2255 uint16_t m_addbaResetCount; ///< Count number of times ADDBA state machine is in reset state
2256};
2257
2259 : TestCase("Test case for Bug 2470"),
2260 m_receivedNormalMpduCount(0),
2261 m_receivedAmpduCount(0),
2262 m_failedActionCount(0),
2263 m_addbaEstablishedCount(0),
2264 m_addbaPendingCount(0),
2265 m_addbaRejectedCount(0),
2266 m_addbaNoReplyCount(0),
2267 m_addbaResetCount(0)
2268{
2269}
2270
2272{
2273}
2274
2275void
2277 Time t,
2278 Mac48Address recipient,
2279 uint8_t tid,
2281{
2282 switch (state)
2283 {
2286 break;
2289 break;
2292 break;
2295 break;
2298 break;
2299 }
2300}
2301
2302void
2304 std::string context,
2305 WifiConstPsduMap psduMap,
2306 WifiTxVector txVector,
2307 double txPowerW)
2308{
2309 auto psdu = psduMap.begin()->second;
2310
2311 // The sender is transmitting an ADDBA_REQUEST or ADDBA_RESPONSE frame. If this is
2312 // the first attempt at establishing a BA agreement (i.e., before the second set of packets
2313 // is generated), make the reception of the frame fail at the receiver.
2314 if (psdu->GetHeader(0).GetType() == WIFI_MAC_MGT_ACTION && Simulator::Now() < Seconds(0.8))
2315 {
2316 auto uid = psdu->GetPayload(0)->GetUid();
2317 rxErrorModel->SetList({uid});
2318 }
2319}
2320
2321void
2324 uint16_t channelFreqMhz,
2325 WifiTxVector txVector,
2326 MpduInfo aMpdu,
2327 SignalNoiseDbm signalNoise,
2328 uint16_t staId)
2329{
2330 Ptr<Packet> packet = p->Copy();
2331 if (aMpdu.type != MpduType::NORMAL_MPDU)
2332 {
2334 }
2335 else
2336 {
2337 WifiMacHeader hdr;
2338 packet->RemoveHeader(hdr);
2339 if (hdr.IsData())
2340 {
2342 }
2343 }
2344}
2345
2346void
2347Bug2470TestCase::RxErrorCallback(std::string context, Ptr<const Packet> p, double snr)
2348{
2349 Ptr<Packet> packet = p->Copy();
2350 WifiMacHeader hdr;
2351 packet->RemoveHeader(hdr);
2352 if (hdr.IsAction())
2353 {
2355 }
2356}
2357
2358void
2360 Ptr<NetDevice> sourceDevice,
2361 Address& destination) const
2362{
2363 for (uint32_t i = 0; i < numPackets; i++)
2364 {
2365 Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
2366 sourceDevice->Send(pkt, destination, 0);
2367 }
2368}
2369
2370void
2372{
2375 int64_t streamNumber = 200;
2376
2377 NodeContainer wifiApNode;
2378 NodeContainer wifiStaNode;
2379 wifiApNode.Create(1);
2380 wifiStaNode.Create(1);
2381
2384 phy.SetChannel(channel.Create());
2385
2386 WifiHelper wifi;
2387 wifi.SetStandard(WIFI_STANDARD_80211n);
2388 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
2389 "DataMode",
2390 StringValue("HtMcs7"),
2391 "ControlMode",
2392 StringValue("HtMcs7"));
2393
2394 WifiMacHelper mac;
2395 NetDeviceContainer apDevice;
2396 phy.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}"));
2397 mac.SetType("ns3::ApWifiMac", "EnableBeaconJitter", BooleanValue(false));
2398 apDevice = wifi.Install(phy, mac, wifiApNode);
2399
2400 NetDeviceContainer staDevice;
2401 mac.SetType("ns3::StaWifiMac");
2402 staDevice = wifi.Install(phy, mac, wifiStaNode);
2403
2404 // Assign fixed streams to random variables in use
2405 wifi.AssignStreams(apDevice, streamNumber);
2406 wifi.AssignStreams(staDevice, streamNumber);
2407
2408 MobilityHelper mobility;
2409 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
2410 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2411 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
2412 mobility.SetPositionAllocator(positionAlloc);
2413
2414 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2415 mobility.Install(wifiApNode);
2416 mobility.Install(wifiStaNode);
2417
2418 auto rxErrorModel = CreateObject<ListErrorModel>();
2419 Ptr<WifiMac> wifiMac;
2420 switch (rcvErrorType)
2421 {
2422 case AP:
2423 wifiMac = DynamicCast<WifiNetDevice>(apDevice.Get(0))->GetMac();
2424 break;
2425 case STA:
2426 wifiMac = DynamicCast<WifiNetDevice>(staDevice.Get(0))->GetMac();
2427 break;
2428 default:
2429 NS_ABORT_MSG("Station type " << +rcvErrorType << " cannot be used here");
2430 }
2431 wifiMac->GetWifiPhy(0)->SetPostReceptionErrorModel(rxErrorModel);
2432
2434 "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/MonitorSnifferRx",
2436 Config::Connect("/NodeList/*/DeviceList/*/Phy/State/RxError",
2438 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/BE_Txop/"
2439 "BlockAckManager/AgreementState",
2441 Config::Connect("/NodeList/" + std::to_string(rcvErrorType == STA ? 0 /* AP */ : 1 /* STA */) +
2442 "/DeviceList/*/$ns3::WifiNetDevice/Phys/0/PhyTxPsduBegin",
2443 MakeCallback(&Bug2470TestCase::TxCallback, this).Bind(rxErrorModel));
2444
2447 this,
2448 1,
2449 apDevice.Get(0),
2450 staDevice.Get(0)->GetAddress());
2453 this,
2454 4,
2455 apDevice.Get(0),
2456 staDevice.Get(0)->GetAddress());
2459 this,
2460 1,
2461 apDevice.Get(0),
2462 staDevice.Get(0)->GetAddress());
2465 this,
2466 4,
2467 apDevice.Get(0),
2468 staDevice.Get(0)->GetAddress());
2469
2473}
2474
2475void
2477{
2478 {
2479 RunSubtest(STA);
2480 NS_TEST_ASSERT_MSG_EQ(m_failedActionCount, 7, "ADDBA request packets are not failed");
2481 // There are two sets of 5 packets to be transmitted. The first 5 packets should be sent by
2482 // normal MPDU because of failed ADDBA handshake. For the second set, the first packet
2483 // should be sent by normal MPDU, and the rest with A-MPDU. In total we expect to receive 6
2484 // normal MPDU packets and 4 A-MPDU packet.
2486 6,
2487 "Receiving incorrect number of normal MPDU packet on subtest 1");
2489 4,
2490 "Receiving incorrect number of A-MPDU packets on subtest 1");
2491
2493 1,
2494 "Incorrect number of times the ADDBA state machine was in "
2495 "established state on subtest 1");
2498 2,
2499 "Incorrect number of times the ADDBA state machine was in pending state on subtest 1");
2502 0,
2503 "Incorrect number of times the ADDBA state machine was in rejected state on subtest 1");
2506 1,
2507 "Incorrect number of times the ADDBA state machine was in no_reply state on subtest 1");
2510 1,
2511 "Incorrect number of times the ADDBA state machine was in reset state on subtest 1");
2512 }
2513
2522
2523 {
2524 RunSubtest(AP);
2525 NS_TEST_ASSERT_MSG_EQ(m_failedActionCount, 7, "ADDBA response packets are not failed");
2526 // Similar to subtest 1, we also expect to receive 6 normal MPDU packets and 4 A-MPDU
2527 // packets.
2529 6,
2530 "Receiving incorrect number of normal MPDU packet on subtest 2");
2532 4,
2533 "Receiving incorrect number of A-MPDU packet on subtest 2");
2534
2536 1,
2537 "Incorrect number of times the ADDBA state machine was in "
2538 "established state on subtest 2");
2541 2,
2542 "Incorrect number of times the ADDBA state machine was in pending state on subtest 2");
2545 0,
2546 "Incorrect number of times the ADDBA state machine was in rejected state on subtest 2");
2549 1,
2550 "Incorrect number of times the ADDBA state machine was in no_reply state on subtest 2");
2553 1,
2554 "Incorrect number of times the ADDBA state machine was in reset state on subtest 2");
2555 }
2556
2557 // TODO: In the second test set, it does not go to reset state since ADDBA response is received
2558 // after timeout (NO_REPLY) but before it does not enter RESET state. More tests should be
2559 // written to verify all possible scenarios.
2560}
2561
2562//-----------------------------------------------------------------------------
2563/**
2564 * Make sure that Ideal rate manager recovers when the station is moving away from the access point.
2565 *
2566 * The scenario considers an access point and a moving station.
2567 * Initially, the station is located at 1 meter from the access point.
2568 * After 1s, the station moves away from the access for 0.5s to
2569 * reach a point away of 50 meters from the access point.
2570 * The tests checks the Ideal rate manager is reset once it has
2571 * failed to transmit a data packet, so that the next data packets
2572 * can be successfully transmitted using a lower modulation.
2573 *
2574 * See \issueid{40}
2575 */
2576
2578{
2579 public:
2581 ~Issue40TestCase() override;
2582 void DoRun() override;
2583
2584 private:
2585 /**
2586 * Run one function
2587 * \param useAmpdu flag to indicate whether the test should be run with A-MPDU
2588 */
2589 void RunOne(bool useAmpdu);
2590
2591 /**
2592 * Callback when packet is successfully received
2593 * \param context node context
2594 * \param p the received packet
2595 */
2596 void RxSuccessCallback(std::string context, Ptr<const Packet> p);
2597 /**
2598 * Triggers the arrival of 1000 Byte-long packets in the source device
2599 * \param numPackets number of packets in burst
2600 * \param sourceDevice pointer to the source NetDevice
2601 * \param destination address of the destination device
2602 */
2603 void SendPackets(uint8_t numPackets, Ptr<NetDevice> sourceDevice, Address& destination);
2604 /**
2605 * Transmit final data failed function
2606 * \param context the context
2607 * \param address the MAC address
2608 */
2609 void TxFinalDataFailedCallback(std::string context, Mac48Address address);
2610
2611 uint16_t m_rxCount; ///< Count number of successfully received data packets
2612 uint16_t m_txCount; ///< Count number of transmitted data packets
2613 uint16_t
2614 m_txMacFinalDataFailedCount; ///< Count number of unsuccessfuly transmitted data packets
2615};
2616
2618 : TestCase("Test case for issue #40"),
2619 m_rxCount(0),
2620 m_txCount(0),
2621 m_txMacFinalDataFailedCount(0)
2622{
2623}
2624
2626{
2627}
2628
2629void
2631{
2632 m_rxCount++;
2633}
2634
2635void
2636Issue40TestCase::SendPackets(uint8_t numPackets, Ptr<NetDevice> sourceDevice, Address& destination)
2637{
2638 for (uint8_t i = 0; i < numPackets; i++)
2639 {
2640 Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
2641 sourceDevice->Send(pkt, destination, 0);
2642 m_txCount++;
2643 }
2644}
2645
2646void
2648{
2650}
2651
2652void
2654{
2655 m_rxCount = 0;
2656 m_txCount = 0;
2658
2661 int64_t streamNumber = 100;
2662
2663 NodeContainer wifiApNode;
2664 NodeContainer wifiStaNode;
2665 wifiApNode.Create(1);
2666 wifiStaNode.Create(1);
2667
2670 phy.SetChannel(channel.Create());
2671
2672 WifiHelper wifi;
2673 wifi.SetStandard(WIFI_STANDARD_80211ac);
2674 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
2675
2676 WifiMacHelper mac;
2677 NetDeviceContainer apDevice;
2678 mac.SetType("ns3::ApWifiMac");
2679 apDevice = wifi.Install(phy, mac, wifiApNode);
2680
2681 NetDeviceContainer staDevice;
2682 mac.SetType("ns3::StaWifiMac");
2683 staDevice = wifi.Install(phy, mac, wifiStaNode);
2684
2685 // Assign fixed streams to random variables in use
2686 wifi.AssignStreams(apDevice, streamNumber);
2687 wifi.AssignStreams(staDevice, streamNumber);
2688
2689 MobilityHelper mobility;
2690 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
2691 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2692 positionAlloc->Add(Vector(10.0, 0.0, 0.0));
2693 mobility.SetPositionAllocator(positionAlloc);
2694
2695 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2696 mobility.Install(wifiApNode);
2697
2698 mobility.SetMobilityModel("ns3::WaypointMobilityModel");
2699 mobility.Install(wifiStaNode);
2700
2701 Config::Connect("/NodeList/*/DeviceList/*/RemoteStationManager/MacTxFinalDataFailed",
2703 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/MacRx",
2705
2706 Ptr<WaypointMobilityModel> staWaypointMobility =
2707 DynamicCast<WaypointMobilityModel>(wifiStaNode.Get(0)->GetObject<MobilityModel>());
2708 staWaypointMobility->AddWaypoint(Waypoint(Seconds(1.0), Vector(10.0, 0.0, 0.0)));
2709 staWaypointMobility->AddWaypoint(Waypoint(Seconds(1.5), Vector(50.0, 0.0, 0.0)));
2710
2711 if (useAmpdu)
2712 {
2713 // Disable use of BAR that are sent with the lowest modulation so that we can also reproduce
2714 // the problem with A-MPDU, i.e. the lack of feedback about SNR change
2715 Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice>(apDevice.Get(0));
2716 PointerValue ptr;
2717 ap_device->GetMac()->GetAttribute("BE_Txop", ptr);
2718 ptr.Get<QosTxop>()->SetAttribute("UseExplicitBarAfterMissedBlockAck", BooleanValue(false));
2719 }
2720
2721 // Transmit a first data packet before the station moves: it should be sent with a high
2722 // modulation and successfully received
2725 this,
2726 useAmpdu ? 2 : 1,
2727 apDevice.Get(0),
2728 staDevice.Get(0)->GetAddress());
2729
2730 // Transmit a second data packet once the station is away from the access point: it should be
2731 // sent with the same high modulation and be unsuccessfuly received
2734 this,
2735 useAmpdu ? 2 : 1,
2736 apDevice.Get(0),
2737 staDevice.Get(0)->GetAddress());
2738
2739 // Keep on transmitting data packets while the station is away from the access point: it should
2740 // be sent with a lower modulation and be successfully received
2743 this,
2744 useAmpdu ? 2 : 1,
2745 apDevice.Get(0),
2746 staDevice.Get(0)->GetAddress());
2749 this,
2750 useAmpdu ? 2 : 1,
2751 apDevice.Get(0),
2752 staDevice.Get(0)->GetAddress());
2755 this,
2756 useAmpdu ? 2 : 1,
2757 apDevice.Get(0),
2758 staDevice.Get(0)->GetAddress());
2761 this,
2762 useAmpdu ? 2 : 1,
2763 apDevice.Get(0),
2764 staDevice.Get(0)->GetAddress());
2767 this,
2768 useAmpdu ? 2 : 1,
2769 apDevice.Get(0),
2770 staDevice.Get(0)->GetAddress());
2771
2774
2776 (useAmpdu ? 14 : 7),
2777 "Incorrect number of transmitted packets");
2779 (useAmpdu ? 12 : 6),
2780 "Incorrect number of successfully received packets");
2781 NS_TEST_ASSERT_MSG_EQ(m_txMacFinalDataFailedCount, 1, "Incorrect number of dropped TX packets");
2782
2784}
2785
2786void
2788{
2789 // Test without A-MPDU
2790 RunOne(false);
2791
2792 // Test with A-MPDU
2793 RunOne(true);
2794}
2795
2796//-----------------------------------------------------------------------------
2797/**
2798 * Make sure that Ideal rate manager is able to handle non best-effort traffic.
2799 *
2800 * The scenario considers an access point and a fixed station.
2801 * The station first sends a best-effort packet to the access point,
2802 * for which Ideal rate manager should select a VHT rate. Then,
2803 * the station sends a non best-effort (voice) packet to the access point,
2804 * and since SNR is unchanged, the same VHT rate should be used.
2805 *
2806 * See \issueid{169}
2807 */
2808
2810{
2811 public:
2813 ~Issue169TestCase() override;
2814 void DoRun() override;
2815
2816 private:
2817 /**
2818 * Triggers the transmission of a 1000 Byte-long data packet from the source device
2819 * \param numPackets number of packets in burst
2820 * \param sourceDevice pointer to the source NetDevice
2821 * \param destination address of the destination device
2822 * \param priority the priority of the packets to send
2823 */
2824 void SendPackets(uint8_t numPackets,
2825 Ptr<NetDevice> sourceDevice,
2826 Address& destination,
2827 uint8_t priority);
2828
2829 /**
2830 * Callback that indicates a PSDU is being transmitted
2831 * \param context the context
2832 * \param psdus the PSDU map to transmit
2833 * \param txVector the TX vector
2834 * \param txPowerW the TX power (W)
2835 */
2836 void TxCallback(std::string context,
2837 WifiConstPsduMap psdus,
2838 WifiTxVector txVector,
2839 double txPowerW);
2840};
2841
2843 : TestCase("Test case for issue #169")
2844{
2845}
2846
2848{
2849}
2850
2851void
2853 Ptr<NetDevice> sourceDevice,
2854 Address& destination,
2855 uint8_t priority)
2856{
2857 SocketPriorityTag priorityTag;
2858 priorityTag.SetPriority(priority);
2859 for (uint8_t i = 0; i < numPackets; i++)
2860 {
2861 Ptr<Packet> packet = Create<Packet>(1000); // 1000 dummy bytes of data
2862 packet->AddPacketTag(priorityTag);
2863 sourceDevice->Send(packet, destination, 0);
2864 }
2865}
2866
2867void
2869 WifiConstPsduMap psdus,
2870 WifiTxVector txVector,
2871 double txPowerW)
2872{
2873 if (psdus.begin()->second->GetSize() >= 1000)
2874 {
2876 WifiModulationClass::WIFI_MOD_CLASS_VHT,
2877 "Ideal rate manager selected incorrect modulation class");
2878 }
2879}
2880
2881void
2883{
2886 int64_t streamNumber = 100;
2887
2888 NodeContainer wifiApNode;
2889 NodeContainer wifiStaNode;
2890 wifiApNode.Create(1);
2891 wifiStaNode.Create(1);
2892
2895 phy.SetChannel(channel.Create());
2896
2897 WifiHelper wifi;
2898 wifi.SetStandard(WIFI_STANDARD_80211ac);
2899 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
2900
2901 WifiMacHelper mac;
2902 NetDeviceContainer apDevice;
2903 mac.SetType("ns3::ApWifiMac");
2904 apDevice = wifi.Install(phy, mac, wifiApNode);
2905
2906 NetDeviceContainer staDevice;
2907 mac.SetType("ns3::StaWifiMac");
2908 staDevice = wifi.Install(phy, mac, wifiStaNode);
2909
2910 // Assign fixed streams to random variables in use
2911 wifi.AssignStreams(apDevice, streamNumber);
2912 wifi.AssignStreams(staDevice, streamNumber);
2913
2914 MobilityHelper mobility;
2915 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
2916 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2917 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
2918 mobility.SetPositionAllocator(positionAlloc);
2919
2920 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2921 mobility.Install(wifiApNode);
2922 mobility.Install(wifiStaNode);
2923
2924 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
2926
2927 // Send best-effort packet (i.e. priority 0)
2930 this,
2931 1,
2932 apDevice.Get(0),
2933 staDevice.Get(0)->GetAddress(),
2934 0);
2935
2936 // Send non best-effort (voice) packet (i.e. priority 6)
2939 this,
2940 1,
2941 apDevice.Get(0),
2942 staDevice.Get(0)->GetAddress(),
2943 6);
2944
2947
2949}
2950
2951//-----------------------------------------------------------------------------
2952/**
2953 * Make sure that Ideal rate manager properly selects MCS based on the configured channel width.
2954 *
2955 * The scenario considers an access point and a fixed station.
2956 * The access point first sends a 80 MHz PPDU to the station,
2957 * for which Ideal rate manager should select VH-MCS 0 based
2958 * on the distance (no interference generated in this test). Then,
2959 * the access point sends a 20 MHz PPDU to the station,
2960 * which corresponds to a SNR 6 dB higher than previously, hence
2961 * VHT-MCS 2 should be selected. Finally, the access point sends a
2962 * 40 MHz PPDU to the station, which means corresponds to a SNR 3 dB
2963 * lower than previously, hence VHT-MCS 1 should be selected.
2964 */
2965
2967{
2968 public:
2971 void DoRun() override;
2972
2973 private:
2974 /**
2975 * Change the configured channel width for all nodes
2976 * \param channelWidth the channel width (in MHz)
2977 */
2978 void ChangeChannelWidth(uint16_t channelWidth);
2979
2980 /**
2981 * Triggers the transmission of a 1000 Byte-long data packet from the source device
2982 * \param sourceDevice pointer to the source NetDevice
2983 * \param destination address of the destination device
2984 */
2985 void SendPacket(Ptr<NetDevice> sourceDevice, Address& destination);
2986
2987 /**
2988 * Callback that indicates a PSDU is being transmitted
2989 * \param context the context
2990 * \param psduMap the PSDU map to transmit
2991 * \param txVector the TX vector
2992 * \param txPowerW the TX power (W)
2993 */
2994 void TxCallback(std::string context,
2995 WifiConstPsduMap psduMap,
2996 WifiTxVector txVector,
2997 double txPowerW);
2998
2999 /**
3000 * Check if the selected WifiMode is correct
3001 * \param expectedMode the expected WifiMode
3002 */
3003 void CheckLastSelectedMode(WifiMode expectedMode);
3004
3005 WifiMode m_txMode; ///< Store the last selected mode to send data packet
3006};
3007
3009 : TestCase("Test case for use of channel bonding with Ideal rate manager")
3010{
3011}
3012
3014{
3015}
3016
3017void
3019{
3020 Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelSettings",
3021 StringValue("{0, " + std::to_string(channelWidth) + ", BAND_5GHZ, 0}"));
3022}
3023
3024void
3026{
3027 Ptr<Packet> packet = Create<Packet>(1000);
3028 sourceDevice->Send(packet, destination, 0);
3029}
3030
3031void
3033 WifiConstPsduMap psduMap,
3034 WifiTxVector txVector,
3035 double txPowerW)
3036{
3037 if (psduMap.begin()->second->GetSize() >= 1000)
3038 {
3039 m_txMode = txVector.GetMode();
3040 }
3041}
3042
3043void
3045{
3047 expectedMode,
3048 "Last selected WifiMode "
3049 << m_txMode << " does not match expected WifiMode " << expectedMode);
3050}
3051
3052void
3054{
3057 int64_t streamNumber = 100;
3058
3059 NodeContainer wifiApNode;
3060 NodeContainer wifiStaNode;
3061 wifiApNode.Create(1);
3062 wifiStaNode.Create(1);
3063
3066 phy.SetChannel(channel.Create());
3067
3068 WifiHelper wifi;
3069 wifi.SetStandard(WIFI_STANDARD_80211ac);
3070 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
3071
3072 WifiMacHelper mac;
3073 NetDeviceContainer apDevice;
3074 mac.SetType("ns3::ApWifiMac");
3075 apDevice = wifi.Install(phy, mac, wifiApNode);
3076
3077 NetDeviceContainer staDevice;
3078 mac.SetType("ns3::StaWifiMac");
3079 staDevice = wifi.Install(phy, mac, wifiStaNode);
3080
3081 // Assign fixed streams to random variables in use
3082 wifi.AssignStreams(apDevice, streamNumber);
3083 wifi.AssignStreams(staDevice, streamNumber);
3084
3085 MobilityHelper mobility;
3086 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
3087 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
3088 positionAlloc->Add(Vector(50.0, 0.0, 0.0));
3089 mobility.SetPositionAllocator(positionAlloc);
3090
3091 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
3092 mobility.Install(wifiApNode);
3093 mobility.Install(wifiStaNode);
3094
3095 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
3097
3098 // Set channel width to 80 MHz & send packet
3101 this,
3102 80);
3105 this,
3106 apDevice.Get(0),
3107 staDevice.Get(0)->GetAddress());
3108 // Selected rate should be VHT-MCS 1
3111 this,
3113
3114 // Set channel width to 20 MHz & send packet
3117 this,
3118 20);
3121 this,
3122 apDevice.Get(0),
3123 staDevice.Get(0)->GetAddress());
3124 // Selected rate should be VHT-MCS 3 since SNR should be 6 dB higher than previously
3127 this,
3129
3130 // Set channel width to 40 MHz & send packet
3133 this,
3134 40);
3137 this,
3138 apDevice.Get(0),
3139 staDevice.Get(0)->GetAddress());
3140 // Selected rate should be VHT-MCS 2 since SNR should be 3 dB lower than previously
3143 this,
3145
3148
3150}
3151
3152//-----------------------------------------------------------------------------
3153/**
3154 * Test to validate that Ideal rate manager properly selects TXVECTOR in scenarios where MIMO is
3155 * used. The test consider both balanced and unbalanced MIMO settings, and verify ideal picks the
3156 * correct number of spatial streams and the correct MCS, taking into account potential diversity in
3157 * AWGN channels when the number of antenna at the receiver is higher than the number of spatial
3158 * streams used for the transmission.
3159 */
3160
3162{
3163 public:
3165 ~IdealRateManagerMimoTest() override;
3166 void DoRun() override;
3167
3168 private:
3169 /**
3170 * Change the configured MIMO settings for AP node
3171 * \param antennas the number of active antennas
3172 * \param maxStreams the maximum number of allowed spatial streams
3173 */
3174 void SetApMimoSettings(uint8_t antennas, uint8_t maxStreams);
3175 /**
3176 * Change the configured MIMO settings for STA node
3177 * \param antennas the number of active antennas
3178 * \param maxStreams the maximum number of allowed spatial streams
3179 */
3180 void SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams);
3181 /**
3182 * Triggers the transmission of a 1000 Byte-long data packet from the source device
3183 * \param sourceDevice pointer to the source NetDevice
3184 * \param destination address of the destination device
3185 */
3186 void SendPacket(Ptr<NetDevice> sourceDevice, Address& destination);
3187
3188 /**
3189 * Callback that indicates a PSDU is being transmitted
3190 * \param context the context
3191 * \param psdus the PSDU map to transmit
3192 * \param txVector the TX vector
3193 * \param txPowerW the TX power (W)
3194 */
3195 void TxCallback(std::string context,
3196 WifiConstPsduMap psdus,
3197 WifiTxVector txVector,
3198 double txPowerW);
3199
3200 /**
3201 * Check if the selected WifiMode is correct
3202 * \param expectedMode the expected WifiMode
3203 */
3204 void CheckLastSelectedMode(WifiMode expectedMode);
3205 /**
3206 * Check if the selected Nss is correct
3207 * \param expectedNss the expected Nss
3208 */
3209 void CheckLastSelectedNss(uint8_t expectedNss);
3210
3211 WifiTxVector m_txVector; ///< Store the last TXVECTOR used to transmit Data
3212};
3213
3215 : TestCase("Test case for use of imbalanced MIMO settings with Ideal rate manager")
3216{
3217}
3218
3220{
3221}
3222
3223void
3224IdealRateManagerMimoTest::SetApMimoSettings(uint8_t antennas, uint8_t maxStreams)
3225{
3226 Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/Antennas",
3227 UintegerValue(antennas));
3228 Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedTxSpatialStreams",
3229 UintegerValue(maxStreams));
3230 Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedRxSpatialStreams",
3231 UintegerValue(maxStreams));
3232}
3233
3234void
3235IdealRateManagerMimoTest::SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams)
3236{
3237 Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/Antennas",
3238 UintegerValue(antennas));
3239 Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedTxSpatialStreams",
3240 UintegerValue(maxStreams));
3241 Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedRxSpatialStreams",
3242 UintegerValue(maxStreams));
3243}
3244
3245void
3247{
3248 Ptr<Packet> packet = Create<Packet>(1000);
3249 sourceDevice->Send(packet, destination, 0);
3250}
3251
3252void
3254 WifiConstPsduMap psdus,
3255 WifiTxVector txVector,
3256 double txPowerW)
3257{
3258 if (psdus.begin()->second->GetSize() >= 1000)
3259 {
3260 m_txVector = txVector;
3261 }
3262}
3263
3264void
3266{
3268 expectedNss,
3269 "Last selected Nss " << m_txVector.GetNss()
3270 << " does not match expected Nss " << expectedNss);
3271}
3272
3273void
3275{
3277 expectedMode,
3278 "Last selected WifiMode " << m_txVector.GetMode()
3279 << " does not match expected WifiMode "
3280 << expectedMode);
3281}
3282
3283void
3285{
3288 int64_t streamNumber = 100;
3289
3290 NodeContainer wifiApNode;
3291 NodeContainer wifiStaNode;
3292 wifiApNode.Create(1);
3293 wifiStaNode.Create(1);
3294
3297 phy.SetChannel(channel.Create());
3298
3299 WifiHelper wifi;
3300 wifi.SetStandard(WIFI_STANDARD_80211ac);
3301 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
3302
3303 WifiMacHelper mac;
3304 NetDeviceContainer apDevice;
3305 mac.SetType("ns3::ApWifiMac");
3306 apDevice = wifi.Install(phy, mac, wifiApNode);
3307
3308 NetDeviceContainer staDevice;
3309 mac.SetType("ns3::StaWifiMac");
3310 staDevice = wifi.Install(phy, mac, wifiStaNode);
3311
3312 // Assign fixed streams to random variables in use
3313 wifi.AssignStreams(apDevice, streamNumber);
3314 wifi.AssignStreams(staDevice, streamNumber);
3315
3316 MobilityHelper mobility;
3317 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
3318 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
3319 positionAlloc->Add(Vector(40.0, 0.0, 0.0));
3320 mobility.SetPositionAllocator(positionAlloc);
3321
3322 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
3323 mobility.Install(wifiApNode);
3324 mobility.Install(wifiStaNode);
3325
3326 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
3328
3329 // TX: 1 antenna
3331 // RX: 1 antenna
3333 // Send packets (2 times to get one feedback)
3336 this,
3337 apDevice.Get(0),
3338 staDevice.Get(0)->GetAddress());
3341 this,
3342 apDevice.Get(0),
3343 staDevice.Get(0)->GetAddress());
3344 // Selected NSS should be 1 since both TX and RX support a single antenna
3346 // Selected rate should be VHT-MCS 2 because of settings and distance between TX and RX
3349 this,
3351
3352 // TX: 1 antenna
3354 // RX: 2 antennas, but only supports 1 spatial stream
3356 // Send packets (2 times to get one feedback)
3359 this,
3360 apDevice.Get(0),
3361 staDevice.Get(0)->GetAddress());
3364 this,
3365 apDevice.Get(0),
3366 staDevice.Get(0)->GetAddress());
3367 // Selected NSS should be 1 since both TX and RX support a single antenna
3369 // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3370 // improvement of about 3dB
3373 this,
3375
3376 // TX: 1 antenna
3378 // RX: 2 antennas, and supports 2 spatial streams
3380 // Send packets (2 times to get one feedback)
3383 this,
3384 apDevice.Get(0),
3385 staDevice.Get(0)->GetAddress());
3388 this,
3389 apDevice.Get(0),
3390 staDevice.Get(0)->GetAddress());
3391 // Selected NSS should be 1 since TX supports a single antenna
3393 // Selected rate should be as previously
3396 this,
3398
3399 // TX: 2 antennas, but only supports 1 spatial stream
3401 // RX: 1 antenna
3403 // Send packets (2 times to get one feedback)
3406 this,
3407 apDevice.Get(0),
3408 staDevice.Get(0)->GetAddress());
3411 this,
3412 apDevice.Get(0),
3413 staDevice.Get(0)->GetAddress());
3414 // Selected NSS should be 1 since both TX and RX support a single antenna
3416 // Selected rate should be VHT-MCS 2 because we do no longer have diversity in this scenario
3417 // (more antennas at TX does not result in SNR improvement in AWGN channel)
3420 this,
3422
3423 // TX: 2 antennas, but only supports 1 spatial stream
3425 // RX: 2 antennas, but only supports 1 spatial stream
3427 // Send packets (2 times to get one feedback)
3430 this,
3431 apDevice.Get(0),
3432 staDevice.Get(0)->GetAddress());
3435 this,
3436 apDevice.Get(0),
3437 staDevice.Get(0)->GetAddress());
3438 // Selected NSS should be 1 since both TX and RX support a single antenna
3440 // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3441 // improvement of about 3dB (more antennas at TX does not result in SNR improvement in AWGN
3442 // channel)
3445 this,
3447
3448 // TX: 2 antennas, but only supports 1 spatial stream
3450 // RX: 2 antennas, and supports 2 spatial streams
3452 // Send packets (2 times to get one feedback)
3455 this,
3456 apDevice.Get(0),
3457 staDevice.Get(0)->GetAddress());
3460 this,
3461 apDevice.Get(0),
3462 staDevice.Get(0)->GetAddress());
3463 // Selected NSS should be 1 since TX supports a single antenna
3465 // Selected rate should be as previously
3468 this,
3470
3471 // TX: 2 antennas, and supports 2 spatial streams
3473 // RX: 1 antenna
3475 // Send packets (2 times to get one feedback)
3478 this,
3479 apDevice.Get(0),
3480 staDevice.Get(0)->GetAddress());
3483 this,
3484 apDevice.Get(0),
3485 staDevice.Get(0)->GetAddress());
3486 // Selected NSS should be 1 since RX supports a single antenna
3488 // Selected rate should be VHT-MCS 2 because we do no longer have diversity in this scenario
3489 // (more antennas at TX does not result in SNR improvement in AWGN channel)
3492 this,
3494
3495 // TX: 2 antennas, and supports 2 spatial streams
3497 // RX: 2 antennas, but only supports 1 spatial stream
3499 // Send packets (2 times to get one feedback)
3502 this,
3503 apDevice.Get(0),
3504 staDevice.Get(0)->GetAddress());
3507 this,
3508 apDevice.Get(0),
3509 staDevice.Get(0)->GetAddress());
3510 // Selected NSS should be 1 since RX supports a single antenna
3512 // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3513 // improvement of about 3dB (more antennas at TX does not result in SNR improvement in AWGN
3514 // channel)
3517 this,
3519
3520 // TX: 2 antennas, and supports 2 spatial streams
3522 // RX: 2 antennas, and supports 2 spatial streams
3524 // Send packets (2 times to get one feedback)
3527 this,
3528 apDevice.Get(0),
3529 staDevice.Get(0)->GetAddress());
3532 this,
3533 apDevice.Get(0),
3534 staDevice.Get(0)->GetAddress());
3535 // Selected NSS should be 2 since both TX and RX support 2 antennas
3537 // Selected rate should be the same as without diversity, as it uses 2 spatial streams so there
3538 // is no more benefits from diversity in AWGN channels
3541 this,
3543
3544 // Verify we can go back to initial situation
3549 this,
3550 apDevice.Get(0),
3551 staDevice.Get(0)->GetAddress());
3555 this,
3557
3558 Simulator::Stop(Seconds(10.2));
3561}
3562
3563//-----------------------------------------------------------------------------
3564/**
3565 * \ingroup wifi-test
3566 * \ingroup tests
3567 *
3568 * \brief Data rate verification test for MCSs of different RU sizes
3569 */
3571{
3572 public:
3574
3575 private:
3576 /**
3577 * Compare the data rate computed for the provided combination with standard defined one.
3578 * \param ruType the RU type
3579 * \param mcs the modulation and coding scheme (as a string, e.g. HeMcs0)
3580 * \param nss the number of spatial streams
3581 * \param guardInterval the guard interval to use
3582 * \param expectedDataRate the expected data rate in 100 kbps units (minimum granularity in
3583 * standard tables)
3584 * \returns true if data rates are the same, false otherwise
3585 */
3586 bool CheckDataRate(HeRu::RuType ruType,
3587 std::string mcs,
3588 uint8_t nss,
3589 uint16_t guardInterval,
3590 uint16_t expectedDataRate);
3591 void DoRun() override;
3592};
3593
3595 : TestCase("Check data rates for different RU types.")
3596{
3597}
3598
3599bool
3601 std::string mcs,
3602 uint8_t nss,
3603 uint16_t guardInterval,
3604 uint16_t expectedDataRate)
3605{
3606 uint16_t approxWidth = HeRu::GetBandwidth(ruType);
3607 WifiMode mode(mcs);
3608 uint64_t dataRate = round(mode.GetDataRate(approxWidth, guardInterval, nss) / 100000.0);
3609 NS_ABORT_MSG_IF(dataRate > 65535, "Rate is way too high");
3610 if (static_cast<uint16_t>(dataRate) != expectedDataRate)
3611 {
3612 std::cerr << "RU=" << ruType << " mode=" << mode << " Nss=" << +nss
3613 << " guardInterval=" << guardInterval << " expected=" << expectedDataRate
3614 << " x100kbps"
3615 << " computed=" << static_cast<uint16_t>(dataRate) << " x100kbps" << std::endl;
3616 return false;
3617 }
3618 return true;
3619}
3620
3621void
3623{
3624 bool retval = true;
3625
3626 // 26-tone RU, browse over all MCSs, GIs and Nss's (up to 4, current max)
3627 retval = retval && CheckDataRate(HeRu::RU_26_TONE, "HeMcs0", 1, 800, 9) &&
3628 CheckDataRate(HeRu::RU_26_TONE, "HeMcs1", 1, 1600, 17) &&
3629 CheckDataRate(HeRu::RU_26_TONE, "HeMcs2", 1, 3200, 23) &&
3630 CheckDataRate(HeRu::RU_26_TONE, "HeMcs3", 1, 3200, 30) &&
3631 CheckDataRate(HeRu::RU_26_TONE, "HeMcs4", 2, 1600, 100) &&
3632 CheckDataRate(HeRu::RU_26_TONE, "HeMcs5", 3, 1600, 200) &&
3633 CheckDataRate(HeRu::RU_26_TONE, "HeMcs6", 4, 1600, 300) &&
3634 CheckDataRate(HeRu::RU_26_TONE, "HeMcs7", 4, 3200, 300) &&
3635 CheckDataRate(HeRu::RU_26_TONE, "HeMcs8", 4, 1600, 400) &&
3636 CheckDataRate(HeRu::RU_26_TONE, "HeMcs9", 4, 3200, 400) &&
3637 CheckDataRate(HeRu::RU_26_TONE, "HeMcs10", 4, 1600, 500) &&
3638 CheckDataRate(HeRu::RU_26_TONE, "HeMcs11", 4, 3200, 500);
3639
3641 retval,
3642 true,
3643 "26-tone RU data rate verification for different MCSs, GIs, and Nss's failed");
3644
3645 // Check other RU sizes
3646 retval = retval && CheckDataRate(HeRu::RU_52_TONE, "HeMcs2", 1, 1600, 50) &&
3647 CheckDataRate(HeRu::RU_106_TONE, "HeMcs9", 1, 800, 500) &&
3648 CheckDataRate(HeRu::RU_242_TONE, "HeMcs5", 1, 1600, 650) &&
3649 CheckDataRate(HeRu::RU_484_TONE, "HeMcs3", 1, 1600, 650) &&
3650 CheckDataRate(HeRu::RU_996_TONE, "HeMcs5", 1, 3200, 2450) &&
3651 CheckDataRate(HeRu::RU_2x996_TONE, "HeMcs3", 1, 3200, 2450);
3652
3653 NS_TEST_EXPECT_MSG_EQ(retval,
3654 true,
3655 "Data rate verification for RUs above 52-tone RU (included) failed");
3656}
3657
3658/// List of Information Elements included in the test management frame
3660 std::tuple<SupportedRates, std::optional<ExtendedSupportedRatesIE>, std::vector<Ssid>>;
3661
3662/**
3663 * \ingroup wifi-test
3664 * \ingroup tests
3665 *
3666 * \brief Test management header
3667 */
3668class MgtTestHeader : public WifiMgtHeader<MgtTestHeader, MgtTestElems>
3669{
3670 public:
3671 ~MgtTestHeader() override = default;
3672
3673 /**
3674 * Register this type.
3675 * \return The TypeId.
3676 */
3677 static TypeId GetTypeId();
3678
3679 /**
3680 * \return the TypeId for this object.
3681 */
3682 TypeId GetInstanceTypeId() const override;
3683
3684 using WifiMgtHeader<MgtTestHeader, MgtTestElems>::GetSerializedSize;
3685 using WifiMgtHeader<MgtTestHeader, MgtTestElems>::Serialize;
3686 using WifiMgtHeader<MgtTestHeader, MgtTestElems>::Deserialize;
3687};
3688
3689TypeId
3691{
3692 static TypeId tid = TypeId("ns3::MgtTestHeader")
3693 .SetParent<Header>()
3694 .SetGroupName("Wifi")
3695 .AddConstructor<MgtTestHeader>();
3696 return tid;
3697}
3698
3699TypeId
3701{
3702 return GetTypeId();
3703}
3704
3705/**
3706 * \ingroup wifi-test
3707 * \ingroup tests
3708 *
3709 * \brief Mgt header (de)serialization Test Suite
3710 */
3712{
3713 public:
3715 ~WifiMgtHeaderTest() override = default;
3716
3717 private:
3718 void DoRun() override;
3719};
3720
3722 : HeaderSerializationTestCase("Check (de)serialization of a test management header")
3723{
3724}
3725
3726void
3728{
3729 MgtTestHeader frame;
3730
3731 // Add the mandatory Information Element (SupportedRates)
3732 AllSupportedRates allRates;
3733 allRates.AddSupportedRate(1000000);
3734 allRates.AddSupportedRate(2000000);
3735 allRates.AddSupportedRate(3000000);
3736 allRates.AddSupportedRate(4000000);
3737 allRates.AddSupportedRate(5000000);
3738
3739 frame.Get<SupportedRates>() = allRates.rates;
3740 frame.Get<ExtendedSupportedRatesIE>() = allRates.extendedRates;
3741
3742 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3743 true,
3744 "Expected a SupportedRates IE to be included");
3745 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3746 false,
3747 "Expected no ExtendedSupportedRatesIE to be included");
3748 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 0, "Expected no Ssid IE to be included");
3749
3751
3752 // Add more rates, so that the optional Information Element (ExtendedSupportedRatesIE) is added
3753 allRates.AddSupportedRate(6000000);
3754 allRates.AddSupportedRate(7000000);
3755 allRates.AddSupportedRate(8000000);
3756 allRates.AddSupportedRate(9000000);
3757 allRates.AddSupportedRate(10000000);
3758
3759 frame.Get<SupportedRates>() = allRates.rates;
3760 frame.Get<ExtendedSupportedRatesIE>() = allRates.extendedRates;
3761
3762 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3763 true,
3764 "Expected a SupportedRates IE to be included");
3765 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3766 true,
3767 "Expected an ExtendedSupportedRatesIE to be included");
3768 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 0, "Expected no Ssid IE to be included");
3769
3771
3772 // Add a first Ssid IE
3773 Ssid one("Ssid One");
3774 frame.Get<Ssid>().push_back(one);
3775
3776 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3777 true,
3778 "Expected a SupportedRates IE to be included");
3779 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3780 true,
3781 "Expected an ExtendedSupportedRatesIE to be included");
3782 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 1, "Expected one Ssid IE to be included");
3783 NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().front().PeekString()),
3784 "Ssid One",
3785 "Incorrect SSID");
3786
3788
3789 // Add a second Ssid IE
3790 frame.Get<Ssid>().emplace_back("Ssid Two");
3791
3792 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3793 true,
3794 "Expected a SupportedRates IE to be included");
3795 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3796 true,
3797 "Expected an ExtendedSupportedRatesIE to be included");
3798 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 2, "Expected two Ssid IEs to be included");
3799 NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().front().PeekString()),
3800 "Ssid One",
3801 "Incorrect first SSID");
3802 NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().back().PeekString()),
3803 "Ssid Two",
3804 "Incorrect second SSID");
3805
3807}
3808
3809/**
3810 * \ingroup wifi-test
3811 * \ingroup tests
3812 *
3813 * \brief Wifi Test Suite
3814 */
3816{
3817 public:
3818 WifiTestSuite();
3819};
3820
3822 : TestSuite("wifi-devices", Type::UNIT)
3823{
3824 AddTestCase(new WifiTest, TestCase::Duration::QUICK);
3825 AddTestCase(new QosUtilsIsOldPacketTest, TestCase::Duration::QUICK);
3826 AddTestCase(new InterferenceHelperSequenceTest, TestCase::Duration::QUICK); // Bug 991
3827 AddTestCase(new DcfImmediateAccessBroadcastTestCase, TestCase::Duration::QUICK);
3828 AddTestCase(new Bug730TestCase, TestCase::Duration::QUICK); // Bug 730
3829 AddTestCase(new QosFragmentationTestCase, TestCase::Duration::QUICK);
3830 AddTestCase(new SetChannelFrequencyTest, TestCase::Duration::QUICK);
3831 AddTestCase(new Bug2222TestCase, TestCase::Duration::QUICK); // Bug 2222
3832 AddTestCase(new Bug2843TestCase, TestCase::Duration::QUICK); // Bug 2843
3833 AddTestCase(new Bug2831TestCase, TestCase::Duration::QUICK); // Bug 2831
3834 AddTestCase(new StaWifiMacScanningTestCase, TestCase::Duration::QUICK); // Bug 2399
3835 AddTestCase(new Bug2470TestCase, TestCase::Duration::QUICK); // Bug 2470
3836 AddTestCase(new Issue40TestCase, TestCase::Duration::QUICK); // Issue #40
3837 AddTestCase(new Issue169TestCase, TestCase::Duration::QUICK); // Issue #169
3838 AddTestCase(new IdealRateManagerChannelWidthTest, TestCase::Duration::QUICK);
3839 AddTestCase(new IdealRateManagerMimoTest, TestCase::Duration::QUICK);
3840 AddTestCase(new HeRuMcsDataRateTestCase, TestCase::Duration::QUICK);
3841 AddTestCase(new WifiMgtHeaderTest, TestCase::Duration::QUICK);
3842}
3843
3844static WifiTestSuite g_wifiTestSuite; ///< the test suite
Make sure that when virtual collision occurs the wifi remote station manager is triggered and the ret...
Definition: wifi-test.cc:1385
~Bug2222TestCase() override
Definition: wifi-test.cc:1409
uint32_t m_countInternalCollisions
count internal collisions
Definition: wifi-test.cc:1393
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:1421
void TxDataFailedTrace(std::string context, Mac48Address adr)
Transmit data failed function.
Definition: wifi-test.cc:1414
Make sure that the ADDBA handshake process is protected.
Definition: wifi-test.cc:2172
void RxErrorCallback(std::string context, Ptr< const Packet > p, double snr)
Callback when packet is dropped.
Definition: wifi-test.cc:2347
void RunSubtest(TypeOfStation rcvErrorType)
Run subtest for this test suite.
Definition: wifi-test.cc:2371
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:2476
uint16_t m_addbaResetCount
Count number of times ADDBA state machine is in reset state.
Definition: wifi-test.cc:2255
uint16_t m_addbaRejectedCount
Count number of times ADDBA state machine is in rejected state.
Definition: wifi-test.cc:2252
void AddbaStateChangedCallback(std::string context, Time t, Mac48Address recipient, uint8_t tid, OriginatorBlockAckAgreement::State state)
Callback when ADDBA state changed.
Definition: wifi-test.cc:2276
uint16_t m_failedActionCount
Count failed ADDBA request/response.
Definition: wifi-test.cc:2247
void TxCallback(Ptr< ListErrorModel > rxErrorModel, std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback when a frame is transmitted.
Definition: wifi-test.cc:2303
uint16_t m_addbaEstablishedCount
Count number of times ADDBA state machine is in established state.
Definition: wifi-test.cc:2248
void RxCallback(std::string context, Ptr< const Packet > p, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise, uint16_t staId)
Callback when packet is received.
Definition: wifi-test.cc:2322
~Bug2470TestCase() override
Definition: wifi-test.cc:2271
uint16_t m_receivedNormalMpduCount
Count received normal MPDU packets on STA.
Definition: wifi-test.cc:2245
uint16_t m_addbaNoReplyCount
Count number of times ADDBA state machine is in no_reply state.
Definition: wifi-test.cc:2254
uint16_t m_addbaPendingCount
Count number of times ADDBA state machine is in pending state.
Definition: wifi-test.cc:2250
void SendPacketBurst(uint32_t numPackets, Ptr< NetDevice > sourceDevice, Address &destination) const
Triggers the arrival of a burst of 1000 Byte-long packets in the source device.
Definition: wifi-test.cc:2359
uint16_t m_receivedAmpduCount
Count received A-MPDU packets on STA.
Definition: wifi-test.cc:2246
Make sure that the channel width and the channel number can be changed at runtime.
Definition: wifi-test.cc:1741
uint16_t m_countOperationalChannelWidth20
count number of beacon frames announcing a 20 MHz operating channel width
Definition: wifi-test.cc:1765
void ChangeSupportedChannelWidth()
Function called to change the supported channel width at runtime.
Definition: wifi-test.cc:1785
uint16_t m_countOperationalChannelWidth40
count number of beacon frames announcing a 40 MHz operating channel width
Definition: wifi-test.cc:1767
void RxCallback(std::string context, Ptr< const Packet > p, RxPowerWattPerChannelBand rxPowersW)
Callback triggered when a packet is received by the PHYs.
Definition: wifi-test.cc:1792
uint16_t m_assocReqCount
count number of association requests
Definition: wifi-test.cc:1763
Ptr< YansWifiPhy > m_apPhy
AP PHY.
Definition: wifi-test.cc:1760
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:1824
Ptr< YansWifiPhy > m_staPhy
STA PHY.
Definition: wifi-test.cc:1761
uint16_t m_assocRespCount
count number of association responses
Definition: wifi-test.cc:1764
~Bug2831TestCase() override
Definition: wifi-test.cc:1780
Make sure that the correct channel width and center frequency have been set for OFDM basic rate trans...
Definition: wifi-test.cc:1525
void SendPacketBurst(uint8_t numPackets, Ptr< NetDevice > sourceDevice, Address &destination) const
Triggers the arrival of a burst of 1000 Byte-long packets in the source device.
Definition: wifi-test.cc:1607
void StoreDistinctTuple(std::string context, Ptr< SpectrumSignalParameters > txParams)
Stores the distinct {starting frequency, channelWidth, Number of subbands in SpectrumModel,...
Definition: wifi-test.cc:1573
std::vector< FreqWidthSubbandModulationTuple > m_distinctTuples
vector of distinct {starting frequency, channelWidth, Number of subbands in SpectrumModel,...
Definition: wifi-test.cc:1539
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:1619
uint16_t m_channelWidth
channel width (in MHz)
Definition: wifi-test.cc:1559
~Bug2843TestCase() override
Definition: wifi-test.cc:1568
std::tuple< double, uint16_t, uint32_t, WifiModulationClass > FreqWidthSubbandModulationTuple
A tuple of {starting frequency, channelWidth, Number of subbands in SpectrumModel,...
Definition: wifi-test.cc:1537
Make sure that when changing the fragmentation threshold during the simulation, the TCP transmission ...
Definition: wifi-test.cc:656
~Bug730TestCase() override
Definition: wifi-test.cc:681
void Receive(std::string context, Ptr< const Packet > p, const Address &adr)
Receive function.
Definition: wifi-test.cc:686
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:695
uint32_t m_received
received
Definition: wifi-test.cc:664
Make sure that when multiple broadcast packets are queued on the same device in a short succession,...
Definition: wifi-test.cc:484
void NotifyPhyTxBegin(Ptr< const Packet > p, double txPowerW)
Notify Phy transmit begin.
Definition: wifi-test.cc:519
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:540
ObjectFactory m_propDelay
propagation delay
Definition: wifi-test.cc:499
unsigned int m_numSentPackets
number of sent packets
Definition: wifi-test.cc:503
Time m_secondTransmissionTime
second transmission time
Definition: wifi-test.cc:502
Time m_firstTransmissionTime
first transmission time
Definition: wifi-test.cc:501
ObjectFactory m_manager
manager
Definition: wifi-test.cc:497
void SendOnePacket(Ptr< WifiNetDevice > dev)
Send one packet function.
Definition: wifi-test.cc:533
Data rate verification test for MCSs of different RU sizes.
Definition: wifi-test.cc:3571
bool CheckDataRate(HeRu::RuType ruType, std::string mcs, uint8_t nss, uint16_t guardInterval, uint16_t expectedDataRate)
Compare the data rate computed for the provided combination with standard defined one.
Definition: wifi-test.cc:3600
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:3622
Make sure that Ideal rate manager properly selects MCS based on the configured channel width.
Definition: wifi-test.cc:2967
WifiMode m_txMode
Store the last selected mode to send data packet.
Definition: wifi-test.cc:3005
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:3053
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
Triggers the transmission of a 1000 Byte-long data packet from the source device.
Definition: wifi-test.cc:3025
void CheckLastSelectedMode(WifiMode expectedMode)
Check if the selected WifiMode is correct.
Definition: wifi-test.cc:3044
void TxCallback(std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback that indicates a PSDU is being transmitted.
Definition: wifi-test.cc:3032
void ChangeChannelWidth(uint16_t channelWidth)
Change the configured channel width for all nodes.
Definition: wifi-test.cc:3018
~IdealRateManagerChannelWidthTest() override
Definition: wifi-test.cc:3013
Test to validate that Ideal rate manager properly selects TXVECTOR in scenarios where MIMO is used.
Definition: wifi-test.cc:3162
~IdealRateManagerMimoTest() override
Definition: wifi-test.cc:3219
void CheckLastSelectedNss(uint8_t expectedNss)
Check if the selected Nss is correct.
Definition: wifi-test.cc:3265
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:3284
void TxCallback(std::string context, WifiConstPsduMap psdus, WifiTxVector txVector, double txPowerW)
Callback that indicates a PSDU is being transmitted.
Definition: wifi-test.cc:3253
void SetApMimoSettings(uint8_t antennas, uint8_t maxStreams)
Change the configured MIMO settings for AP node.
Definition: wifi-test.cc:3224
WifiTxVector m_txVector
Store the last TXVECTOR used to transmit Data.
Definition: wifi-test.cc:3211
void SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams)
Change the configured MIMO settings for STA node.
Definition: wifi-test.cc:3235
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
Triggers the transmission of a 1000 Byte-long data packet from the source device.
Definition: wifi-test.cc:3246
void CheckLastSelectedMode(WifiMode expectedMode)
Check if the selected WifiMode is correct.
Definition: wifi-test.cc:3274
void SwitchCh(Ptr< WifiNetDevice > dev)
Switch channel function.
Definition: wifi-test.cc:332
void SendOnePacket(Ptr< WifiNetDevice > dev)
Send one packet function.
Definition: wifi-test.cc:325
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:384
ObjectFactory m_manager
manager
Definition: wifi-test.cc:314
ObjectFactory m_propDelay
propagation delay
Definition: wifi-test.cc:316
Ptr< Node > CreateOne(Vector pos, Ptr< YansWifiChannel > channel)
Create one function.
Definition: wifi-test.cc:339
Make sure that Ideal rate manager is able to handle non best-effort traffic.
Definition: wifi-test.cc:2810
void SendPackets(uint8_t numPackets, Ptr< NetDevice > sourceDevice, Address &destination, uint8_t priority)
Triggers the transmission of a 1000 Byte-long data packet from the source device.
Definition: wifi-test.cc:2852
~Issue169TestCase() override
Definition: wifi-test.cc:2847
void TxCallback(std::string context, WifiConstPsduMap psdus, WifiTxVector txVector, double txPowerW)
Callback that indicates a PSDU is being transmitted.
Definition: wifi-test.cc:2868
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:2882
Make sure that Ideal rate manager recovers when the station is moving away from the access point.
Definition: wifi-test.cc:2578
uint16_t m_txCount
Count number of transmitted data packets.
Definition: wifi-test.cc:2612
uint16_t m_txMacFinalDataFailedCount
Count number of unsuccessfuly transmitted data packets.
Definition: wifi-test.cc:2614
void RunOne(bool useAmpdu)
Run one function.
Definition: wifi-test.cc:2653
uint16_t m_rxCount
Count number of successfully received data packets.
Definition: wifi-test.cc:2611
void RxSuccessCallback(std::string context, Ptr< const Packet > p)
Callback when packet is successfully received.
Definition: wifi-test.cc:2630
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:2787
void TxFinalDataFailedCallback(std::string context, Mac48Address address)
Transmit final data failed function.
Definition: wifi-test.cc:2647
void SendPackets(uint8_t numPackets, Ptr< NetDevice > sourceDevice, Address &destination)
Triggers the arrival of 1000 Byte-long packets in the source device.
Definition: wifi-test.cc:2636
~Issue40TestCase() override
Definition: wifi-test.cc:2625
Test management header.
Definition: wifi-test.cc:3669
static TypeId GetTypeId()
Register this type.
Definition: wifi-test.cc:3690
~MgtTestHeader() override=default
TypeId GetInstanceTypeId() const override
Definition: wifi-test.cc:3700
Make sure that fragmentation works with QoS stations.
Definition: wifi-test.cc:795
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:856
uint32_t m_received
received packets
Definition: wifi-test.cc:803
~QosFragmentationTestCase() override
Definition: wifi-test.cc:830
uint32_t m_fragments
transmitted fragments
Definition: wifi-test.cc:804
void Transmit(std::string context, Ptr< const Packet > p, double power)
Callback invoked when PHY transmits a packet.
Definition: wifi-test.cc:844
void Receive(std::string context, Ptr< const Packet > p, const Address &adr)
Receive function.
Definition: wifi-test.cc:835
Qos Utils Is Old Packet Test.
Definition: wifi-test.cc:247
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:254
Set Channel Frequency Test.
Definition: wifi-test.cc:951
Ptr< YansWifiPhy > GetYansWifiPhyPtr(const NetDeviceContainer &nc) const
Get yans wifi phy function.
Definition: wifi-test.cc:972
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:980
Make sure that Wifi STA is correctly associating to the best AP (i.e., nearest from STA).
Definition: wifi-test.cc:1969
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:2093
void TurnBeaconGenerationOn(Ptr< Node > apNode)
Turn beacon generation on the AP node.
Definition: wifi-test.cc:2019
Mac48Address m_associatedApBssid
Associated AP's bssid.
Definition: wifi-test.cc:2000
~StaWifiMacScanningTestCase() override
Definition: wifi-test.cc:2008
void TurnApOff(Ptr< Node > apNode)
Turn the AP node off.
Definition: wifi-test.cc:2027
NodeContainer Setup(bool nearestApBeaconGeneration, bool staActiveProbe)
Setup test.
Definition: wifi-test.cc:2035
void AssocCallback(std::string context, Mac48Address bssid)
Callback function on STA assoc event.
Definition: wifi-test.cc:2013
Mgt header (de)serialization Test Suite.
Definition: wifi-test.cc:3712
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:3727
~WifiMgtHeaderTest() override=default
Wifi Test.
Definition: wifi-test.cc:104
void CreateOne(Vector pos, Ptr< YansWifiChannel > channel)
Create one function.
Definition: wifi-test.cc:143
void RunOne()
Run one function.
Definition: wifi-test.cc:191
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:210
ObjectFactory m_mac
MAC.
Definition: wifi-test.cc:126
void SendOnePacket(Ptr< WifiNetDevice > dev)
Send one packet function.
Definition: wifi-test.cc:136
ObjectFactory m_manager
manager
Definition: wifi-test.cc:125
ObjectFactory m_propDelay
propagation delay
Definition: wifi-test.cc:127
Wifi Test Suite.
Definition: wifi-test.cc:3816
a polymophic address class
Definition: address.h:101
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
The Extended Supported Rates Information Element.
static uint16_t GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
Definition: he-ru.cc:767
RuType
The different HE Resource Unit (RU) types.
Definition: he-ru.h:41
@ RU_26_TONE
Definition: he-ru.h:42
@ RU_484_TONE
Definition: he-ru.h:46
@ RU_996_TONE
Definition: he-ru.h:47
@ RU_106_TONE
Definition: he-ru.h:44
@ RU_52_TONE
Definition: he-ru.h:43
@ RU_242_TONE
Definition: he-ru.h:45
@ RU_2x996_TONE
Definition: he-ru.h:48
Protocol header serialization and deserialization.
Definition: header.h:44
Subclass of TestCase class adding the ability to test the serialization and deserialization of a Head...
void TestHeaderSerialization(const T &hdr, Args &&... args)
Serialize the given header in a buffer, then create a new header by deserializing from the buffer and...
The HT Operation Information Element.
Definition: ht-operation.h:51
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address Allocate()
Allocate a new Mac48Address.
Implement the header for management frames of type beacon.
Definition: mgt-headers.h:517
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
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
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:149
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.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:522
State
Represents the state for this agreement.
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.
AttributeValue implementation for Pointer.
Definition: pointer.h:48
Ptr< T > Get() const
Definition: pointer.h:234
calculate a propagation delay.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Handle packet fragmentation and retransmissions for QoS data frames as well as MSDU aggregation (A-MS...
Definition: qos-txop.h:74
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
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 Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
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
indicates whether the socket has a priority set.
Definition: socket.h:1318
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition: socket.cc:854
Make it easy to create and manage PHY objects for the spectrum model.
void SetChannel(const Ptr< SpectrumChannel > channel)
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
char * PeekString() const
Peek the SSID.
Definition: ssid.cc:78
Hold variables of type string.
Definition: string.h:56
The Supported Rates Information Element.
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:302
A suite of tests to run.
Definition: test.h:1273
Type
Type of test.
Definition: test.h:1280
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
Handle packet fragmentation and retransmissions for data and management frames.
Definition: txop.h:82
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Hold an unsigned integer type.
Definition: uinteger.h:45
static WifiMode GetVhtMcs3()
Return MCS 3 from VHT MCS values.
static WifiMode GetVhtMcs1()
Return MCS 1 from VHT MCS values.
static WifiMode GetVhtMcs2()
Return MCS 2 from VHT MCS values.
a (time, location) pair.
Definition: waypoint.h:36
helps to create WifiNetDevice objects
Definition: wifi-helper.h:324
Implements the IEEE 802.11 MAC header.
bool IsAssocReq() const
Return true if the header is an Association Request header.
bool IsBeacon() const
Return true if the header is a Beacon header.
bool IsAssocResp() const
Return true if the header is an Association Response header.
bool IsAction() const
Return true if the header is an Action header.
bool IsData() const
Return true if the Type is DATA.
bool IsQosData() const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
create MAC layers for a ns3::WifiNetDevice.
void SetType(std::string type, Args &&... args)
base class for all MAC-level wifi objects.
Definition: wifi-mac.h:99
void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-mac.cc:472
Implement the header for management frames.
represent a single transmission mode
Definition: wifi-mode.h:51
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:185
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:122
Hold together all Wifi-related objects.
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:163
void SetErrorRateModel(std::string type, Args &&... args)
Helper function used to set the error rate model.
Definition: wifi-helper.h:551
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition: wifi-phy.cc:671
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:993
void SetOperatingChannel(const ChannelTuple &channelTuple)
If the standard for this object has not been set yet, store the given channel settings.
Definition: wifi-phy.cc:1130
virtual void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:625
std::tuple< uint8_t, uint16_t, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:926
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:637
hold a list of per-remote-station state.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode.
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
uint16_t GetChannelWidth() const
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.
802.11 PHY layer model
Definition: yans-wifi-phy.h:48
void SetChannel(const Ptr< YansWifiChannel > channel)
Set the YansWifiChannel this YansWifiPhy is to be connected to.
void SetInterferenceHelper(const Ptr< InterferenceHelper > helper) override
Sets the interference helper.
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:978
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:880
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#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_LT_OR_EQ(actual, limit, msg)
Test that an actual value is less than or equal to a limit and report if not.
Definition: test.h:831
#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
TypeOfStation
Enumeration for type of WiFi station.
Definition: wifi-mac.h:67
bool QosUtilsIsOldPacket(uint16_t startingSeq, uint16_t seqNumber)
This function checks if packet with sequence number seqNumber is an "old" packet.
Definition: qos-utils.cc:182
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
@ STA
Definition: wifi-mac.h:68
@ AP
Definition: wifi-mac.h:69
@ WIFI_STANDARD_80211a
@ WIFI_STANDARD_80211p
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211g
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ WIFI_STANDARD_80211b
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< void, Ptr< const WifiPsdu > > RxErrorCallback
Callback if PSDU unsuccessfuly received.
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:700
@ WIFI_MAC_MGT_ACTION
std::map< WifiSpectrumBandInfo, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:77
Struct containing all supported rates.
SupportedRates rates
supported rates
std::optional< ExtendedSupportedRatesIE > extendedRates
supported extended rates
void AddSupportedRate(uint64_t bs)
Add the given rate to the supported rates.
MpduInfo structure.
Definition: phy-entity.h:62
MpduType type
type of MPDU
Definition: phy-entity.h:63
SignalNoiseDbm structure.
Definition: phy-entity.h:55
static void AssignWifiRandomStreams(Ptr< WifiMac > mac, int64_t stream)
Definition: wifi-test.cc:67
static WifiTestSuite g_wifiTestSuite
the test suite
Definition: wifi-test.cc:3844
std::tuple< SupportedRates, std::optional< ExtendedSupportedRatesIE >, std::vector< Ssid > > MgtTestElems
List of Information Elements included in the test management frame.
Definition: wifi-test.cc:3660