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 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
8 * Quincy Tse <quincy.tse@nicta.com.au>
9 * Sébastien Deronne <sebastien.deronne@gmail.com>
10 */
11
12#include "ns3/adhoc-wifi-mac.h"
13#include "ns3/ap-wifi-mac.h"
14#include "ns3/config.h"
15#include "ns3/constant-position-mobility-model.h"
16#include "ns3/constant-rate-wifi-manager.h"
17#include "ns3/error-model.h"
18#include "ns3/fcfs-wifi-queue-scheduler.h"
19#include "ns3/he-frame-exchange-manager.h"
20#include "ns3/he-phy.h"
21#include "ns3/header-serialization-test.h"
22#include "ns3/ht-configuration.h"
23#include "ns3/interference-helper.h"
24#include "ns3/mgt-headers.h"
25#include "ns3/mobility-helper.h"
26#include "ns3/multi-model-spectrum-channel.h"
27#include "ns3/packet-socket-client.h"
28#include "ns3/packet-socket-helper.h"
29#include "ns3/packet-socket-server.h"
30#include "ns3/pointer.h"
31#include "ns3/propagation-loss-model.h"
32#include "ns3/rng-seed-manager.h"
33#include "ns3/socket.h"
34#include "ns3/spectrum-wifi-helper.h"
35#include "ns3/string.h"
36#include "ns3/test.h"
37#include "ns3/uinteger.h"
38#include "ns3/waypoint-mobility-model.h"
39#include "ns3/wifi-default-ack-manager.h"
40#include "ns3/wifi-default-assoc-manager.h"
41#include "ns3/wifi-default-protection-manager.h"
42#include "ns3/wifi-mgt-header.h"
43#include "ns3/wifi-net-device.h"
44#include "ns3/wifi-ppdu.h"
45#include "ns3/wifi-psdu.h"
46#include "ns3/wifi-spectrum-signal-parameters.h"
47#include "ns3/yans-error-rate-model.h"
48#include "ns3/yans-wifi-helper.h"
49#include "ns3/yans-wifi-phy.h"
50
51#include <optional>
52
53using namespace ns3;
54
55// Helper function to assign streams to random variables, to control
56// randomness in the tests
57static void
59{
60 int64_t currentStream = stream;
61 PointerValue ptr;
62 if (!mac->GetQosSupported())
63 {
64 mac->GetAttribute("Txop", ptr);
65 Ptr<Txop> txop = ptr.Get<Txop>();
66 currentStream += txop->AssignStreams(currentStream);
67 }
68 else
69 {
70 mac->GetAttribute("VO_Txop", ptr);
71 Ptr<QosTxop> vo_txop = ptr.Get<QosTxop>();
72 currentStream += vo_txop->AssignStreams(currentStream);
73
74 mac->GetAttribute("VI_Txop", ptr);
75 Ptr<QosTxop> vi_txop = ptr.Get<QosTxop>();
76 currentStream += vi_txop->AssignStreams(currentStream);
77
78 mac->GetAttribute("BE_Txop", ptr);
79 Ptr<QosTxop> be_txop = ptr.Get<QosTxop>();
80 currentStream += be_txop->AssignStreams(currentStream);
81
82 mac->GetAttribute("BK_Txop", ptr);
83 Ptr<QosTxop> bk_txop = ptr.Get<QosTxop>();
84 bk_txop->AssignStreams(currentStream);
85 }
86}
87
88/**
89 * \ingroup wifi-test
90 * \ingroup tests
91 *
92 * \brief Wifi Test
93 */
94class WifiTest : public TestCase
95{
96 public:
97 WifiTest();
98
99 void DoRun() override;
100
101 private:
102 /// Run one function
103 void RunOne();
104 /**
105 * Create one function
106 * \param pos the position
107 * \param channel the wifi channel
108 */
109 void CreateOne(Vector pos, Ptr<YansWifiChannel> channel);
110 /**
111 * Send one packet function
112 * \param dev the device
113 */
115
118 ObjectFactory m_propDelay; ///< propagation delay
119};
120
122 : TestCase("Wifi")
123{
124}
125
126void
128{
130 dev->Send(p, dev->GetBroadcast(), 1);
131}
132
133void
135{
138 node->AddDevice(dev);
139
141 auto phy = CreateObject<YansWifiPhy>();
143 phy->SetInterferenceHelper(interferenceHelper);
145 phy->SetErrorRateModel(error);
146 phy->SetChannel(channel);
147 phy->SetDevice(dev);
148 phy->ConfigureStandard(WIFI_STANDARD_80211a);
149 dev->SetPhy(phy);
150 auto manager = m_manager.Create<WifiRemoteStationManager>();
151 dev->SetRemoteStationManager(manager);
152
153 auto txop = CreateObjectWithAttributes<Txop>("AcIndex", StringValue("AC_BE_NQOS"));
154 m_mac.Set("Txop", PointerValue(txop));
155 auto mac = m_mac.Create<WifiMac>();
156 mac->SetDevice(dev);
157 mac->SetAddress(Mac48Address::Allocate());
158 dev->SetMac(mac);
159 mac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
160 mac->SetFrameExchangeManagers({CreateObject<FrameExchangeManager>()});
161 if (mac->GetTypeOfStation() == STA)
162 {
164 }
165 mac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
166 Ptr<FrameExchangeManager> fem = mac->GetFrameExchangeManager();
167 fem->SetAddress(mac->GetAddress());
169 protectionManager->SetWifiMac(mac);
170 fem->SetProtectionManager(protectionManager);
172 ackManager->SetWifiMac(mac);
173 fem->SetAckManager(ackManager);
174
175 mobility->SetPosition(pos);
176 node->AggregateObject(mobility);
177
179}
180
181void
183{
187 channel->SetPropagationDelayModel(propDelay);
188 channel->SetPropagationLossModel(propLoss);
189
190 CreateOne(Vector(0.0, 0.0, 0.0), channel);
191 CreateOne(Vector(5.0, 0.0, 0.0), channel);
192 CreateOne(Vector(5.0, 0.0, 0.0), channel);
193
195
198}
199
200void
202{
203 m_mac.SetTypeId("ns3::AdhocWifiMac");
204 m_propDelay.SetTypeId("ns3::ConstantSpeedPropagationDelayModel");
205
206 m_manager.SetTypeId("ns3::ArfWifiManager");
207 RunOne();
208 m_manager.SetTypeId("ns3::AarfWifiManager");
209 RunOne();
210 m_manager.SetTypeId("ns3::ConstantRateWifiManager");
211 RunOne();
212 m_manager.SetTypeId("ns3::OnoeWifiManager");
213 RunOne();
214 m_manager.SetTypeId("ns3::AmrrWifiManager");
215 RunOne();
216 m_manager.SetTypeId("ns3::IdealWifiManager");
217 RunOne();
218
219 m_mac.SetTypeId("ns3::AdhocWifiMac");
220 RunOne();
221 m_mac.SetTypeId("ns3::ApWifiMac");
222 RunOne();
223 m_mac.SetTypeId("ns3::StaWifiMac");
224 RunOne();
225
226 m_propDelay.SetTypeId("ns3::RandomPropagationDelayModel");
227 m_mac.SetTypeId("ns3::AdhocWifiMac");
228 RunOne();
229}
230
231/**
232 * \ingroup wifi-test
233 * \ingroup tests
234 *
235 * \brief Qos Utils Is Old Packet Test
236 */
238{
239 public:
241 : TestCase("QosUtilsIsOldPacket")
242 {
243 }
244
245 void DoRun() override
246 {
247 // startingSeq=0, seqNum=2047
249 false,
250 "2047 is new in comparison to 0");
251 // startingSeq=0, seqNum=2048
252 NS_TEST_EXPECT_MSG_EQ(QosUtilsIsOldPacket(0, 2048), true, "2048 is old in comparison to 0");
253 // startingSeq=2048, seqNum=0
254 NS_TEST_EXPECT_MSG_EQ(QosUtilsIsOldPacket(2048, 0), true, "0 is old in comparison to 2048");
255 // startingSeq=4095, seqNum=0
257 false,
258 "0 is new in comparison to 4095");
259 // startingSeq=0, seqNum=4095
260 NS_TEST_EXPECT_MSG_EQ(QosUtilsIsOldPacket(0, 4095), true, "4095 is old in comparison to 0");
261 // startingSeq=4095 seqNum=2047
263 true,
264 "2047 is old in comparison to 4095");
265 // startingSeq=2048 seqNum=4095
267 false,
268 "4095 is new in comparison to 2048");
269 // startingSeq=2049 seqNum=0
271 false,
272 "0 is new in comparison to 2049");
273 }
274};
275
276/**
277 * See \bugid{991}
278 */
280{
281 public:
283
284 void DoRun() override;
285
286 private:
287 /**
288 * Create one function
289 * \param pos the position
290 * \param channel the wifi channel
291 * \returns the node
292 */
293 Ptr<Node> CreateOne(Vector pos, Ptr<YansWifiChannel> channel);
294 /**
295 * Send one packet function
296 * \param dev the device
297 */
299 /**
300 * Switch channel function
301 * \param dev the device
302 */
304
307 ObjectFactory m_propDelay; ///< propagation delay
308};
309
311 : TestCase("InterferenceHelperSequence")
312{
313}
314
315void
317{
318 Ptr<Packet> p = Create<Packet>(1000);
319 dev->Send(p, dev->GetBroadcast(), 1);
320}
321
322void
324{
325 Ptr<WifiPhy> p = dev->GetPhy();
326 p->SetOperatingChannel(WifiPhy::ChannelTuple{40, 0, WIFI_PHY_BAND_5GHZ, 0});
327}
328
331{
334 node->AddDevice(dev);
335
337 auto phy = CreateObject<YansWifiPhy>();
339 phy->SetInterferenceHelper(interferenceHelper);
341 phy->SetErrorRateModel(error);
342 phy->SetChannel(channel);
343 phy->SetDevice(dev);
344 phy->SetMobility(mobility);
345 phy->ConfigureStandard(WIFI_STANDARD_80211a);
346 dev->SetPhy(phy);
347 auto manager = m_manager.Create<WifiRemoteStationManager>();
348 dev->SetRemoteStationManager(manager);
349
350 auto txop = CreateObjectWithAttributes<Txop>("AcIndex", StringValue("AC_BE_NQOS"));
351 m_mac.Set("Txop", PointerValue(txop));
352 auto mac = m_mac.Create<WifiMac>();
353 mac->SetDevice(dev);
354 mac->SetAddress(Mac48Address::Allocate());
355 dev->SetMac(mac);
356 mac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
357 mac->SetFrameExchangeManagers({CreateObject<FrameExchangeManager>()});
358 mac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
359 Ptr<FrameExchangeManager> fem = mac->GetFrameExchangeManager();
360 fem->SetAddress(mac->GetAddress());
362 protectionManager->SetWifiMac(mac);
363 fem->SetProtectionManager(protectionManager);
365 ackManager->SetWifiMac(mac);
366 fem->SetAckManager(ackManager);
367
368 mobility->SetPosition(pos);
369 node->AggregateObject(mobility);
370
371 return node;
372}
373
374void
376{
377 m_mac.SetTypeId("ns3::AdhocWifiMac");
378 m_propDelay.SetTypeId("ns3::ConstantSpeedPropagationDelayModel");
379 m_manager.SetTypeId("ns3::ConstantRateWifiManager");
380
384 channel->SetPropagationDelayModel(propDelay);
385 channel->SetPropagationLossModel(propLoss);
386
387 Ptr<Node> rxOnly = CreateOne(Vector(0.0, 0.0, 0.0), channel);
388 Ptr<Node> senderA = CreateOne(Vector(5.0, 0.0, 0.0), channel);
389 Ptr<Node> senderB = CreateOne(Vector(-5.0, 0.0, 0.0), channel);
390
391 propLoss->SetLoss(senderB->GetObject<MobilityModel>(),
392 rxOnly->GetObject<MobilityModel>(),
393 0,
394 true);
395 propLoss->SetDefaultLoss(999);
396
399 this,
400 DynamicCast<WifiNetDevice>(senderB->GetDevice(0)));
401
402 Simulator::Schedule(Seconds(1.0000001),
404 this,
405 DynamicCast<WifiNetDevice>(rxOnly->GetDevice(0)));
406
409 this,
410 DynamicCast<WifiNetDevice>(senderA->GetDevice(0)));
411
414 this,
415 DynamicCast<WifiNetDevice>(senderB->GetDevice(0)));
416
417 Simulator::Stop(Seconds(100.0));
419
421}
422
423//-----------------------------------------------------------------------------
424/**
425 * Make sure that when multiple broadcast packets are queued on the same
426 * device in a short succession, that:
427 * 1) no backoff occurs if the frame arrives and the idle time >= DIFS or AIFSn
428 * (this is 'DCF immediate access', Figure 9-3 of IEEE 802.11-2012)
429 * 2) a backoff occurs for the second frame that arrives (this is clearly
430 * stated in Sec. 9.3.4.2 of IEEE 802.11-2012, (basic access, which
431 * applies to group-addressed frames) where it states
432 * "If, under these conditions, the medium is determined by the CS
433 * mechanism to be busy when a STA desires to initiate the initial frame
434 * of a frame exchange sequence (described in Annex G), exclusive of the
435 * CF period, the random backoff procedure described in 9.3.4.3
436 * shall be followed."
437 * and from 9.3.4.3
438 * "The result of this procedure is that transmitted
439 * frames from a STA are always separated by at least one backoff interval."
440 *
441 * The observed behavior is that the first frame will be sent immediately,
442 * and the frames are spaced by (backoff + DIFS) time intervals
443 * (where backoff is a random number of slot sizes up to maximum CW)
444 *
445 * The following test case should _not_ generate virtual collision for
446 * the second frame. The seed and run numbers were pick such that the
447 * second frame gets backoff = 1 slot.
448 *
449 * frame 1, frame 2
450 * arrive DIFS = 2 x slot + SIFS
451 * | = 2 x 9us + 16us for 11a
452 * | <----------->
453 * V <-backoff->
454 * time |--------------|-------------------|-------------|----------->
455 * 0 1s 1.001408s 1.001442s |1.001451s
456 * ^ ^ ^
457 * start TX finish TX start TX
458 * frame 1 frame 1 frame 2
459 * ^
460 * frame 2
461 * backoff = 1 slot
462 *
463 * The buggy behavior observed in prior versions was shown by picking
464 * RngSeedManager::SetRun (17);
465 * which generated a 0 slot backoff for frame 2. Then, frame 2
466 * experiences a virtual collision and re-selects the backoff again.
467 * As a result, the _actual_ backoff experience by frame 2 is less likely
468 * to be 0 since that would require two successions of 0 backoff (one that
469 * generates the virtual collision and one after the virtual collision).
470 *
471 * See \bugid{555} for past behavior.
472 */
473
475{
476 public:
478
479 void DoRun() override;
480
481 private:
482 /**
483 * Send one packet function
484 * \param dev the device
485 */
487
490 ObjectFactory m_propDelay; ///< propagation delay
491
492 Time m_firstTransmissionTime; ///< first transmission time
493 Time m_secondTransmissionTime; ///< second transmission time
494 unsigned int m_numSentPackets; ///< number of sent packets
495
496 /**
497 * Notify Phy transmit begin
498 * \param p the packet
499 * \param txPowerW the tx power
500 */
501 void NotifyPhyTxBegin(Ptr<const Packet> p, double txPowerW);
502};
503
505 : TestCase("Test case for DCF immediate access with broadcast frames")
506{
507}
508
509void
522
523void
525{
526 Ptr<Packet> p = Create<Packet>(1000);
527 dev->Send(p, dev->GetBroadcast(), 1);
528}
529
530void
532{
533 m_mac.SetTypeId("ns3::AdhocWifiMac");
534 m_propDelay.SetTypeId("ns3::ConstantSpeedPropagationDelayModel");
535 m_manager.SetTypeId("ns3::ConstantRateWifiManager");
536
537 // Assign a seed and run number, and later fix the assignment of streams to
538 // WiFi random variables, so that the first backoff used is one slot
540 RngSeedManager::SetRun(40); // a value of 17 will result in zero slots
541
545 channel->SetPropagationDelayModel(propDelay);
546 channel->SetPropagationLossModel(propLoss);
547
548 Ptr<Node> txNode = CreateObject<Node>();
550
554 txPhy->SetInterferenceHelper(txInterferenceHelper);
556 txPhy->SetErrorRateModel(txError);
557 txPhy->SetChannel(channel);
558 txPhy->SetDevice(txDev);
559 txPhy->SetMobility(txMobility);
560 txPhy->ConfigureStandard(WIFI_STANDARD_80211a);
561
562 txPhy->TraceConnectWithoutContext(
563 "PhyTxBegin",
565
566 txMobility->SetPosition(Vector(0.0, 0.0, 0.0));
567 txNode->AggregateObject(txMobility);
568 txDev->SetPhy(txPhy);
569 txDev->SetRemoteStationManager(m_manager.Create<WifiRemoteStationManager>());
570 txNode->AddDevice(txDev);
571
572 auto txop = CreateObjectWithAttributes<Txop>("AcIndex", StringValue("AC_BE_NQOS"));
573 m_mac.Set("Txop", PointerValue(txop));
574 auto txMac = m_mac.Create<WifiMac>();
575 txMac->SetDevice(txDev);
576 txMac->SetAddress(Mac48Address::Allocate());
577 txDev->SetMac(txMac);
578 txMac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
579 txMac->SetFrameExchangeManagers({CreateObject<FrameExchangeManager>()});
580 txMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
581 auto fem = txMac->GetFrameExchangeManager();
582 fem->SetAddress(txMac->GetAddress());
583 auto protectionManager = CreateObject<WifiDefaultProtectionManager>();
584 protectionManager->SetWifiMac(txMac);
585 fem->SetProtectionManager(protectionManager);
586 auto ackManager = CreateObject<WifiDefaultAckManager>();
587 ackManager->SetWifiMac(txMac);
588 fem->SetAckManager(ackManager);
589
590 // Fix the stream assignment to the Dcf Txop objects (backoffs)
591 // The below stream assignment will result in the Txop object
592 // using a backoff value of zero for this test when the
593 // Txop::EndTxNoAck() calls to StartBackoffNow()
594 AssignWifiRandomStreams(txMac, 23);
595
599
602 this,
603 txDev);
606 this,
607 txDev);
608
612
613 // First packet is transmitted a DIFS after the packet is queued. A DIFS
614 // is 2 slots (2 * 9 = 18 us) plus a SIFS (16 us), i.e., 34 us
615 Time expectedFirstTransmissionTime = Seconds(1.0) + MicroSeconds(34);
616
617 // First packet has 1408 us of transmit time. Slot time is 9 us.
618 // Backoff is 1 slots. SIFS is 16 us. DIFS is 2 slots = 18 us.
619 // Should send next packet at 1408 us + (1 * 9 us) + 16 us + (2 * 9) us
620 // 1451 us after the first one.
621 uint32_t expectedWait1 = 1408 + (1 * 9) + 16 + (2 * 9);
622 Time expectedSecondTransmissionTime =
623 expectedFirstTransmissionTime + MicroSeconds(expectedWait1);
625 expectedFirstTransmissionTime,
626 "The first transmission time not correct!");
627
629 expectedSecondTransmissionTime,
630 "The second transmission time not correct!");
631}
632
633//-----------------------------------------------------------------------------
634/**
635 * Make sure that when changing the fragmentation threshold during the simulation,
636 * the TCP transmission does not unexpectedly stop.
637 *
638 * The scenario considers a TCP transmission between a 802.11b station and a 802.11b
639 * access point. After the simulation has begun, the fragmentation threshold is set at
640 * a value lower than the packet size. It then checks whether the TCP transmission
641 * continues after the fragmentation threshold modification.
642 *
643 * See \bugid{730}
644 */
645
647{
648 public:
650 ~Bug730TestCase() override;
651
652 void DoRun() override;
653
654 private:
655 uint32_t m_received; ///< received
656
657 /**
658 * Receive function
659 * \param context the context
660 * \param p the packet
661 * \param adr the address
662 */
663 void Receive(std::string context, Ptr<const Packet> p, const Address& adr);
664};
665
667 : TestCase("Test case for Bug 730"),
668 m_received(0)
669{
670}
671
675
676void
677Bug730TestCase::Receive(std::string context, Ptr<const Packet> p, const Address& adr)
678{
679 if ((p->GetSize() == 1460) && (Simulator::Now() > Seconds(20)))
680 {
681 m_received++;
682 }
683}
684
685void
687{
688 m_received = 0;
689
690 NodeContainer wifiStaNode;
691 wifiStaNode.Create(1);
692
693 NodeContainer wifiApNode;
694 wifiApNode.Create(1);
695
698 phy.SetChannel(channel.Create());
699
700 WifiHelper wifi;
701 wifi.SetStandard(WIFI_STANDARD_80211b);
702 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
703 "DataMode",
704 StringValue("DsssRate1Mbps"),
705 "ControlMode",
706 StringValue("DsssRate1Mbps"));
707
708 WifiMacHelper mac;
709 Ssid ssid = Ssid("ns-3-ssid");
710 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid), "ActiveProbing", BooleanValue(false));
711
712 NetDeviceContainer staDevices;
713 staDevices = wifi.Install(phy, mac, wifiStaNode);
714
715 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid), "BeaconGeneration", BooleanValue(true));
716
717 NetDeviceContainer apDevices;
718 apDevices = wifi.Install(phy, mac, wifiApNode);
719
720 MobilityHelper mobility;
722
723 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
724 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
725 mobility.SetPositionAllocator(positionAlloc);
726
727 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
728 mobility.Install(wifiApNode);
729 mobility.Install(wifiStaNode);
730
731 Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice>(apDevices.Get(0));
732 Ptr<WifiNetDevice> sta_device = DynamicCast<WifiNetDevice>(staDevices.Get(0));
733
734 PacketSocketAddress socket;
735 socket.SetSingleDevice(sta_device->GetIfIndex());
736 socket.SetPhysicalAddress(ap_device->GetAddress());
737 socket.SetProtocol(1);
738
739 // give packet socket powers to nodes.
740 PacketSocketHelper packetSocket;
741 packetSocket.Install(wifiStaNode);
742 packetSocket.Install(wifiApNode);
743
745 client->SetAttribute("PacketSize", UintegerValue(1460));
746 client->SetRemote(socket);
747 wifiStaNode.Get(0)->AddApplication(client);
748 client->SetStartTime(Seconds(1));
749 client->SetStopTime(Seconds(51.0));
750
752 server->SetLocal(socket);
753 wifiApNode.Get(0)->AddApplication(server);
754 server->SetStartTime(Seconds(0.0));
755 server->SetStopTime(Seconds(52.0));
756
757 Config::Connect("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx",
759
762 "/NodeList/0/DeviceList/0/RemoteStationManager/FragmentationThreshold",
763 StringValue("800"));
764
767
769
770 bool result = (m_received > 0);
772 result,
773 true,
774 "packet reception unexpectedly stopped after adapting fragmentation threshold!");
775}
776
777//-----------------------------------------------------------------------------
778/**
779 * Make sure that fragmentation works with QoS stations.
780 *
781 * The scenario considers a TCP transmission between an 802.11n station and an 802.11n
782 * access point.
783 */
784
786{
787 public:
789 ~QosFragmentationTestCase() override;
790
791 void DoRun() override;
792
793 private:
794 uint32_t m_received; ///< received packets
795 uint32_t m_fragments; ///< transmitted fragments
796
797 /**
798 * Receive function
799 * \param context the context
800 * \param p the packet
801 * \param adr the address
802 */
803 void Receive(std::string context, Ptr<const Packet> p, const Address& adr);
804
805 /**
806 * Callback invoked when PHY transmits a packet
807 * \param context the context
808 * \param p the packet
809 * \param power the tx power
810 */
811 void Transmit(std::string context, Ptr<const Packet> p, double power);
812};
813
815 : TestCase("Test case for fragmentation with QoS stations"),
816 m_received(0),
817 m_fragments(0)
818{
819}
820
824
825void
827{
828 if (p->GetSize() == 1400)
829 {
830 m_received++;
831 }
832}
833
834void
835QosFragmentationTestCase::Transmit(std::string context, Ptr<const Packet> p, double power)
836{
837 WifiMacHeader hdr;
838 p->PeekHeader(hdr);
839 if (hdr.IsQosData())
840 {
841 NS_TEST_EXPECT_MSG_LT_OR_EQ(p->GetSize(), 400, "Unexpected fragment size");
842 m_fragments++;
843 }
844}
845
846void
848{
849 NodeContainer wifiStaNode;
850 wifiStaNode.Create(1);
851
852 NodeContainer wifiApNode;
853 wifiApNode.Create(1);
854
857 phy.SetChannel(channel.Create());
858
859 WifiHelper wifi;
860 wifi.SetStandard(WIFI_STANDARD_80211n);
861 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", "DataMode", StringValue("HtMcs7"));
862
863 WifiMacHelper mac;
864 Ssid ssid = Ssid("ns-3-ssid");
865 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid), "ActiveProbing", BooleanValue(false));
866
867 NetDeviceContainer staDevices;
868 staDevices = wifi.Install(phy, mac, wifiStaNode);
869
870 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid), "BeaconGeneration", BooleanValue(true));
871
872 NetDeviceContainer apDevices;
873 apDevices = wifi.Install(phy, mac, wifiApNode);
874
875 MobilityHelper mobility;
877
878 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
879 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
880 mobility.SetPositionAllocator(positionAlloc);
881
882 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
883 mobility.Install(wifiApNode);
884 mobility.Install(wifiStaNode);
885
886 Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice>(apDevices.Get(0));
887 Ptr<WifiNetDevice> sta_device = DynamicCast<WifiNetDevice>(staDevices.Get(0));
888
889 // set the TXOP limit on BE AC
890 PointerValue ptr;
891 sta_device->GetMac()->GetAttribute("BE_Txop", ptr);
892 ptr.Get<QosTxop>()->SetTxopLimit(MicroSeconds(3008));
893
894 PacketSocketAddress socket;
895 socket.SetSingleDevice(sta_device->GetIfIndex());
896 socket.SetPhysicalAddress(ap_device->GetAddress());
897 socket.SetProtocol(1);
898
899 // give packet socket powers to nodes.
900 PacketSocketHelper packetSocket;
901 packetSocket.Install(wifiStaNode);
902 packetSocket.Install(wifiApNode);
903
905 client->SetAttribute("PacketSize", UintegerValue(1400));
906 client->SetAttribute("MaxPackets", UintegerValue(1));
907 client->SetRemote(socket);
908 wifiStaNode.Get(0)->AddApplication(client);
909 client->SetStartTime(Seconds(1));
910 client->SetStopTime(Seconds(3.0));
911
913 server->SetLocal(socket);
914 wifiApNode.Get(0)->AddApplication(server);
915 server->SetStartTime(Seconds(0.0));
916 server->SetStopTime(Seconds(4.0));
917
918 Config::Connect("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx",
920
921 Config::Set("/NodeList/0/DeviceList/0/RemoteStationManager/FragmentationThreshold",
922 StringValue("400"));
923 Config::Connect("/NodeList/0/DeviceList/0/Phy/PhyTxBegin",
925
928
930
931 NS_TEST_ASSERT_MSG_EQ(m_received, 1, "Unexpected number of received packets");
932 NS_TEST_ASSERT_MSG_EQ(m_fragments, 4, "Unexpected number of transmitted fragments");
933}
934
935/**
936 * \ingroup wifi-test
937 * \ingroup tests
938 *
939 * \brief Set Channel Frequency Test
940 */
942{
943 public:
945
946 void DoRun() override;
947
948 private:
949 /**
950 * Get yans wifi phy function
951 * \param nc the device collection
952 * \returns the wifi phy
953 */
955};
956
958 : TestCase("Test case for setting WifiPhy channel and frequency")
959{
960}
961
964{
965 Ptr<WifiNetDevice> wnd = nc.Get(0)->GetObject<WifiNetDevice>();
966 Ptr<WifiPhy> wp = wnd->GetPhy();
967 return wp->GetObject<YansWifiPhy>();
968}
969
970void
972{
973 NodeContainer wifiStaNode;
974 wifiStaNode.Create(1);
975 NodeContainer wifiApNode;
976 wifiApNode.Create(1);
977
980 phy.SetChannel(channel.Create());
981
982 // Configure and declare other generic components of this example
983 Ssid ssid;
984 ssid = Ssid("wifi-phy-configuration");
985 WifiMacHelper macSta;
986 macSta.SetType("ns3::StaWifiMac",
987 "Ssid",
988 SsidValue(ssid),
989 "ActiveProbing",
990 BooleanValue(false));
991 NetDeviceContainer staDevice;
992 Ptr<YansWifiPhy> phySta;
993
994 // Cases taken from src/wifi/examples/wifi-phy-configuration.cc example
995 {
996 // case 0:
997 // Default configuration, without WifiHelper::SetStandard or WifiHelper
998 phySta = CreateObject<YansWifiPhy>();
999 // The default results in an invalid configuration
1000 NS_TEST_ASSERT_MSG_EQ(phySta->GetOperatingChannel().IsSet(),
1001 false,
1002 "default configuration");
1003 }
1004 {
1005 // case 1:
1006 WifiHelper wifi;
1007 wifi.SetStandard(WIFI_STANDARD_80211a);
1008 wifi.SetRemoteStationManager("ns3::ArfWifiManager");
1009 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1010 phySta = GetYansWifiPhyPtr(staDevice);
1011 // We expect channel 36, width 20, frequency 5180
1012 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "default configuration");
1013 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "default configuration");
1014 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "default configuration");
1015 }
1016 {
1017 // case 2:
1018 WifiHelper wifi;
1019 wifi.SetStandard(WIFI_STANDARD_80211b);
1020 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1021 phySta = GetYansWifiPhyPtr(staDevice);
1022 // We expect channel 1, width 22, frequency 2412
1023 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 1, "802.11b configuration");
1024 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 22, "802.11b configuration");
1025 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 2412, "802.11b configuration");
1026 }
1027 {
1028 // case 3:
1029 WifiHelper wifi;
1030 wifi.SetStandard(WIFI_STANDARD_80211g);
1031 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1032 phySta = GetYansWifiPhyPtr(staDevice);
1033 // We expect channel 1, width 20, frequency 2412
1034 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 1, "802.11g configuration");
1035 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11g configuration");
1036 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 2412, "802.11g configuration");
1037 }
1038 {
1039 // case 4:
1040 WifiHelper wifi;
1041 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1042 wifi.SetStandard(WIFI_STANDARD_80211n);
1043 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_5GHZ, 0}"));
1044 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1045 phySta = GetYansWifiPhyPtr(staDevice);
1046 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11n-5GHz configuration");
1047 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11n-5GHz configuration");
1048 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11n-5GHz configuration");
1049 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1050 }
1051 {
1052 // case 5:
1053 WifiHelper wifi;
1054 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1055 wifi.SetStandard(WIFI_STANDARD_80211n);
1056 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1057 phySta = GetYansWifiPhyPtr(staDevice);
1058 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 1, "802.11n-2.4GHz configuration");
1059 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11n-2.4GHz configuration");
1060 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 2412, "802.11n-2.4GHz configuration");
1061 }
1062 {
1063 // case 6:
1064 WifiHelper wifi;
1065 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1066 wifi.SetStandard(WIFI_STANDARD_80211ac);
1067 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1068 phySta = GetYansWifiPhyPtr(staDevice);
1069 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 42, "802.11ac configuration");
1070 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 80, "802.11ac configuration");
1071 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5210, "802.11ac configuration");
1072 }
1073 {
1074 // case 7:
1075 // By default, WifiHelper will use WIFI_PHY_STANDARD_80211ax
1076 WifiHelper wifi;
1077 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1078 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_2_4GHZ, 0}"));
1079 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1080 phySta = GetYansWifiPhyPtr(staDevice);
1081 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 1, "802.11ax-2.4GHz configuration");
1082 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11ax-2.4GHz configuration");
1083 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 2412, "802.11ax-2.4GHz configuration");
1084 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1085 }
1086 {
1087 // case 8:
1088 WifiHelper wifi;
1089 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1090 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1091 phySta = GetYansWifiPhyPtr(staDevice);
1092 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 42, "802.11ax-5GHz configuration");
1093 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 80, "802.11ax-5GHz configuration");
1094 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5210, "802.11ax-5GHz configuration");
1095 }
1096 {
1097 // case 9:
1098 WifiHelper wifi;
1099 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1100 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_6GHZ, 0}"));
1101 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1102 phySta = GetYansWifiPhyPtr(staDevice);
1103 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 7, "802.11ax-6GHz configuration");
1104 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 80, "802.11ax-6GHz configuration");
1105 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5985, "802.11ax-6GHz configuration");
1106 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1107 }
1108 {
1109 // case 10:
1110 WifiHelper wifi;
1111 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1112 wifi.SetStandard(WIFI_STANDARD_80211p);
1113 phy.Set("ChannelSettings", StringValue("{0, 10, BAND_5GHZ, 0}"));
1114 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1115 phySta = GetYansWifiPhyPtr(staDevice);
1116 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 172, "802.11p 10Mhz configuration");
1117 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 10, "802.11p 10Mhz configuration");
1118 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5860, "802.11p 10Mhz configuration");
1119 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1120 }
1121 {
1122 // case 11:
1123 WifiHelper wifi;
1124 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1125 wifi.SetStandard(WIFI_STANDARD_80211p);
1126 phy.Set("ChannelSettings", StringValue("{0, 5, BAND_5GHZ, 0}"));
1127 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1128 phySta = GetYansWifiPhyPtr(staDevice);
1129 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 171, "802.11p 5Mhz configuration");
1130 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 5, "802.11p 5Mhz configuration");
1131 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5860, "802.11p 5Mhz configuration");
1132 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1133 }
1134 {
1135 // case 12:
1136 WifiHelper wifi;
1137 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1138 wifi.SetStandard(WIFI_STANDARD_80211n);
1139 phy.Set("ChannelSettings", StringValue("{44, 20, BAND_5GHZ, 0}"));
1140 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1141 phySta = GetYansWifiPhyPtr(staDevice);
1142 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 44, "802.11 5GHz configuration");
1143 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1144 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5220, "802.11 5GHz configuration");
1145 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1146 }
1147 {
1148 // case 13:
1149 WifiHelper wifi;
1150 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1151 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1152 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1153 phySta = GetYansWifiPhyPtr(staDevice);
1154 // Post-install reconfiguration to channel number 40
1155 std::ostringstream path;
1156 path << "/NodeList/*/DeviceList/" << staDevice.Get(0)->GetIfIndex()
1157 << "/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelSettings";
1158 Config::Set(path.str(), StringValue("{40, 0, BAND_5GHZ, 0}"));
1159 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 40, "802.11 5GHz configuration");
1160 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1161 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5200, "802.11 5GHz configuration");
1162 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1163 }
1164 {
1165 // case 14:
1166 WifiHelper wifi;
1167 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1168 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1169 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1170 phySta = GetYansWifiPhyPtr(staDevice);
1171 // Post-install reconfiguration to a 40 MHz channel
1172 std::ostringstream path;
1173 path << "/NodeList/*/DeviceList/" << staDevice.Get(0)->GetIfIndex()
1174 << "/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelSettings";
1175 Config::Set(path.str(), StringValue("{46, 0, BAND_5GHZ, 0}"));
1176 // Although channel 44 is configured originally for 20 MHz, we
1177 // allow it to be used for 40 MHz here
1178 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 46, "802.11 5GHz configuration");
1179 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 40, "802.11 5GHz configuration");
1180 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5230, "802.11 5GHz configuration");
1181 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1182 }
1183 {
1184 // case 15:
1185 WifiHelper wifi;
1186 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1187 wifi.SetStandard(WIFI_STANDARD_80211n);
1188 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1189 phySta = GetYansWifiPhyPtr(staDevice);
1190 phySta->SetAttribute("ChannelSettings", StringValue("{3, 20, BAND_2_4GHZ, 0}"));
1191 // Post-install reconfiguration to a 40 MHz channel
1192 std::ostringstream path;
1193 path << "/NodeList/*/DeviceList/" << staDevice.Get(0)->GetIfIndex()
1194 << "/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelSettings";
1195 Config::Set(path.str(), StringValue("{4, 40, BAND_2_4GHZ, 0}"));
1196 // Although channel 44 is configured originally for 20 MHz, we
1197 // allow it to be used for 40 MHz here
1198 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 4, "802.11 5GHz configuration");
1199 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 40, "802.11 5GHz configuration");
1200 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 2427, "802.11 5GHz configuration");
1201 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1202 }
1203 {
1204 // case 16:
1205 WifiHelper wifi;
1206 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1207 // Test that setting Frequency to a non-standard value will throw an exception
1208 wifi.SetStandard(WIFI_STANDARD_80211n);
1209 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1210 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1211 phySta = GetYansWifiPhyPtr(staDevice);
1212 bool exceptionThrown = false;
1213 try
1214 {
1215 phySta->SetAttribute("ChannelSettings", StringValue("{45, 0, BAND_5GHZ, 0}"));
1216 }
1217 catch (const std::runtime_error&)
1218 {
1219 exceptionThrown = true;
1220 }
1221 // We expect that an exception is thrown
1222 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1223 }
1224 {
1225 // case 17:
1226 WifiHelper wifi;
1227 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1228 wifi.SetStandard(WIFI_STANDARD_80211n);
1229 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1230 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1231 phySta = GetYansWifiPhyPtr(staDevice);
1232 // Test that setting channel to a standard value will set the
1233 // frequency correctly
1234 phySta->SetAttribute("ChannelSettings", StringValue("{100, 0, BAND_5GHZ, 0}"));
1235 // We expect frequency to be 5500 due to channel number being 100
1236 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 100, "802.11 5GHz configuration");
1237 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1238 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5500, "802.11 5GHz configuration");
1239 }
1240 {
1241 // case 18:
1242 // Set a wrong channel after initialization
1243 WifiHelper wifi;
1244 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1245 wifi.SetStandard(WIFI_STANDARD_80211n);
1246 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1247 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1248 phySta = GetYansWifiPhyPtr(staDevice);
1249 bool exceptionThrown = false;
1250 try
1251 {
1252 phySta->SetOperatingChannel(WifiPhy::ChannelTuple{99, 40, WIFI_PHY_BAND_5GHZ, 0});
1253 }
1254 catch (const std::runtime_error&)
1255 {
1256 exceptionThrown = true;
1257 }
1258 // We expect that an exception is thrown
1259 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1260 }
1261 {
1262 // case 19:
1263 WifiHelper wifi;
1264 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1265 // Test how channel number behaves when frequency is non-standard
1266 wifi.SetStandard(WIFI_STANDARD_80211n);
1267 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1268 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1269 phySta = GetYansWifiPhyPtr(staDevice);
1270 bool exceptionThrown = false;
1271 try
1272 {
1273 phySta->SetAttribute("ChannelSettings", StringValue("{45, 0, BAND_5GHZ, 0}"));
1274 }
1275 catch (const std::runtime_error&)
1276 {
1277 exceptionThrown = true;
1278 }
1279 // We expect that an exception is thrown due to unknown channel number 45
1280 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1281 phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1282 // We expect channel number to be 36 due to known center frequency 5180
1283 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1284 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1285 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11 5GHz configuration");
1286 exceptionThrown = false;
1287 try
1288 {
1289 phySta->SetAttribute("ChannelSettings", StringValue("{43, 0, BAND_5GHZ, 0}"));
1290 }
1291 catch (const std::runtime_error&)
1292 {
1293 exceptionThrown = true;
1294 }
1295 // We expect that an exception is thrown due to unknown channel number 43
1296 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1297 phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1298 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1299 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1300 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11 5GHz configuration");
1301 }
1302 {
1303 // case 20:
1304 WifiHelper wifi;
1305 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1306 phy.Set("ChannelSettings", StringValue("{40, 0, BAND_5GHZ, 0}"));
1307 wifi.SetStandard(WIFI_STANDARD_80211n);
1308 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1309 phySta = GetYansWifiPhyPtr(staDevice);
1310 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 40, "802.11 5GHz configuration");
1311 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1312 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5200, "802.11 5GHz configuration");
1313 // Set both channel and frequency to consistent values after initialization
1314 wifi.SetStandard(WIFI_STANDARD_80211n);
1315 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1316 phySta = GetYansWifiPhyPtr(staDevice);
1317 phySta->SetAttribute("ChannelSettings", StringValue("{40, 0, BAND_5GHZ, 0}"));
1318 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 40, "802.11 5GHz configuration");
1319 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1320 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5200, "802.11 5GHz configuration");
1321
1322 phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1323 // We expect channel number to be 36
1324 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1325 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1326 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11 5GHz configuration");
1327 phySta->SetAttribute("ChannelSettings", StringValue("{40, 0, BAND_5GHZ, 0}"));
1328 // We expect channel number to be 40
1329 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 40, "802.11 5GHz configuration");
1330 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1331 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5200, "802.11 5GHz configuration");
1332 bool exceptionThrown = false;
1333 try
1334 {
1335 phySta->SetAttribute("ChannelSettings", StringValue("{45, 0, BAND_5GHZ, 0}"));
1336 }
1337 catch (const std::runtime_error&)
1338 {
1339 exceptionThrown = true;
1340 }
1341 phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1342 // We expect channel number to be 36 and an exception to be thrown
1343 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1344 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1345 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11 5GHz configuration");
1346 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1347 phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1348 exceptionThrown = false;
1349 try
1350 {
1351 phySta->SetAttribute("ChannelSettings", StringValue("{43, 0, BAND_5GHZ, 0}"));
1352 }
1353 catch (const std::runtime_error&)
1354 {
1355 exceptionThrown = true;
1356 }
1357 // We expect channel number to be 36 and an exception to be thrown
1358 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1359 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1360 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11 5GHz configuration");
1361 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1362 }
1363
1365}
1366
1367//-----------------------------------------------------------------------------
1368/**
1369 * Make sure that when virtual collision occurs the wifi remote station manager
1370 * is triggered and the retry counter is increased.
1371 *
1372 * See \bugid{2222}
1373 */
1374
1376{
1377 public:
1379 ~Bug2222TestCase() override;
1380
1381 void DoRun() override;
1382
1383 private:
1384 uint32_t m_countInternalCollisions; ///< count internal collisions
1385
1386 /**
1387 * Transmit data failed function
1388 * \param context the context
1389 * \param adr the MAC address
1390 */
1391 void TxDataFailedTrace(std::string context, Mac48Address adr);
1392};
1393
1395 : TestCase("Test case for Bug 2222"),
1396 m_countInternalCollisions(0)
1397{
1398}
1399
1403
1404void
1406{
1407 // Indicate the long retry counter has been increased in the wifi remote station manager
1409}
1410
1411void
1413{
1415
1416 // Generate same backoff for AC_VI and AC_VO
1417 // The below combination will work
1420 int64_t streamNumber = 100;
1421
1422 NodeContainer wifiNodes;
1423 wifiNodes.Create(2);
1424
1427 phy.SetChannel(channel.Create());
1428
1429 WifiHelper wifi;
1430 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
1431 "DataMode",
1432 StringValue("OfdmRate54Mbps"),
1433 "ControlMode",
1434 StringValue("OfdmRate24Mbps"));
1435 WifiMacHelper mac;
1436 Ssid ssid = Ssid("ns-3-ssid");
1437 mac.SetType("ns3::AdhocWifiMac", "QosSupported", BooleanValue(true));
1438
1439 NetDeviceContainer wifiDevices;
1440 wifiDevices = wifi.Install(phy, mac, wifiNodes);
1441
1442 // Assign fixed streams to random variables in use
1443 WifiHelper::AssignStreams(wifiDevices, streamNumber);
1444
1445 MobilityHelper mobility;
1447
1448 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
1449 positionAlloc->Add(Vector(10.0, 0.0, 0.0));
1450 mobility.SetPositionAllocator(positionAlloc);
1451
1452 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1453 mobility.Install(wifiNodes);
1454
1455 Ptr<WifiNetDevice> device1 = DynamicCast<WifiNetDevice>(wifiDevices.Get(0));
1456 Ptr<WifiNetDevice> device2 = DynamicCast<WifiNetDevice>(wifiDevices.Get(1));
1457
1458 PacketSocketAddress socket;
1459 socket.SetSingleDevice(device1->GetIfIndex());
1460 socket.SetPhysicalAddress(device2->GetAddress());
1461 socket.SetProtocol(1);
1462
1463 PacketSocketHelper packetSocket;
1464 packetSocket.Install(wifiNodes);
1465
1467 clientLowPriority->SetAttribute("PacketSize", UintegerValue(1460));
1468 clientLowPriority->SetAttribute("MaxPackets", UintegerValue(1));
1469 clientLowPriority->SetAttribute("Priority", UintegerValue(4)); // AC_VI
1470 clientLowPriority->SetRemote(socket);
1471 wifiNodes.Get(0)->AddApplication(clientLowPriority);
1472 clientLowPriority->SetStartTime(Seconds(0.0));
1473 clientLowPriority->SetStopTime(Seconds(1.0));
1474
1476 clientHighPriority->SetAttribute("PacketSize", UintegerValue(1460));
1477 clientHighPriority->SetAttribute("MaxPackets", UintegerValue(1));
1478 clientHighPriority->SetAttribute("Priority", UintegerValue(6)); // AC_VO
1479 clientHighPriority->SetRemote(socket);
1480 wifiNodes.Get(0)->AddApplication(clientHighPriority);
1481 clientHighPriority->SetStartTime(Seconds(0.0));
1482 clientHighPriority->SetStopTime(Seconds(1.0));
1483
1485 server->SetLocal(socket);
1486 wifiNodes.Get(1)->AddApplication(server);
1487 server->SetStartTime(Seconds(0.0));
1488 server->SetStopTime(Seconds(1.0));
1489
1490 Config::Connect("/NodeList/*/DeviceList/*/RemoteStationManager/MacTxDataFailed",
1492
1496
1498 1,
1499 "unexpected number of internal collisions!");
1500}
1501
1502//-----------------------------------------------------------------------------
1503/**
1504 * Make sure that the correct channel width and center frequency have been set
1505 * for OFDM basic rate transmissions and BSS channel widths larger than 20 MHz.
1506 *
1507 * The scenario considers a UDP transmission between a 40 MHz 802.11ac station and a
1508 * 40 MHz 802.11ac access point. All transmission parameters are checked so as
1509 * to ensure that only 2 {starting frequency, channelWidth, Number of subbands
1510 * in SpectrumModel, modulation type} tuples are used.
1511 *
1512 * See \bugid{2843}
1513 */
1514
1516{
1517 public:
1519 ~Bug2843TestCase() override;
1520 void DoRun() override;
1521
1522 private:
1523 /**
1524 * A tuple of {starting frequency, channelWidth, Number of subbands in SpectrumModel, modulation
1525 * type}
1526 */
1527 typedef std::tuple<Hz_u, MHz_u, uint32_t, WifiModulationClass> FreqWidthSubbandModulationTuple;
1528 std::vector<FreqWidthSubbandModulationTuple>
1529 m_distinctTuples; ///< vector of distinct {starting frequency, channelWidth, Number of
1530 ///< subbands in SpectrumModel, modulation type} tuples
1531
1532 /**
1533 * Stores the distinct {starting frequency, channelWidth, Number of subbands in SpectrumModel,
1534 * modulation type} tuples that have been used during the testcase run.
1535 * \param context the context
1536 * \param txParams spectrum signal parameters set by transmitter
1537 */
1538 void StoreDistinctTuple(std::string context, Ptr<SpectrumSignalParameters> txParams);
1539 /**
1540 * Triggers the arrival of a burst of 1000 Byte-long packets in the source device
1541 * \param numPackets number of packets in burst
1542 * \param sourceDevice pointer to the source NetDevice
1543 * \param destination address of the destination device
1544 */
1545 void SendPacketBurst(uint8_t numPackets,
1546 Ptr<NetDevice> sourceDevice,
1547 Address& destination) const;
1548
1549 MHz_u m_channelWidth; ///< channel width
1550};
1551
1553 : TestCase("Test case for Bug 2843"),
1554 m_channelWidth(20)
1555{
1556}
1557
1561
1562void
1564{
1565 // Extract starting frequency and number of subbands
1566 Ptr<const SpectrumModel> c = txParams->psd->GetSpectrumModel();
1567 std::size_t numBands = c->GetNumBands();
1568 const Hz_u startingFreq = c->Begin()->fl;
1569
1570 // Get channel bandwidth and modulation class
1573
1574 Ptr<WifiPpdu> ppdu = wifiTxParams->ppdu->Copy();
1575 WifiTxVector txVector = ppdu->GetTxVector();
1576 m_channelWidth = txVector.GetChannelWidth();
1577 WifiModulationClass modulationClass = txVector.GetMode().GetModulationClass();
1578
1579 // Build a tuple and check if seen before (if so store it)
1580 FreqWidthSubbandModulationTuple tupleForCurrentTx =
1581 std::make_tuple(startingFreq, m_channelWidth, numBands, modulationClass);
1582 bool found = false;
1583 for (auto it = m_distinctTuples.begin(); it != m_distinctTuples.end(); it++)
1584 {
1585 if (*it == tupleForCurrentTx)
1586 {
1587 found = true;
1588 }
1589 }
1590 if (!found)
1591 {
1592 m_distinctTuples.push_back(tupleForCurrentTx);
1593 }
1594}
1595
1596void
1598 Ptr<NetDevice> sourceDevice,
1599 Address& destination) const
1600{
1601 for (uint8_t i = 0; i < numPackets; i++)
1602 {
1603 Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
1604 sourceDevice->Send(pkt, destination, 0);
1605 }
1606}
1607
1608void
1610{
1611 MHz_u channelWidth = 40; // at least 40 MHz expected here
1612
1613 NodeContainer wifiStaNode;
1614 wifiStaNode.Create(1);
1615
1616 NodeContainer wifiApNode;
1617 wifiApNode.Create(1);
1618
1619 SpectrumWifiPhyHelper spectrumPhy;
1622 lossModel->SetFrequency(5.190e9);
1623 spectrumChannel->AddPropagationLossModel(lossModel);
1624
1627 spectrumChannel->SetPropagationDelayModel(delayModel);
1628
1629 spectrumPhy.SetChannel(spectrumChannel);
1630 spectrumPhy.SetErrorRateModel("ns3::NistErrorRateModel");
1631 spectrumPhy.Set("ChannelSettings", StringValue("{38, 40, BAND_5GHZ, 0}"));
1632 spectrumPhy.Set("TxPowerStart", DoubleValue(10));
1633 spectrumPhy.Set("TxPowerEnd", DoubleValue(10));
1634
1635 WifiHelper wifi;
1636 wifi.SetStandard(WIFI_STANDARD_80211ac);
1637 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
1638 "DataMode",
1639 StringValue("VhtMcs8"),
1640 "ControlMode",
1641 StringValue("VhtMcs8"),
1642 "RtsCtsThreshold",
1643 StringValue("500")); // so as to force RTS/CTS for data frames
1644
1645 WifiMacHelper mac;
1646 mac.SetType("ns3::StaWifiMac");
1647 NetDeviceContainer staDevice;
1648 staDevice = wifi.Install(spectrumPhy, mac, wifiStaNode);
1649
1650 mac.SetType("ns3::ApWifiMac");
1651 NetDeviceContainer apDevice;
1652 apDevice = wifi.Install(spectrumPhy, mac, wifiApNode);
1653
1654 MobilityHelper mobility;
1656 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
1657 positionAlloc->Add(Vector(1.0, 0.0, 0.0)); // put close enough in order to use MCS
1658 mobility.SetPositionAllocator(positionAlloc);
1659
1660 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1661 mobility.Install(wifiApNode);
1662 mobility.Install(wifiStaNode);
1663
1664 // Send two 5 packet-bursts
1667 this,
1668 5,
1669 apDevice.Get(0),
1670 staDevice.Get(0)->GetAddress());
1673 this,
1674 5,
1675 apDevice.Get(0),
1676 staDevice.Get(0)->GetAddress());
1677
1678 Config::Connect("/ChannelList/*/$ns3::MultiModelSpectrumChannel/TxSigParams",
1680
1683
1685
1686 // {starting frequency, channelWidth, Number of subbands in SpectrumModel, modulation type}
1687 // tuples
1688 std::size_t numberTuples = m_distinctTuples.size();
1689 NS_TEST_ASSERT_MSG_EQ(numberTuples, 2, "Only two distinct tuples expected");
1690 NS_TEST_ASSERT_MSG_EQ(std::get<0>(m_distinctTuples[0]) - 20e6,
1691 std::get<0>(m_distinctTuples[1]),
1692 "The starting frequency of the first tuple should be shifted 20 MHz to "
1693 "the right wrt second tuple");
1694 // Note that the first tuple should the one initiated by the beacon, i.e. non-HT OFDM (20 MHz)
1696 20,
1697 "First tuple's channel width should be 20 MHz");
1699 193,
1700 "First tuple should have 193 subbands (64+DC, 20MHz+DC, inband and 64*2 "
1701 "out-of-band, 20MHz on each side)");
1703 WifiModulationClass::WIFI_MOD_CLASS_OFDM,
1704 "First tuple should be OFDM");
1705 // Second tuple
1707 channelWidth,
1708 "Second tuple's channel width should be 40 MHz");
1710 385,
1711 "Second tuple should have 385 subbands (128+DC, 40MHz+DC, inband and "
1712 "128*2 out-of-band, 40MHz on each side)");
1714 WifiModulationClass::WIFI_MOD_CLASS_VHT,
1715 "Second tuple should be VHT_OFDM");
1716}
1717
1718//-----------------------------------------------------------------------------
1719/**
1720 * Make sure that the channel width and the channel number can be changed at runtime.
1721 *
1722 * The scenario considers an access point and a station using a 20 MHz channel width.
1723 * After 1s, we change the channel width and the channel number to use a 40 MHz channel.
1724 * The tests checks the operational channel width sent in Beacon frames
1725 * and verify that the association procedure is executed twice.
1726 *
1727 * See \bugid{2831}
1728 */
1729
1731{
1732 public:
1734 ~Bug2831TestCase() override;
1735 void DoRun() override;
1736
1737 private:
1738 /**
1739 * Function called to change the supported channel width at runtime
1740 */
1742 /**
1743 * Callback triggered when a packet is received by the PHYs
1744 * \param context the context
1745 * \param p the received packet
1746 * \param rxPowersW the received power per channel band in watts
1747 */
1748 void RxCallback(std::string context, Ptr<const Packet> p, RxPowerWattPerChannelBand rxPowersW);
1749
1752
1753 uint16_t m_assocReqCount; ///< count number of association requests
1754 uint16_t m_assocRespCount; ///< count number of association responses
1755 uint16_t m_countOperationalChannelWidth20; ///< count number of beacon frames announcing a 20
1756 ///< MHz operating channel width
1757 uint16_t m_countOperationalChannelWidth40; ///< count number of beacon frames announcing a 40
1758 ///< MHz operating channel width
1759};
1760
1762 : TestCase("Test case for Bug 2831"),
1763 m_assocReqCount(0),
1764 m_assocRespCount(0),
1765 m_countOperationalChannelWidth20(0),
1766 m_countOperationalChannelWidth40(0)
1767{
1768}
1769
1773
1774void
1780
1781void
1784 RxPowerWattPerChannelBand rxPowersW)
1785{
1786 Ptr<Packet> packet = p->Copy();
1787 WifiMacHeader hdr;
1788 packet->RemoveHeader(hdr);
1789 if (hdr.IsAssocReq())
1790 {
1792 }
1793 else if (hdr.IsAssocResp())
1794 {
1796 }
1797 else if (hdr.IsBeacon())
1798 {
1799 MgtBeaconHeader beacon;
1800 packet->RemoveHeader(beacon);
1801 const auto& htOperation = beacon.Get<HtOperation>();
1802 if (htOperation.has_value() && htOperation->GetStaChannelWidth() > 0)
1803 {
1805 }
1806 else
1807 {
1809 }
1810 }
1811}
1812
1813void
1815{
1817 ObjectFactory propDelay;
1818 propDelay.SetTypeId("ns3::ConstantSpeedPropagationDelayModel");
1819 Ptr<PropagationDelayModel> propagationDelay = propDelay.Create<PropagationDelayModel>();
1821 channel->SetPropagationDelayModel(propagationDelay);
1822 channel->SetPropagationLossModel(propagationLoss);
1823
1824 Ptr<Node> apNode = CreateObject<Node>();
1826 apNode->AddDevice(apDev);
1827 apDev->SetStandard(WIFI_STANDARD_80211ax);
1829 apDev->SetHtConfiguration(apHtConfiguration);
1830 ObjectFactory manager;
1831 manager.SetTypeId("ns3::ConstantRateWifiManager");
1832 apDev->SetRemoteStationManager(manager.Create<WifiRemoteStationManager>());
1833
1835 apMobility->SetPosition(Vector(0.0, 0.0, 0.0));
1836 apNode->AggregateObject(apMobility);
1837
1838 auto error = CreateObject<YansErrorRateModel>();
1840 apDev->SetPhy(m_apPhy);
1842 m_apPhy->SetInterferenceHelper(apInterferenceHelper);
1843 m_apPhy->SetErrorRateModel(error);
1844 m_apPhy->SetChannel(channel);
1845 m_apPhy->SetMobility(apMobility);
1846 m_apPhy->SetDevice(apDev);
1849
1850 ObjectFactory mac;
1851 mac.SetTypeId("ns3::ApWifiMac");
1852 mac.Set("EnableBeaconJitter", BooleanValue(false));
1853 mac.Set("QosSupported", BooleanValue(true));
1854 for (const std::string ac : {"BE", "BK", "VI", "VO"})
1855 {
1856 auto qosTxop =
1857 CreateObjectWithAttributes<QosTxop>("AcIndex", StringValue(std::string("AC_") + ac));
1858 mac.Set(ac + "_Txop", PointerValue(qosTxop));
1859 }
1860 auto apMac = mac.Create<WifiMac>();
1861 apMac->SetDevice(apDev);
1862 apMac->SetAddress(Mac48Address::Allocate());
1863 apDev->SetMac(apMac);
1864 apMac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
1865 apMac->SetFrameExchangeManagers({CreateObject<HeFrameExchangeManager>()});
1866 apMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
1867 Ptr<FrameExchangeManager> fem = apMac->GetFrameExchangeManager();
1868 fem->SetAddress(apMac->GetAddress());
1870 protectionManager->SetWifiMac(apMac);
1871 fem->SetProtectionManager(protectionManager);
1873 ackManager->SetWifiMac(apMac);
1874 fem->SetAckManager(ackManager);
1875
1876 Ptr<Node> staNode = CreateObject<Node>();
1878 staNode->AddDevice(staDev);
1879 staDev->SetStandard(WIFI_STANDARD_80211ax);
1881 staDev->SetHtConfiguration(staHtConfiguration);
1882 staDev->SetRemoteStationManager(manager.Create<WifiRemoteStationManager>());
1883
1885 staMobility->SetPosition(Vector(1.0, 0.0, 0.0));
1886 staNode->AggregateObject(staMobility);
1887
1889 staDev->SetPhy(m_staPhy);
1891 m_staPhy->SetInterferenceHelper(staInterferenceHelper);
1893 m_staPhy->SetChannel(channel);
1894 m_staPhy->SetMobility(staMobility);
1895 m_staPhy->SetDevice(apDev);
1898
1899 mac.SetTypeId("ns3::StaWifiMac");
1900 for (const std::string ac : {"BE", "BK", "VI", "VO"})
1901 {
1902 auto qosTxop =
1903 CreateObjectWithAttributes<QosTxop>("AcIndex", StringValue(std::string("AC_") + ac));
1904 mac.Set(ac + "_Txop", PointerValue(qosTxop));
1905 }
1906 auto staMac = mac.Create<WifiMac>();
1907 staDev->SetMac(staMac);
1908 staMac->SetDevice(staDev);
1909 staMac->SetAddress(Mac48Address::Allocate());
1910 staMac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
1911 staMac->SetFrameExchangeManagers({CreateObject<HeFrameExchangeManager>()});
1913 staMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
1914 fem = staMac->GetFrameExchangeManager();
1915 fem->SetAddress(staMac->GetAddress());
1916 protectionManager = CreateObject<WifiDefaultProtectionManager>();
1917 protectionManager->SetWifiMac(staMac);
1918 fem->SetProtectionManager(protectionManager);
1920 ackManager->SetWifiMac(staMac);
1921 fem->SetAckManager(ackManager);
1922
1923 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxBegin",
1925
1927
1931
1932 NS_TEST_ASSERT_MSG_EQ(m_assocReqCount, 2, "Second Association request not received");
1933 NS_TEST_ASSERT_MSG_EQ(m_assocRespCount, 2, "Second Association response not received");
1935 10,
1936 "Incorrect operational channel width before channel change");
1938 20,
1939 "Incorrect operational channel width after channel change");
1940}
1941
1942//-----------------------------------------------------------------------------
1943/**
1944 * Make sure that Wifi STA is correctly associating to the best AP (i.e.,
1945 * nearest from STA). We consider 3 AP and 1 STA. This test case consisted of
1946 * three sub tests:
1947 * - The best AP sends its beacon later than the other APs. STA is expected
1948 * to associate to the best AP.
1949 * - The STA is using active scanning instead of passive, the rest of the
1950 * APs works normally. STA is expected to associate to the best AP
1951 * - The nearest AP is turned off after sending beacon and while STA is
1952 * still scanning. STA is expected to associate to the second best AP.
1953 *
1954 * See \bugid{2399}
1955 * \todo Add explicit association refusal test if ns-3 implemented it.
1956 */
1957
1959{
1960 public:
1962 ~StaWifiMacScanningTestCase() override;
1963 void DoRun() override;
1964
1965 private:
1966 /**
1967 * Callback function on STA assoc event
1968 * \param context context string
1969 * \param bssid the associated AP's bssid
1970 */
1971 void AssocCallback(std::string context, Mac48Address bssid);
1972 /**
1973 * Turn beacon generation on the AP node
1974 * \param apNode the AP node
1975 */
1976 void TurnBeaconGenerationOn(Ptr<Node> apNode);
1977 /**
1978 * Turn the AP node off
1979 * \param apNode the AP node
1980 */
1981 void TurnApOff(Ptr<Node> apNode);
1982 /**
1983 * Setup test
1984 * \param nearestApBeaconGeneration set BeaconGeneration attribute of the nearest AP
1985 * \param staActiveProbe set ActiveProbing attribute of the STA
1986 * \return node container containing all nodes
1987 */
1988 NodeContainer Setup(bool nearestApBeaconGeneration, bool staActiveProbe);
1989
1990 Mac48Address m_associatedApBssid; ///< Associated AP's bssid
1991};
1992
1994 : TestCase("Test case for StaWifiMac scanning capability")
1995{
1996}
1997
2001
2002void
2004{
2005 m_associatedApBssid = bssid;
2006}
2007
2008void
2010{
2011 Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice>(apNode->GetDevice(0));
2012 Ptr<ApWifiMac> mac = DynamicCast<ApWifiMac>(netDevice->GetMac());
2013 mac->SetAttribute("BeaconGeneration", BooleanValue(true));
2014}
2015
2016void
2018{
2019 Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice>(apNode->GetDevice(0));
2020 Ptr<WifiPhy> phy = netDevice->GetPhy();
2021 phy->SetOffMode();
2022}
2023
2025StaWifiMacScanningTestCase::Setup(bool nearestApBeaconGeneration, bool staActiveProbe)
2026{
2029 int64_t streamNumber = 1;
2030
2031 NodeContainer apNodes;
2032 apNodes.Create(2);
2033
2034 Ptr<Node> apNodeNearest = CreateObject<Node>();
2035 Ptr<Node> staNode = CreateObject<Node>();
2036
2039 phy.SetChannel(channel.Create());
2040
2041 WifiHelper wifi;
2042 wifi.SetStandard(WIFI_STANDARD_80211n);
2043 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager");
2044
2045 WifiMacHelper mac;
2046 NetDeviceContainer apDevice;
2047 NetDeviceContainer apDeviceNearest;
2048 mac.SetType("ns3::ApWifiMac", "BeaconGeneration", BooleanValue(true));
2049 apDevice = wifi.Install(phy, mac, apNodes);
2050 mac.SetType("ns3::ApWifiMac", "BeaconGeneration", BooleanValue(nearestApBeaconGeneration));
2051 apDeviceNearest = wifi.Install(phy, mac, apNodeNearest);
2052
2053 NetDeviceContainer staDevice;
2054 mac.SetType("ns3::StaWifiMac", "ActiveProbing", BooleanValue(staActiveProbe));
2055 staDevice = wifi.Install(phy, mac, staNode);
2056
2057 // Assign fixed streams to random variables in use
2058 WifiHelper::AssignStreams(apDevice, streamNumber);
2059 WifiHelper::AssignStreams(apDeviceNearest, streamNumber + 1);
2060 WifiHelper::AssignStreams(staDevice, streamNumber + 2);
2061
2062 MobilityHelper mobility;
2064 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Furthest AP
2065 positionAlloc->Add(Vector(10.0, 0.0, 0.0)); // Second nearest AP
2066 positionAlloc->Add(Vector(5.0, 5.0, 0.0)); // Nearest AP
2067 positionAlloc->Add(Vector(6.0, 5.0, 0.0)); // STA
2068 mobility.SetPositionAllocator(positionAlloc);
2069
2070 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2071 mobility.Install(apNodes);
2072 mobility.Install(apNodeNearest);
2073 mobility.Install(staNode);
2074
2075 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/Assoc",
2077
2078 NodeContainer allNodes = NodeContainer(apNodes, apNodeNearest, staNode);
2079 return allNodes;
2080}
2081
2082void
2084{
2085 {
2086 NodeContainer nodes = Setup(false, false);
2087 Ptr<Node> nearestAp = nodes.Get(2);
2088 Mac48Address nearestApAddr =
2089 DynamicCast<WifiNetDevice>(nearestAp->GetDevice(0))->GetMac()->GetAddress();
2090
2093 this,
2094 nearestAp);
2095
2099
2101 nearestApAddr,
2102 "STA is associated to the wrong AP");
2103 }
2105 {
2106 NodeContainer nodes = Setup(true, true);
2107 Ptr<Node> nearestAp = nodes.Get(2);
2108 Mac48Address nearestApAddr =
2109 DynamicCast<WifiNetDevice>(nearestAp->GetDevice(0))->GetMac()->GetAddress();
2110
2114
2116 nearestApAddr,
2117 "STA is associated to the wrong AP");
2118 }
2120 {
2121 NodeContainer nodes = Setup(true, false);
2122 Ptr<Node> nearestAp = nodes.Get(2);
2123 Mac48Address secondNearestApAddr =
2124 DynamicCast<WifiNetDevice>(nodes.Get(1)->GetDevice(0))->GetMac()->GetAddress();
2125
2127
2131
2133 secondNearestApAddr,
2134 "STA is associated to the wrong AP");
2135 }
2136}
2137
2138//-----------------------------------------------------------------------------
2139/**
2140 * Make sure that the ADDBA handshake process is protected.
2141 *
2142 * The scenario considers an access point and a station. It utilizes
2143 * ReceiveListErrorModel to drop by force ADDBA request on STA or ADDBA
2144 * response on AP. The AP sends 5 packets of each 1000 bytes (thus generating
2145 * BA agreement), 2 times during the test at 0.5s and 0.8s. We only drop the
2146 * first ADDBA request/response of the first BA negotiation. Therefore, we
2147 * expect that the packets still in queue after the failed BA agreement will be
2148 * sent with normal MPDU, and packets queued after that should be sent with
2149 * A-MPDU.
2150 *
2151 * This test consider 2 cases:
2152 *
2153 * 1. ADDBA request packets are blocked on receive at STA, triggering
2154 * transmission failure at AP
2155 * 2. ADDBA response packets are blocked on receive at AP, STA stops
2156 * retransmission of ADDBA response
2157 *
2158 * See \bugid{2470}
2159 */
2160
2162{
2163 public:
2165 ~Bug2470TestCase() override;
2166 void DoRun() override;
2167
2168 private:
2169 /**
2170 * Callback when ADDBA state changed
2171 * \param context node context
2172 * \param t the time the state changed
2173 * \param recipient the MAC address of the recipient
2174 * \param tid the TID
2175 * \param state the state
2176 */
2177 void AddbaStateChangedCallback(std::string context,
2178 Time t,
2179 Mac48Address recipient,
2180 uint8_t tid,
2182 /**
2183 * Callback when a frame is transmitted.
2184 * \param rxErrorModel the post reception error model on the receiver
2185 * \param context the context
2186 * \param psduMap the PSDU map
2187 * \param txVector the TX vector
2188 * \param txPowerW the tx power in Watts
2189 */
2190 void TxCallback(Ptr<ListErrorModel> rxErrorModel,
2191 std::string context,
2192 WifiConstPsduMap psduMap,
2193 WifiTxVector txVector,
2194 double txPowerW);
2195
2196 /**
2197 * Callback when packet is received
2198 * \param context node context
2199 * \param p the received packet
2200 * \param channelFreqMhz the channel frequency in MHz
2201 * \param txVector the TX vector
2202 * \param aMpdu the A-MPDU info
2203 * \param signalNoise the signal noise in dBm
2204 * \param staId the STA-ID
2205 */
2206 void RxCallback(std::string context,
2208 uint16_t channelFreqMhz,
2209 WifiTxVector txVector,
2210 MpduInfo aMpdu,
2211 SignalNoiseDbm signalNoise,
2212 uint16_t staId);
2213 /**
2214 * Callback when packet is dropped
2215 * \param context node context
2216 * \param p the failed packet
2217 * \param snr the SNR of the failed packet in linear scale
2218 */
2219 void RxErrorCallback(std::string context, Ptr<const Packet> p, double snr);
2220 /**
2221 * Triggers the arrival of a burst of 1000 Byte-long packets in the source device
2222 * \param numPackets number of packets in burst
2223 * \param sourceDevice pointer to the source NetDevice
2224 * \param destination address of the destination device
2225 */
2226 void SendPacketBurst(uint32_t numPackets,
2227 Ptr<NetDevice> sourceDevice,
2228 Address& destination) const;
2229 /**
2230 * Run subtest for this test suite
2231 * \param rcvErrorType type of station (STA or AP) to install the post reception error model on
2232 */
2233 void RunSubtest(TypeOfStation rcvErrorType);
2234
2235 uint16_t m_receivedNormalMpduCount; ///< Count received normal MPDU packets on STA
2236 uint16_t m_receivedAmpduCount; ///< Count received A-MPDU packets on STA
2237 uint16_t m_failedActionCount; ///< Count failed ADDBA request/response
2238 uint16_t m_addbaEstablishedCount; ///< Count number of times ADDBA state machine is in
2239 ///< established state
2240 uint16_t m_addbaPendingCount; ///< Count number of times ADDBA state machine is in pending state
2241 uint16_t
2242 m_addbaRejectedCount; ///< Count number of times ADDBA state machine is in rejected state
2243 uint16_t
2244 m_addbaNoReplyCount; ///< Count number of times ADDBA state machine is in no_reply state
2245 uint16_t m_addbaResetCount; ///< Count number of times ADDBA state machine is in reset state
2246};
2247
2249 : TestCase("Test case for Bug 2470"),
2250 m_receivedNormalMpduCount(0),
2251 m_receivedAmpduCount(0),
2252 m_failedActionCount(0),
2253 m_addbaEstablishedCount(0),
2254 m_addbaPendingCount(0),
2255 m_addbaRejectedCount(0),
2256 m_addbaNoReplyCount(0),
2257 m_addbaResetCount(0)
2258{
2259}
2260
2264
2265void
2267 Time t,
2268 Mac48Address recipient,
2269 uint8_t tid,
2271{
2272 switch (state)
2273 {
2276 break;
2279 break;
2282 break;
2285 break;
2288 break;
2289 }
2290}
2291
2292void
2294 std::string context,
2295 WifiConstPsduMap psduMap,
2296 WifiTxVector txVector,
2297 double txPowerW)
2298{
2299 auto psdu = psduMap.begin()->second;
2300
2301 // The sender is transmitting an ADDBA_REQUEST or ADDBA_RESPONSE frame. If this is
2302 // the first attempt at establishing a BA agreement (i.e., before the second set of packets
2303 // is generated), make the reception of the frame fail at the receiver.
2304 if (psdu->GetHeader(0).GetType() == WIFI_MAC_MGT_ACTION && Simulator::Now() < Seconds(0.8))
2305 {
2306 auto uid = psdu->GetPayload(0)->GetUid();
2307 rxErrorModel->SetList({uid});
2308 }
2309}
2310
2311void
2314 uint16_t channelFreqMhz,
2315 WifiTxVector txVector,
2316 MpduInfo aMpdu,
2317 SignalNoiseDbm signalNoise,
2318 uint16_t staId)
2319{
2320 Ptr<Packet> packet = p->Copy();
2321 if (aMpdu.type != MpduType::NORMAL_MPDU)
2322 {
2324 }
2325 else
2326 {
2327 WifiMacHeader hdr;
2328 packet->RemoveHeader(hdr);
2329 if (hdr.IsData())
2330 {
2332 }
2333 }
2334}
2335
2336void
2337Bug2470TestCase::RxErrorCallback(std::string context, Ptr<const Packet> p, double snr)
2338{
2339 Ptr<Packet> packet = p->Copy();
2340 WifiMacHeader hdr;
2341 packet->RemoveHeader(hdr);
2342 if (hdr.IsAction())
2343 {
2345 }
2346}
2347
2348void
2350 Ptr<NetDevice> sourceDevice,
2351 Address& destination) const
2352{
2353 for (uint32_t i = 0; i < numPackets; i++)
2354 {
2355 Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
2356 sourceDevice->Send(pkt, destination, 0);
2357 }
2358}
2359
2360void
2362{
2365 int64_t streamNumber = 200;
2366
2367 NodeContainer wifiApNode;
2368 NodeContainer wifiStaNode;
2369 wifiApNode.Create(1);
2370 wifiStaNode.Create(1);
2371
2374 phy.SetChannel(channel.Create());
2375
2376 WifiHelper wifi;
2377 wifi.SetStandard(WIFI_STANDARD_80211n);
2378 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
2379 "DataMode",
2380 StringValue("HtMcs7"),
2381 "ControlMode",
2382 StringValue("HtMcs7"));
2383
2384 WifiMacHelper mac;
2385 NetDeviceContainer apDevice;
2386 phy.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}"));
2387 mac.SetType("ns3::ApWifiMac", "EnableBeaconJitter", BooleanValue(false));
2388 apDevice = wifi.Install(phy, mac, wifiApNode);
2389
2390 NetDeviceContainer staDevice;
2391 mac.SetType("ns3::StaWifiMac");
2392 staDevice = wifi.Install(phy, mac, wifiStaNode);
2393
2394 // Assign fixed streams to random variables in use
2395 WifiHelper::AssignStreams(apDevice, streamNumber);
2396 WifiHelper::AssignStreams(staDevice, streamNumber);
2397
2398 MobilityHelper mobility;
2400 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2401 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
2402 mobility.SetPositionAllocator(positionAlloc);
2403
2404 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2405 mobility.Install(wifiApNode);
2406 mobility.Install(wifiStaNode);
2407
2408 auto rxErrorModel = CreateObject<ListErrorModel>();
2409 Ptr<WifiMac> wifiMac;
2410 switch (rcvErrorType)
2411 {
2412 case AP:
2413 wifiMac = DynamicCast<WifiNetDevice>(apDevice.Get(0))->GetMac();
2414 break;
2415 case STA:
2416 wifiMac = DynamicCast<WifiNetDevice>(staDevice.Get(0))->GetMac();
2417 break;
2418 default:
2419 NS_ABORT_MSG("Station type " << +rcvErrorType << " cannot be used here");
2420 }
2421 wifiMac->GetWifiPhy(0)->SetPostReceptionErrorModel(rxErrorModel);
2422
2424 "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/MonitorSnifferRx",
2426 Config::Connect("/NodeList/*/DeviceList/*/Phy/State/RxError",
2428 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/BE_Txop/"
2429 "BlockAckManager/AgreementState",
2431 Config::Connect("/NodeList/" + std::to_string(rcvErrorType == STA ? 0 /* AP */ : 1 /* STA */) +
2432 "/DeviceList/*/$ns3::WifiNetDevice/Phys/0/PhyTxPsduBegin",
2433 MakeCallback(&Bug2470TestCase::TxCallback, this).Bind(rxErrorModel));
2434
2437 this,
2438 1,
2439 apDevice.Get(0),
2440 staDevice.Get(0)->GetAddress());
2443 this,
2444 4,
2445 apDevice.Get(0),
2446 staDevice.Get(0)->GetAddress());
2449 this,
2450 1,
2451 apDevice.Get(0),
2452 staDevice.Get(0)->GetAddress());
2455 this,
2456 4,
2457 apDevice.Get(0),
2458 staDevice.Get(0)->GetAddress());
2459
2463}
2464
2465void
2467{
2468 {
2469 RunSubtest(STA);
2470 NS_TEST_ASSERT_MSG_EQ(m_failedActionCount, 7, "ADDBA request packets are not failed");
2471 // There are two sets of 5 packets to be transmitted. The first 5 packets should be sent by
2472 // normal MPDU because of failed ADDBA handshake. For the second set, the first packet
2473 // should be sent by normal MPDU, and the rest with A-MPDU. In total we expect to receive 6
2474 // normal MPDU packets and 4 A-MPDU packet.
2476 6,
2477 "Receiving incorrect number of normal MPDU packet on subtest 1");
2479 4,
2480 "Receiving incorrect number of A-MPDU packets on subtest 1");
2481
2483 1,
2484 "Incorrect number of times the ADDBA state machine was in "
2485 "established state on subtest 1");
2488 2,
2489 "Incorrect number of times the ADDBA state machine was in pending state on subtest 1");
2492 0,
2493 "Incorrect number of times the ADDBA state machine was in rejected state on subtest 1");
2496 1,
2497 "Incorrect number of times the ADDBA state machine was in no_reply state on subtest 1");
2500 1,
2501 "Incorrect number of times the ADDBA state machine was in reset state on subtest 1");
2502 }
2503
2512
2513 {
2514 RunSubtest(AP);
2515 NS_TEST_ASSERT_MSG_EQ(m_failedActionCount, 7, "ADDBA response packets are not failed");
2516 // Similar to subtest 1, we also expect to receive 6 normal MPDU packets and 4 A-MPDU
2517 // packets.
2519 6,
2520 "Receiving incorrect number of normal MPDU packet on subtest 2");
2522 4,
2523 "Receiving incorrect number of A-MPDU packet on subtest 2");
2524
2526 1,
2527 "Incorrect number of times the ADDBA state machine was in "
2528 "established state on subtest 2");
2531 2,
2532 "Incorrect number of times the ADDBA state machine was in pending state on subtest 2");
2535 0,
2536 "Incorrect number of times the ADDBA state machine was in rejected state on subtest 2");
2539 1,
2540 "Incorrect number of times the ADDBA state machine was in no_reply state on subtest 2");
2543 1,
2544 "Incorrect number of times the ADDBA state machine was in reset state on subtest 2");
2545 }
2546
2547 // TODO: In the second test set, it does not go to reset state since ADDBA response is received
2548 // after timeout (NO_REPLY) but before it does not enter RESET state. More tests should be
2549 // written to verify all possible scenarios.
2550}
2551
2552//-----------------------------------------------------------------------------
2553/**
2554 * Make sure that Ideal rate manager recovers when the station is moving away from the access point.
2555 *
2556 * The scenario considers an access point and a moving station.
2557 * Initially, the station is located at 1 meter from the access point.
2558 * After 1s, the station moves away from the access for 0.5s to
2559 * reach a point away of 50 meters from the access point.
2560 * The tests checks the Ideal rate manager is reset once it has
2561 * failed to transmit a data packet, so that the next data packets
2562 * can be successfully transmitted using a lower modulation.
2563 *
2564 * See \issueid{40}
2565 */
2566
2568{
2569 public:
2571 ~Issue40TestCase() override;
2572 void DoRun() override;
2573
2574 private:
2575 /**
2576 * Run one function
2577 * \param useAmpdu flag to indicate whether the test should be run with A-MPDU
2578 */
2579 void RunOne(bool useAmpdu);
2580
2581 /**
2582 * Callback when packet is successfully received
2583 * \param context node context
2584 * \param p the received packet
2585 */
2586 void RxSuccessCallback(std::string context, Ptr<const Packet> p);
2587 /**
2588 * Triggers the arrival of 1000 Byte-long packets in the source device
2589 * \param numPackets number of packets in burst
2590 * \param sourceDevice pointer to the source NetDevice
2591 * \param destination address of the destination device
2592 */
2593 void SendPackets(uint8_t numPackets, Ptr<NetDevice> sourceDevice, Address& destination);
2594 /**
2595 * Transmit final data failed function
2596 * \param context the context
2597 * \param address the MAC address
2598 */
2599 void TxFinalDataFailedCallback(std::string context, Mac48Address address);
2600
2601 uint16_t m_rxCount; ///< Count number of successfully received data packets
2602 uint16_t m_txCount; ///< Count number of transmitted data packets
2603 uint16_t
2604 m_txMacFinalDataFailedCount; ///< Count number of unsuccessfuly transmitted data packets
2605};
2606
2608 : TestCase("Test case for issue #40"),
2609 m_rxCount(0),
2610 m_txCount(0),
2611 m_txMacFinalDataFailedCount(0)
2612{
2613}
2614
2618
2619void
2621{
2622 m_rxCount++;
2623}
2624
2625void
2626Issue40TestCase::SendPackets(uint8_t numPackets, Ptr<NetDevice> sourceDevice, Address& destination)
2627{
2628 for (uint8_t i = 0; i < numPackets; i++)
2629 {
2630 Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
2631 sourceDevice->Send(pkt, destination, 0);
2632 m_txCount++;
2633 }
2634}
2635
2636void
2641
2642void
2644{
2645 m_rxCount = 0;
2646 m_txCount = 0;
2648
2651 int64_t streamNumber = 100;
2652
2653 NodeContainer wifiApNode;
2654 NodeContainer wifiStaNode;
2655 wifiApNode.Create(1);
2656 wifiStaNode.Create(1);
2657
2660 phy.SetChannel(channel.Create());
2661
2662 WifiHelper wifi;
2663 wifi.SetStandard(WIFI_STANDARD_80211ac);
2664 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
2665
2666 WifiMacHelper mac;
2667 NetDeviceContainer apDevice;
2668 mac.SetType("ns3::ApWifiMac");
2669 apDevice = wifi.Install(phy, mac, wifiApNode);
2670
2671 NetDeviceContainer staDevice;
2672 mac.SetType("ns3::StaWifiMac");
2673 staDevice = wifi.Install(phy, mac, wifiStaNode);
2674
2675 // Assign fixed streams to random variables in use
2676 WifiHelper::AssignStreams(apDevice, streamNumber);
2677 WifiHelper::AssignStreams(staDevice, streamNumber);
2678
2679 MobilityHelper mobility;
2681 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2682 positionAlloc->Add(Vector(10.0, 0.0, 0.0));
2683 mobility.SetPositionAllocator(positionAlloc);
2684
2685 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2686 mobility.Install(wifiApNode);
2687
2688 mobility.SetMobilityModel("ns3::WaypointMobilityModel");
2689 mobility.Install(wifiStaNode);
2690
2691 Config::Connect("/NodeList/*/DeviceList/*/RemoteStationManager/MacTxFinalDataFailed",
2693 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/MacRx",
2695
2696 Ptr<WaypointMobilityModel> staWaypointMobility =
2698 staWaypointMobility->AddWaypoint(Waypoint(Seconds(1.0), Vector(10.0, 0.0, 0.0)));
2699 staWaypointMobility->AddWaypoint(Waypoint(Seconds(1.5), Vector(50.0, 0.0, 0.0)));
2700
2701 if (useAmpdu)
2702 {
2703 // Disable use of BAR that are sent with the lowest modulation so that we can also reproduce
2704 // the problem with A-MPDU, i.e. the lack of feedback about SNR change
2705 Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice>(apDevice.Get(0));
2706 PointerValue ptr;
2707 ap_device->GetMac()->GetAttribute("BE_Txop", ptr);
2708 ptr.Get<QosTxop>()->SetAttribute("UseExplicitBarAfterMissedBlockAck", BooleanValue(false));
2709 }
2710
2711 // Transmit a first data packet before the station moves: it should be sent with a high
2712 // modulation and successfully received
2715 this,
2716 useAmpdu ? 2 : 1,
2717 apDevice.Get(0),
2718 staDevice.Get(0)->GetAddress());
2719
2720 // Transmit a second data packet once the station is away from the access point: it should be
2721 // sent with the same high modulation and be unsuccessfuly received
2724 this,
2725 useAmpdu ? 2 : 1,
2726 apDevice.Get(0),
2727 staDevice.Get(0)->GetAddress());
2728
2729 // Keep on transmitting data packets while the station is away from the access point: it should
2730 // be sent with a lower modulation and be successfully received
2733 this,
2734 useAmpdu ? 2 : 1,
2735 apDevice.Get(0),
2736 staDevice.Get(0)->GetAddress());
2739 this,
2740 useAmpdu ? 2 : 1,
2741 apDevice.Get(0),
2742 staDevice.Get(0)->GetAddress());
2745 this,
2746 useAmpdu ? 2 : 1,
2747 apDevice.Get(0),
2748 staDevice.Get(0)->GetAddress());
2751 this,
2752 useAmpdu ? 2 : 1,
2753 apDevice.Get(0),
2754 staDevice.Get(0)->GetAddress());
2757 this,
2758 useAmpdu ? 2 : 1,
2759 apDevice.Get(0),
2760 staDevice.Get(0)->GetAddress());
2761
2764
2766 (useAmpdu ? 14 : 7),
2767 "Incorrect number of transmitted packets");
2769 (useAmpdu ? 12 : 6),
2770 "Incorrect number of successfully received packets");
2771 NS_TEST_ASSERT_MSG_EQ(m_txMacFinalDataFailedCount, 1, "Incorrect number of dropped TX packets");
2772
2774}
2775
2776void
2778{
2779 // Test without A-MPDU
2780 RunOne(false);
2781
2782 // Test with A-MPDU
2783 RunOne(true);
2784}
2785
2786//-----------------------------------------------------------------------------
2787/**
2788 * Make sure that Ideal rate manager is able to handle non best-effort traffic.
2789 *
2790 * The scenario considers an access point and a fixed station.
2791 * The station first sends a best-effort packet to the access point,
2792 * for which Ideal rate manager should select a VHT rate. Then,
2793 * the station sends a non best-effort (voice) packet to the access point,
2794 * and since SNR is unchanged, the same VHT rate should be used.
2795 *
2796 * See \issueid{169}
2797 */
2798
2800{
2801 public:
2803 ~Issue169TestCase() override;
2804 void DoRun() override;
2805
2806 private:
2807 /**
2808 * Triggers the transmission of a 1000 Byte-long data packet from the source device
2809 * \param numPackets number of packets in burst
2810 * \param sourceDevice pointer to the source NetDevice
2811 * \param destination address of the destination device
2812 * \param priority the priority of the packets to send
2813 */
2814 void SendPackets(uint8_t numPackets,
2815 Ptr<NetDevice> sourceDevice,
2816 Address& destination,
2817 uint8_t priority);
2818
2819 /**
2820 * Callback that indicates a PSDU is being transmitted
2821 * \param context the context
2822 * \param psdus the PSDU map to transmit
2823 * \param txVector the TX vector
2824 * \param txPowerW the TX power (W)
2825 */
2826 void TxCallback(std::string context,
2827 WifiConstPsduMap psdus,
2828 WifiTxVector txVector,
2829 double txPowerW);
2830};
2831
2833 : TestCase("Test case for issue #169")
2834{
2835}
2836
2840
2841void
2843 Ptr<NetDevice> sourceDevice,
2844 Address& destination,
2845 uint8_t priority)
2846{
2847 SocketPriorityTag priorityTag;
2848 priorityTag.SetPriority(priority);
2849 for (uint8_t i = 0; i < numPackets; i++)
2850 {
2851 Ptr<Packet> packet = Create<Packet>(1000); // 1000 dummy bytes of data
2852 packet->AddPacketTag(priorityTag);
2853 sourceDevice->Send(packet, destination, 0);
2854 }
2855}
2856
2857void
2859 WifiConstPsduMap psdus,
2860 WifiTxVector txVector,
2861 double txPowerW)
2862{
2863 if (psdus.begin()->second->GetSize() >= 1000)
2864 {
2866 WifiModulationClass::WIFI_MOD_CLASS_VHT,
2867 "Ideal rate manager selected incorrect modulation class");
2868 }
2869}
2870
2871void
2873{
2876 int64_t streamNumber = 100;
2877
2878 NodeContainer wifiApNode;
2879 NodeContainer wifiStaNode;
2880 wifiApNode.Create(1);
2881 wifiStaNode.Create(1);
2882
2885 phy.SetChannel(channel.Create());
2886
2887 WifiHelper wifi;
2888 wifi.SetStandard(WIFI_STANDARD_80211ac);
2889 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
2890
2891 WifiMacHelper mac;
2892 NetDeviceContainer apDevice;
2893 mac.SetType("ns3::ApWifiMac");
2894 apDevice = wifi.Install(phy, mac, wifiApNode);
2895
2896 NetDeviceContainer staDevice;
2897 mac.SetType("ns3::StaWifiMac");
2898 staDevice = wifi.Install(phy, mac, wifiStaNode);
2899
2900 // Assign fixed streams to random variables in use
2901 WifiHelper::AssignStreams(apDevice, streamNumber);
2902 WifiHelper::AssignStreams(staDevice, streamNumber);
2903
2904 MobilityHelper mobility;
2906 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2907 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
2908 mobility.SetPositionAllocator(positionAlloc);
2909
2910 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2911 mobility.Install(wifiApNode);
2912 mobility.Install(wifiStaNode);
2913
2914 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
2916
2917 // Send best-effort packet (i.e. priority 0)
2920 this,
2921 1,
2922 apDevice.Get(0),
2923 staDevice.Get(0)->GetAddress(),
2924 0);
2925
2926 // Send non best-effort (voice) packet (i.e. priority 6)
2929 this,
2930 1,
2931 apDevice.Get(0),
2932 staDevice.Get(0)->GetAddress(),
2933 6);
2934
2937
2939}
2940
2941//-----------------------------------------------------------------------------
2942/**
2943 * Make sure that Ideal rate manager properly selects MCS based on the configured channel width.
2944 *
2945 * The scenario considers an access point and a fixed station.
2946 * The access point first sends a 80 MHz PPDU to the station,
2947 * for which Ideal rate manager should select VH-MCS 0 based
2948 * on the distance (no interference generated in this test). Then,
2949 * the access point sends a 20 MHz PPDU to the station,
2950 * which corresponds to a SNR 6 dB higher than previously, hence
2951 * VHT-MCS 2 should be selected. Finally, the access point sends a
2952 * 40 MHz PPDU to the station, which means corresponds to a SNR 3 dB
2953 * lower than previously, hence VHT-MCS 1 should be selected.
2954 */
2955
2957{
2958 public:
2961 void DoRun() override;
2962
2963 private:
2964 /**
2965 * Change the configured channel width for all nodes
2966 * \param channelWidth the channel width
2967 */
2968 void ChangeChannelWidth(MHz_u channelWidth);
2969
2970 /**
2971 * Triggers the transmission of a 1000 Byte-long data packet from the source device
2972 * \param sourceDevice pointer to the source NetDevice
2973 * \param destination address of the destination device
2974 */
2975 void SendPacket(Ptr<NetDevice> sourceDevice, Address& destination);
2976
2977 /**
2978 * Callback that indicates a PSDU is being transmitted
2979 * \param context the context
2980 * \param psduMap the PSDU map to transmit
2981 * \param txVector the TX vector
2982 * \param txPowerW the TX power (W)
2983 */
2984 void TxCallback(std::string context,
2985 WifiConstPsduMap psduMap,
2986 WifiTxVector txVector,
2987 double txPowerW);
2988
2989 /**
2990 * Check if the selected WifiMode is correct
2991 * \param expectedMode the expected WifiMode
2992 */
2993 void CheckLastSelectedMode(WifiMode expectedMode);
2994
2995 WifiMode m_txMode; ///< Store the last selected mode to send data packet
2996};
2997
2999 : TestCase("Test case for use of channel bonding with Ideal rate manager")
3000{
3001}
3002
3006
3007void
3009{
3010 Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelSettings",
3011 StringValue("{0, " + std::to_string(static_cast<uint16_t>(channelWidth)) +
3012 ", BAND_5GHZ, 0}"));
3013}
3014
3015void
3017{
3018 Ptr<Packet> packet = Create<Packet>(1000);
3019 sourceDevice->Send(packet, destination, 0);
3020}
3021
3022void
3024 WifiConstPsduMap psduMap,
3025 WifiTxVector txVector,
3026 double txPowerW)
3027{
3028 if (psduMap.begin()->second->GetSize() >= 1000)
3029 {
3030 m_txMode = txVector.GetMode();
3031 }
3032}
3033
3034void
3036{
3038 expectedMode,
3039 "Last selected WifiMode "
3040 << m_txMode << " does not match expected WifiMode " << expectedMode);
3041}
3042
3043void
3045{
3048 int64_t streamNumber = 100;
3049
3050 NodeContainer wifiApNode;
3051 NodeContainer wifiStaNode;
3052 wifiApNode.Create(1);
3053 wifiStaNode.Create(1);
3054
3057 phy.SetChannel(channel.Create());
3058
3059 WifiHelper wifi;
3060 wifi.SetStandard(WIFI_STANDARD_80211ac);
3061 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
3062
3063 WifiMacHelper mac;
3064 NetDeviceContainer apDevice;
3065 mac.SetType("ns3::ApWifiMac");
3066 apDevice = wifi.Install(phy, mac, wifiApNode);
3067
3068 NetDeviceContainer staDevice;
3069 mac.SetType("ns3::StaWifiMac");
3070 staDevice = wifi.Install(phy, mac, wifiStaNode);
3071
3072 // Assign fixed streams to random variables in use
3073 WifiHelper::AssignStreams(apDevice, streamNumber);
3074 WifiHelper::AssignStreams(staDevice, streamNumber);
3075
3076 MobilityHelper mobility;
3078 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
3079 positionAlloc->Add(Vector(50.0, 0.0, 0.0));
3080 mobility.SetPositionAllocator(positionAlloc);
3081
3082 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
3083 mobility.Install(wifiApNode);
3084 mobility.Install(wifiStaNode);
3085
3086 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
3088
3089 // Set channel width to 80 MHz & send packet
3092 this,
3093 80);
3096 this,
3097 apDevice.Get(0),
3098 staDevice.Get(0)->GetAddress());
3099 // Selected rate should be VHT-MCS 1
3102 this,
3104
3105 // Set channel width to 20 MHz & send packet
3108 this,
3109 20);
3112 this,
3113 apDevice.Get(0),
3114 staDevice.Get(0)->GetAddress());
3115 // Selected rate should be VHT-MCS 3 since SNR should be 6 dB higher than previously
3118 this,
3120
3121 // Set channel width to 40 MHz & send packet
3124 this,
3125 40);
3128 this,
3129 apDevice.Get(0),
3130 staDevice.Get(0)->GetAddress());
3131 // Selected rate should be VHT-MCS 2 since SNR should be 3 dB lower than previously
3134 this,
3136
3139
3141}
3142
3143//-----------------------------------------------------------------------------
3144/**
3145 * Test to validate that Ideal rate manager properly selects TXVECTOR in scenarios where MIMO is
3146 * used. The test consider both balanced and unbalanced MIMO settings, and verify ideal picks the
3147 * correct number of spatial streams and the correct MCS, taking into account potential diversity in
3148 * AWGN channels when the number of antenna at the receiver is higher than the number of spatial
3149 * streams used for the transmission.
3150 */
3151
3153{
3154 public:
3156 ~IdealRateManagerMimoTest() override;
3157 void DoRun() override;
3158
3159 private:
3160 /**
3161 * Change the configured MIMO settings for AP node
3162 * \param antennas the number of active antennas
3163 * \param maxStreams the maximum number of allowed spatial streams
3164 */
3165 void SetApMimoSettings(uint8_t antennas, uint8_t maxStreams);
3166 /**
3167 * Change the configured MIMO settings for STA node
3168 * \param antennas the number of active antennas
3169 * \param maxStreams the maximum number of allowed spatial streams
3170 */
3171 void SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams);
3172 /**
3173 * Triggers the transmission of a 1000 Byte-long data packet from the source device
3174 * \param sourceDevice pointer to the source NetDevice
3175 * \param destination address of the destination device
3176 */
3177 void SendPacket(Ptr<NetDevice> sourceDevice, Address& destination);
3178
3179 /**
3180 * Callback that indicates a PSDU is being transmitted
3181 * \param context the context
3182 * \param psdus the PSDU map to transmit
3183 * \param txVector the TX vector
3184 * \param txPowerW the TX power (W)
3185 */
3186 void TxCallback(std::string context,
3187 WifiConstPsduMap psdus,
3188 WifiTxVector txVector,
3189 double txPowerW);
3190
3191 /**
3192 * Check if the selected WifiMode is correct
3193 * \param expectedMode the expected WifiMode
3194 */
3195 void CheckLastSelectedMode(WifiMode expectedMode);
3196 /**
3197 * Check if the selected Nss is correct
3198 * \param expectedNss the expected Nss
3199 */
3200 void CheckLastSelectedNss(uint8_t expectedNss);
3201
3202 WifiTxVector m_txVector; ///< Store the last TXVECTOR used to transmit Data
3203};
3204
3206 : TestCase("Test case for use of imbalanced MIMO settings with Ideal rate manager")
3207{
3208}
3209
3213
3214void
3215IdealRateManagerMimoTest::SetApMimoSettings(uint8_t antennas, uint8_t maxStreams)
3216{
3217 Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/Antennas",
3218 UintegerValue(antennas));
3219 Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedTxSpatialStreams",
3220 UintegerValue(maxStreams));
3221 Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedRxSpatialStreams",
3222 UintegerValue(maxStreams));
3223}
3224
3225void
3226IdealRateManagerMimoTest::SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams)
3227{
3228 Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/Antennas",
3229 UintegerValue(antennas));
3230 Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedTxSpatialStreams",
3231 UintegerValue(maxStreams));
3232 Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedRxSpatialStreams",
3233 UintegerValue(maxStreams));
3234}
3235
3236void
3238{
3239 Ptr<Packet> packet = Create<Packet>(1000);
3240 sourceDevice->Send(packet, destination, 0);
3241}
3242
3243void
3245 WifiConstPsduMap psdus,
3246 WifiTxVector txVector,
3247 double txPowerW)
3248{
3249 if (psdus.begin()->second->GetSize() >= 1000)
3250 {
3251 m_txVector = txVector;
3252 }
3253}
3254
3255void
3257{
3259 expectedNss,
3260 "Last selected Nss " << m_txVector.GetNss()
3261 << " does not match expected Nss " << expectedNss);
3262}
3263
3264void
3266{
3268 expectedMode,
3269 "Last selected WifiMode " << m_txVector.GetMode()
3270 << " does not match expected WifiMode "
3271 << expectedMode);
3272}
3273
3274void
3276{
3279 int64_t streamNumber = 100;
3280
3281 NodeContainer wifiApNode;
3282 NodeContainer wifiStaNode;
3283 wifiApNode.Create(1);
3284 wifiStaNode.Create(1);
3285
3288 phy.SetChannel(channel.Create());
3289
3290 WifiHelper wifi;
3291 wifi.SetStandard(WIFI_STANDARD_80211ac);
3292 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
3293
3294 WifiMacHelper mac;
3295 NetDeviceContainer apDevice;
3296 mac.SetType("ns3::ApWifiMac");
3297 apDevice = wifi.Install(phy, mac, wifiApNode);
3298
3299 NetDeviceContainer staDevice;
3300 mac.SetType("ns3::StaWifiMac");
3301 staDevice = wifi.Install(phy, mac, wifiStaNode);
3302
3303 // Assign fixed streams to random variables in use
3304 WifiHelper::AssignStreams(apDevice, streamNumber);
3305 WifiHelper::AssignStreams(staDevice, streamNumber);
3306
3307 MobilityHelper mobility;
3309 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
3310 positionAlloc->Add(Vector(40.0, 0.0, 0.0));
3311 mobility.SetPositionAllocator(positionAlloc);
3312
3313 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
3314 mobility.Install(wifiApNode);
3315 mobility.Install(wifiStaNode);
3316
3317 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
3319
3320 // TX: 1 antenna
3322 // RX: 1 antenna
3324 // Send packets (2 times to get one feedback)
3327 this,
3328 apDevice.Get(0),
3329 staDevice.Get(0)->GetAddress());
3332 this,
3333 apDevice.Get(0),
3334 staDevice.Get(0)->GetAddress());
3335 // Selected NSS should be 1 since both TX and RX support a single antenna
3337 // Selected rate should be VHT-MCS 2 because of settings and distance between TX and RX
3340 this,
3342
3343 // TX: 1 antenna
3345 // RX: 2 antennas, but only supports 1 spatial stream
3347 // Send packets (2 times to get one feedback)
3350 this,
3351 apDevice.Get(0),
3352 staDevice.Get(0)->GetAddress());
3355 this,
3356 apDevice.Get(0),
3357 staDevice.Get(0)->GetAddress());
3358 // Selected NSS should be 1 since both TX and RX support a single antenna
3360 // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3361 // improvement of about 3dB
3364 this,
3366
3367 // TX: 1 antenna
3369 // RX: 2 antennas, and supports 2 spatial streams
3371 // Send packets (2 times to get one feedback)
3374 this,
3375 apDevice.Get(0),
3376 staDevice.Get(0)->GetAddress());
3379 this,
3380 apDevice.Get(0),
3381 staDevice.Get(0)->GetAddress());
3382 // Selected NSS should be 1 since TX supports a single antenna
3384 // Selected rate should be as previously
3387 this,
3389
3390 // TX: 2 antennas, but only supports 1 spatial stream
3392 // RX: 1 antenna
3394 // Send packets (2 times to get one feedback)
3397 this,
3398 apDevice.Get(0),
3399 staDevice.Get(0)->GetAddress());
3402 this,
3403 apDevice.Get(0),
3404 staDevice.Get(0)->GetAddress());
3405 // Selected NSS should be 1 since both TX and RX support a single antenna
3407 // Selected rate should be VHT-MCS 2 because we do no longer have diversity in this scenario
3408 // (more antennas at TX does not result in SNR improvement in AWGN channel)
3411 this,
3413
3414 // TX: 2 antennas, but only supports 1 spatial stream
3416 // RX: 2 antennas, but only supports 1 spatial stream
3418 // Send packets (2 times to get one feedback)
3421 this,
3422 apDevice.Get(0),
3423 staDevice.Get(0)->GetAddress());
3426 this,
3427 apDevice.Get(0),
3428 staDevice.Get(0)->GetAddress());
3429 // Selected NSS should be 1 since both TX and RX support a single antenna
3431 // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3432 // improvement of about 3dB (more antennas at TX does not result in SNR improvement in AWGN
3433 // channel)
3436 this,
3438
3439 // TX: 2 antennas, but only supports 1 spatial stream
3441 // RX: 2 antennas, and supports 2 spatial streams
3443 // Send packets (2 times to get one feedback)
3446 this,
3447 apDevice.Get(0),
3448 staDevice.Get(0)->GetAddress());
3451 this,
3452 apDevice.Get(0),
3453 staDevice.Get(0)->GetAddress());
3454 // Selected NSS should be 1 since TX supports a single antenna
3456 // Selected rate should be as previously
3459 this,
3461
3462 // TX: 2 antennas, and supports 2 spatial streams
3464 // RX: 1 antenna
3466 // Send packets (2 times to get one feedback)
3469 this,
3470 apDevice.Get(0),
3471 staDevice.Get(0)->GetAddress());
3474 this,
3475 apDevice.Get(0),
3476 staDevice.Get(0)->GetAddress());
3477 // Selected NSS should be 1 since RX supports a single antenna
3479 // Selected rate should be VHT-MCS 2 because we do no longer have diversity in this scenario
3480 // (more antennas at TX does not result in SNR improvement in AWGN channel)
3483 this,
3485
3486 // TX: 2 antennas, and supports 2 spatial streams
3488 // RX: 2 antennas, but only supports 1 spatial stream
3490 // Send packets (2 times to get one feedback)
3493 this,
3494 apDevice.Get(0),
3495 staDevice.Get(0)->GetAddress());
3498 this,
3499 apDevice.Get(0),
3500 staDevice.Get(0)->GetAddress());
3501 // Selected NSS should be 1 since RX supports a single antenna
3503 // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3504 // improvement of about 3dB (more antennas at TX does not result in SNR improvement in AWGN
3505 // channel)
3508 this,
3510
3511 // TX: 2 antennas, and supports 2 spatial streams
3513 // RX: 2 antennas, and supports 2 spatial streams
3515 // Send packets (2 times to get one feedback)
3518 this,
3519 apDevice.Get(0),
3520 staDevice.Get(0)->GetAddress());
3523 this,
3524 apDevice.Get(0),
3525 staDevice.Get(0)->GetAddress());
3526 // Selected NSS should be 2 since both TX and RX support 2 antennas
3528 // Selected rate should be the same as without diversity, as it uses 2 spatial streams so there
3529 // is no more benefits from diversity in AWGN channels
3532 this,
3534
3535 // Verify we can go back to initial situation
3540 this,
3541 apDevice.Get(0),
3542 staDevice.Get(0)->GetAddress());
3546 this,
3548
3549 Simulator::Stop(Seconds(10.2));
3552}
3553
3554//-----------------------------------------------------------------------------
3555/**
3556 * \ingroup wifi-test
3557 * \ingroup tests
3558 *
3559 * \brief Data rate verification test for MCSs of different RU sizes
3560 */
3562{
3563 public:
3565
3566 private:
3567 /**
3568 * Compare the data rate computed for the provided combination with standard defined one.
3569 * \param ruType the RU type
3570 * \param mcs the modulation and coding scheme (as a string, e.g. HeMcs0)
3571 * \param nss the number of spatial streams
3572 * \param guardInterval the guard interval to use
3573 * \param expectedDataRate the expected data rate in 100 kbps units (minimum granularity in
3574 * standard tables)
3575 * \returns true if data rates are the same, false otherwise
3576 */
3577 bool CheckDataRate(HeRu::RuType ruType,
3578 std::string mcs,
3579 uint8_t nss,
3580 Time guardInterval,
3581 uint16_t expectedDataRate);
3582 void DoRun() override;
3583};
3584
3586 : TestCase("Check data rates for different RU types.")
3587{
3588}
3589
3590bool
3592 std::string mcs,
3593 uint8_t nss,
3594 Time guardInterval,
3595 uint16_t expectedDataRate)
3596{
3597 uint8_t staId = 1;
3598 auto txVector = WifiTxVector(HePhy::GetHeMcs(0),
3599 0,
3601 guardInterval,
3602 1,
3603 1,
3604 0,
3605 160,
3606 false,
3607 false);
3608 WifiMode mode(mcs);
3609 txVector.SetMode(mode, staId);
3610 txVector.SetNss(nss, staId);
3611 HeRu::RuSpec ru(ruType, 1, true);
3612 txVector.SetRu(ru, staId);
3613 uint64_t dataRate = round(mode.GetDataRate(txVector, staId) / 100000.0);
3614 NS_ABORT_MSG_IF(dataRate > 65535, "Rate is way too high");
3615 if (static_cast<uint16_t>(dataRate) != expectedDataRate)
3616 {
3617 std::cerr << "RU=" << ruType << " mode=" << mode << " Nss=" << +nss
3618 << " guardInterval=" << guardInterval << " expected=" << expectedDataRate
3619 << " x100kbps"
3620 << " computed=" << static_cast<uint16_t>(dataRate) << " x100kbps" << std::endl;
3621 return false;
3622 }
3623 return true;
3624}
3625
3626void
3628{
3629 bool retval = true;
3630
3631 // 26-tone RU, browse over all MCSs, GIs and Nss's (up to 4, current max)
3632 retval = retval && CheckDataRate(HeRu::RU_26_TONE, "HeMcs0", 1, NanoSeconds(800), 9) &&
3633 CheckDataRate(HeRu::RU_26_TONE, "HeMcs1", 1, NanoSeconds(1600), 17) &&
3634 CheckDataRate(HeRu::RU_26_TONE, "HeMcs2", 1, NanoSeconds(3200), 23) &&
3635 CheckDataRate(HeRu::RU_26_TONE, "HeMcs3", 1, NanoSeconds(3200), 30) &&
3636 CheckDataRate(HeRu::RU_26_TONE, "HeMcs4", 2, NanoSeconds(1600), 100) &&
3637 CheckDataRate(HeRu::RU_26_TONE, "HeMcs5", 3, NanoSeconds(1600), 200) &&
3638 CheckDataRate(HeRu::RU_26_TONE, "HeMcs6", 4, NanoSeconds(1600), 300) &&
3639 CheckDataRate(HeRu::RU_26_TONE, "HeMcs7", 4, NanoSeconds(3200), 300) &&
3640 CheckDataRate(HeRu::RU_26_TONE, "HeMcs8", 4, NanoSeconds(1600), 400) &&
3641 CheckDataRate(HeRu::RU_26_TONE, "HeMcs9", 4, NanoSeconds(3200), 400) &&
3642 CheckDataRate(HeRu::RU_26_TONE, "HeMcs10", 4, NanoSeconds(1600), 500) &&
3643 CheckDataRate(HeRu::RU_26_TONE, "HeMcs11", 4, NanoSeconds(3200), 500);
3644
3646 retval,
3647 true,
3648 "26-tone RU data rate verification for different MCSs, GIs, and Nss's failed");
3649
3650 // Check other RU sizes
3651 retval = retval && CheckDataRate(HeRu::RU_52_TONE, "HeMcs2", 1, NanoSeconds(1600), 50) &&
3652 CheckDataRate(HeRu::RU_106_TONE, "HeMcs9", 1, NanoSeconds(800), 500) &&
3653 CheckDataRate(HeRu::RU_242_TONE, "HeMcs5", 1, NanoSeconds(1600), 650) &&
3654 CheckDataRate(HeRu::RU_484_TONE, "HeMcs3", 1, NanoSeconds(1600), 650) &&
3655 CheckDataRate(HeRu::RU_996_TONE, "HeMcs5", 1, NanoSeconds(3200), 2450) &&
3656 CheckDataRate(HeRu::RU_2x996_TONE, "HeMcs3", 1, NanoSeconds(3200), 2450);
3657
3658 NS_TEST_EXPECT_MSG_EQ(retval,
3659 true,
3660 "Data rate verification for RUs above 52-tone RU (included) failed");
3661}
3662
3663/// List of Information Elements included in the test management frame
3665 std::tuple<SupportedRates, std::optional<ExtendedSupportedRatesIE>, std::vector<Ssid>>;
3666
3667/**
3668 * \ingroup wifi-test
3669 * \ingroup tests
3670 *
3671 * \brief Test management header
3672 */
3673class MgtTestHeader : public WifiMgtHeader<MgtTestHeader, MgtTestElems>
3674{
3675 public:
3676 ~MgtTestHeader() override = default;
3677
3678 /**
3679 * Register this type.
3680 * \return The TypeId.
3681 */
3682 static TypeId GetTypeId();
3683
3684 /**
3685 * \return the TypeId for this object.
3686 */
3687 TypeId GetInstanceTypeId() const override;
3688
3689 using WifiMgtHeader<MgtTestHeader, MgtTestElems>::GetSerializedSize;
3690 using WifiMgtHeader<MgtTestHeader, MgtTestElems>::Serialize;
3691 using WifiMgtHeader<MgtTestHeader, MgtTestElems>::Deserialize;
3692};
3693
3694TypeId
3696{
3697 static TypeId tid = TypeId("ns3::MgtTestHeader")
3698 .SetParent<Header>()
3699 .SetGroupName("Wifi")
3700 .AddConstructor<MgtTestHeader>();
3701 return tid;
3702}
3703
3704TypeId
3706{
3707 return GetTypeId();
3708}
3709
3710/**
3711 * \ingroup wifi-test
3712 * \ingroup tests
3713 *
3714 * \brief Mgt header (de)serialization Test Suite
3715 */
3717{
3718 public:
3720 ~WifiMgtHeaderTest() override = default;
3721
3722 private:
3723 void DoRun() override;
3724};
3725
3727 : HeaderSerializationTestCase("Check (de)serialization of a test management header")
3728{
3729}
3730
3731void
3733{
3734 MgtTestHeader frame;
3735
3736 // Add the mandatory Information Element (SupportedRates)
3737 AllSupportedRates allRates;
3738 allRates.AddSupportedRate(1000000);
3739 allRates.AddSupportedRate(2000000);
3740 allRates.AddSupportedRate(3000000);
3741 allRates.AddSupportedRate(4000000);
3742 allRates.AddSupportedRate(5000000);
3743
3744 frame.Get<SupportedRates>() = allRates.rates;
3745 frame.Get<ExtendedSupportedRatesIE>() = allRates.extendedRates;
3746
3747 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3748 true,
3749 "Expected a SupportedRates IE to be included");
3750 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3751 false,
3752 "Expected no ExtendedSupportedRatesIE to be included");
3753 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 0, "Expected no Ssid IE to be included");
3754
3756
3757 // Add more rates, so that the optional Information Element (ExtendedSupportedRatesIE) is added
3758 allRates.AddSupportedRate(6000000);
3759 allRates.AddSupportedRate(7000000);
3760 allRates.AddSupportedRate(8000000);
3761 allRates.AddSupportedRate(9000000);
3762 allRates.AddSupportedRate(10000000);
3763
3764 frame.Get<SupportedRates>() = allRates.rates;
3765 frame.Get<ExtendedSupportedRatesIE>() = allRates.extendedRates;
3766
3767 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3768 true,
3769 "Expected a SupportedRates IE to be included");
3770 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3771 true,
3772 "Expected an ExtendedSupportedRatesIE to be included");
3773 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 0, "Expected no Ssid IE to be included");
3774
3776
3777 // Add a first Ssid IE
3778 Ssid one("Ssid One");
3779 frame.Get<Ssid>().push_back(one);
3780
3781 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3782 true,
3783 "Expected a SupportedRates IE to be included");
3784 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3785 true,
3786 "Expected an ExtendedSupportedRatesIE to be included");
3787 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 1, "Expected one Ssid IE to be included");
3788 NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().front().PeekString()),
3789 "Ssid One",
3790 "Incorrect SSID");
3791
3793
3794 // Add a second Ssid IE
3795 frame.Get<Ssid>().emplace_back("Ssid Two");
3796
3797 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3798 true,
3799 "Expected a SupportedRates IE to be included");
3800 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3801 true,
3802 "Expected an ExtendedSupportedRatesIE to be included");
3803 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 2, "Expected two Ssid IEs to be included");
3804 NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().front().PeekString()),
3805 "Ssid One",
3806 "Incorrect first SSID");
3807 NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().back().PeekString()),
3808 "Ssid Two",
3809 "Incorrect second SSID");
3810
3812}
3813
3814//-----------------------------------------------------------------------------
3815
3816/**
3817 * Make sure that all DSSS modulation types work (see issue #1095).
3818 *
3819 * This test sends four packets from a STA to an AP, each with a different
3820 * DSSS rate (1, 2, 5.5, and 11Mbps), and checks that all four are received.
3821 */
3823{
3824 public:
3826
3827 void DoRun() override;
3828
3829 private:
3830 uint32_t m_received; ///< number of received packets
3831
3832 /**
3833 * Trace sink to receive from the PacketSocket; the address parameter is unused
3834 * \param context the context
3835 * \param p the received packet
3836 */
3837 void Receive(std::string context, Ptr<const Packet> p, const Address&);
3838};
3839
3841 : TestCase("Test case for Bug 730"),
3842 m_received(0)
3843{
3844}
3845
3846void
3848{
3849 m_received++;
3850}
3851
3852void
3854{
3855 m_received = 0;
3856
3857 NodeContainer wifiStaNode;
3858 wifiStaNode.Create(1);
3859
3860 NodeContainer wifiApNode;
3861 wifiApNode.Create(1);
3862
3863 auto channel = YansWifiChannelHelper::Default();
3865 phy.SetChannel(channel.Create());
3866
3867 WifiHelper wifi;
3868 wifi.SetStandard(WIFI_STANDARD_80211b);
3869 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
3870 "DataMode",
3871 StringValue("DsssRate1Mbps"),
3872 "ControlMode",
3873 StringValue("DsssRate1Mbps"));
3874
3875 WifiMacHelper mac;
3876 auto ssid = Ssid("ns-3-ssid");
3877 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid), "ActiveProbing", BooleanValue(false));
3878
3879 NetDeviceContainer staDevices;
3880 staDevices = wifi.Install(phy, mac, wifiStaNode);
3881
3882 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid), "BeaconGeneration", BooleanValue(true));
3883
3884 NetDeviceContainer apDevices;
3885 apDevices = wifi.Install(phy, mac, wifiApNode);
3886 auto apRemoteStationManager = apDevices.Get(0)
3887 ->GetObject<WifiNetDevice>()
3888 ->GetRemoteStationManager()
3890 apRemoteStationManager->SetAttribute("DataMode", StringValue("DsssRate1Mbps"));
3891
3892 MobilityHelper mobility;
3893 auto positionAlloc = CreateObject<ListPositionAllocator>();
3894
3895 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
3896 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
3897 mobility.SetPositionAllocator(positionAlloc);
3898
3899 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
3900 mobility.Install(wifiApNode);
3901 mobility.Install(wifiStaNode);
3902
3903 auto apDevice = DynamicCast<WifiNetDevice>(apDevices.Get(0));
3904 auto staDevice = DynamicCast<WifiNetDevice>(staDevices.Get(0));
3905
3906 PacketSocketAddress socket;
3907 socket.SetSingleDevice(staDevice->GetIfIndex());
3908 socket.SetPhysicalAddress(apDevice->GetAddress());
3909 socket.SetProtocol(1);
3910
3911 // give packet socket powers to nodes.
3912 PacketSocketHelper packetSocket;
3913 packetSocket.Install(wifiStaNode);
3914 packetSocket.Install(wifiApNode);
3915
3916 auto client = CreateObject<PacketSocketClient>();
3917 client->SetAttribute("PacketSize", UintegerValue(1460));
3918 client->SetAttribute("MaxPackets", UintegerValue(4));
3919 client->SetRemote(socket);
3920 wifiStaNode.Get(0)->AddApplication(client);
3921 client->SetStartTime(Seconds(1));
3922 client->SetStopTime(Seconds(4.5));
3923
3924 auto server = CreateObject<PacketSocketServer>();
3925 server->SetLocal(socket);
3926 wifiApNode.Get(0)->AddApplication(server);
3927 server->SetStartTime(Seconds(0));
3928 server->SetStopTime(Seconds(4.5));
3929
3930 Config::Connect("/NodeList/1/ApplicationList/0/$ns3::PacketSocketServer/Rx",
3932
3933 // The PacketSocketClient starts at time 1s, and packets are sent at times 1s, 2s, 3s, 4s.
3934 // Change the MCS in between these send times (e.g., at 1.5s, 2.5s, 3.5s)
3936 Seconds(1.5),
3938 "/NodeList/0/DeviceList/0/RemoteStationManager/$ns3::ConstantRateWifiManager/DataMode",
3939 StringValue("DsssRate2Mbps"));
3941 Seconds(2.5),
3943 "/NodeList/0/DeviceList/0/RemoteStationManager/$ns3::ConstantRateWifiManager/DataMode",
3944 StringValue("DsssRate5_5Mbps"));
3946 Seconds(3.5),
3948 "/NodeList/0/DeviceList/0/RemoteStationManager/$ns3::ConstantRateWifiManager/DataMode",
3949 StringValue("DsssRate11Mbps"));
3950
3953
3955
3956 NS_TEST_ASSERT_MSG_EQ(m_received, 4, "Did not receive four DSSS packets");
3957}
3958
3959/**
3960 * \ingroup wifi-test
3961 * \ingroup tests
3962 *
3963 * \brief Wifi Test Suite
3964 */
3966{
3967 public:
3968 WifiTestSuite();
3969};
3970
3972 : TestSuite("wifi-devices", Type::UNIT)
3973{
3974 AddTestCase(new WifiTest, TestCase::Duration::QUICK);
3975 AddTestCase(new QosUtilsIsOldPacketTest, TestCase::Duration::QUICK);
3976 AddTestCase(new InterferenceHelperSequenceTest, TestCase::Duration::QUICK); // Bug 991
3977 AddTestCase(new DcfImmediateAccessBroadcastTestCase, TestCase::Duration::QUICK);
3978 AddTestCase(new Bug730TestCase, TestCase::Duration::QUICK); // Bug 730
3979 AddTestCase(new QosFragmentationTestCase, TestCase::Duration::QUICK);
3980 AddTestCase(new SetChannelFrequencyTest, TestCase::Duration::QUICK);
3981 AddTestCase(new Bug2222TestCase, TestCase::Duration::QUICK); // Bug 2222
3982 AddTestCase(new Bug2843TestCase, TestCase::Duration::QUICK); // Bug 2843
3983 AddTestCase(new Bug2831TestCase, TestCase::Duration::QUICK); // Bug 2831
3984 AddTestCase(new StaWifiMacScanningTestCase, TestCase::Duration::QUICK); // Bug 2399
3985 AddTestCase(new Bug2470TestCase, TestCase::Duration::QUICK); // Bug 2470
3986 AddTestCase(new Issue40TestCase, TestCase::Duration::QUICK); // Issue #40
3987 AddTestCase(new Issue169TestCase, TestCase::Duration::QUICK); // Issue #169
3988 AddTestCase(new IdealRateManagerChannelWidthTest, TestCase::Duration::QUICK);
3989 AddTestCase(new IdealRateManagerMimoTest, TestCase::Duration::QUICK);
3990 AddTestCase(new HeRuMcsDataRateTestCase, TestCase::Duration::QUICK);
3991 AddTestCase(new WifiMgtHeaderTest, TestCase::Duration::QUICK);
3992 AddTestCase(new DsssModulationTest, TestCase::Duration::QUICK);
3993}
3994
3995static WifiTestSuite g_wifiTestSuite; ///< the test suite
Make sure that when virtual collision occurs the wifi remote station manager is triggered and the ret...
~Bug2222TestCase() override
uint32_t m_countInternalCollisions
count internal collisions
void DoRun() override
Implementation to actually run this TestCase.
void TxDataFailedTrace(std::string context, Mac48Address adr)
Transmit data failed function.
Make sure that the ADDBA handshake process is protected.
void RxErrorCallback(std::string context, Ptr< const Packet > p, double snr)
Callback when packet is dropped.
void RunSubtest(TypeOfStation rcvErrorType)
Run subtest for this test suite.
void DoRun() override
Implementation to actually run this TestCase.
uint16_t m_addbaResetCount
Count number of times ADDBA state machine is in reset state.
uint16_t m_addbaRejectedCount
Count number of times ADDBA state machine is in rejected state.
void AddbaStateChangedCallback(std::string context, Time t, Mac48Address recipient, uint8_t tid, OriginatorBlockAckAgreement::State state)
Callback when ADDBA state changed.
uint16_t m_failedActionCount
Count failed ADDBA request/response.
void TxCallback(Ptr< ListErrorModel > rxErrorModel, std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback when a frame is transmitted.
uint16_t m_addbaEstablishedCount
Count number of times ADDBA state machine is in established state.
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.
~Bug2470TestCase() override
uint16_t m_receivedNormalMpduCount
Count received normal MPDU packets on STA.
uint16_t m_addbaNoReplyCount
Count number of times ADDBA state machine is in no_reply state.
uint16_t m_addbaPendingCount
Count number of times ADDBA state machine is in pending state.
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.
uint16_t m_receivedAmpduCount
Count received A-MPDU packets on STA.
Make sure that the channel width and the channel number can be changed at runtime.
uint16_t m_countOperationalChannelWidth20
count number of beacon frames announcing a 20 MHz operating channel width
void ChangeSupportedChannelWidth()
Function called to change the supported channel width at runtime.
uint16_t m_countOperationalChannelWidth40
count number of beacon frames announcing a 40 MHz operating channel width
void RxCallback(std::string context, Ptr< const Packet > p, RxPowerWattPerChannelBand rxPowersW)
Callback triggered when a packet is received by the PHYs.
uint16_t m_assocReqCount
count number of association requests
Ptr< YansWifiPhy > m_apPhy
AP PHY.
void DoRun() override
Implementation to actually run this TestCase.
Ptr< YansWifiPhy > m_staPhy
STA PHY.
uint16_t m_assocRespCount
count number of association responses
~Bug2831TestCase() override
Make sure that the correct channel width and center frequency have been set for OFDM basic rate trans...
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.
void StoreDistinctTuple(std::string context, Ptr< SpectrumSignalParameters > txParams)
Stores the distinct {starting frequency, channelWidth, Number of subbands in SpectrumModel,...
std::vector< FreqWidthSubbandModulationTuple > m_distinctTuples
vector of distinct {starting frequency, channelWidth, Number of subbands in SpectrumModel,...
void DoRun() override
Implementation to actually run this TestCase.
MHz_u m_channelWidth
channel width
std::tuple< Hz_u, MHz_u, uint32_t, WifiModulationClass > FreqWidthSubbandModulationTuple
A tuple of {starting frequency, channelWidth, Number of subbands in SpectrumModel,...
~Bug2843TestCase() override
Make sure that when changing the fragmentation threshold during the simulation, the TCP transmission ...
Definition wifi-test.cc:647
~Bug730TestCase() override
Definition wifi-test.cc:672
void Receive(std::string context, Ptr< const Packet > p, const Address &adr)
Receive function.
Definition wifi-test.cc:677
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:686
uint32_t m_received
received
Definition wifi-test.cc:655
Make sure that when multiple broadcast packets are queued on the same device in a short succession,...
Definition wifi-test.cc:475
void NotifyPhyTxBegin(Ptr< const Packet > p, double txPowerW)
Notify Phy transmit begin.
Definition wifi-test.cc:510
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:531
ObjectFactory m_propDelay
propagation delay
Definition wifi-test.cc:490
unsigned int m_numSentPackets
number of sent packets
Definition wifi-test.cc:494
Time m_secondTransmissionTime
second transmission time
Definition wifi-test.cc:493
Time m_firstTransmissionTime
first transmission time
Definition wifi-test.cc:492
void SendOnePacket(Ptr< WifiNetDevice > dev)
Send one packet function.
Definition wifi-test.cc:524
Make sure that all DSSS modulation types work (see issue #1095).
void Receive(std::string context, Ptr< const Packet > p, const Address &)
Trace sink to receive from the PacketSocket; the address parameter is unused.
void DoRun() override
Implementation to actually run this TestCase.
uint32_t m_received
number of received packets
Data rate verification test for MCSs of different RU sizes.
void DoRun() override
Implementation to actually run this TestCase.
bool CheckDataRate(HeRu::RuType ruType, std::string mcs, uint8_t nss, Time guardInterval, uint16_t expectedDataRate)
Compare the data rate computed for the provided combination with standard defined one.
Make sure that Ideal rate manager properly selects MCS based on the configured channel width.
WifiMode m_txMode
Store the last selected mode to send data packet.
void ChangeChannelWidth(MHz_u channelWidth)
Change the configured channel width for all nodes.
void DoRun() override
Implementation to actually run this TestCase.
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
Triggers the transmission of a 1000 Byte-long data packet from the source device.
void CheckLastSelectedMode(WifiMode expectedMode)
Check if the selected WifiMode is correct.
void TxCallback(std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback that indicates a PSDU is being transmitted.
Test to validate that Ideal rate manager properly selects TXVECTOR in scenarios where MIMO is used.
~IdealRateManagerMimoTest() override
void CheckLastSelectedNss(uint8_t expectedNss)
Check if the selected Nss is correct.
void DoRun() override
Implementation to actually run this TestCase.
void TxCallback(std::string context, WifiConstPsduMap psdus, WifiTxVector txVector, double txPowerW)
Callback that indicates a PSDU is being transmitted.
void SetApMimoSettings(uint8_t antennas, uint8_t maxStreams)
Change the configured MIMO settings for AP node.
WifiTxVector m_txVector
Store the last TXVECTOR used to transmit Data.
void SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams)
Change the configured MIMO settings for STA node.
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
Triggers the transmission of a 1000 Byte-long data packet from the source device.
void CheckLastSelectedMode(WifiMode expectedMode)
Check if the selected WifiMode is correct.
void SwitchCh(Ptr< WifiNetDevice > dev)
Switch channel function.
Definition wifi-test.cc:323
void SendOnePacket(Ptr< WifiNetDevice > dev)
Send one packet function.
Definition wifi-test.cc:316
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:375
ObjectFactory m_manager
manager
Definition wifi-test.cc:305
ObjectFactory m_propDelay
propagation delay
Definition wifi-test.cc:307
Ptr< Node > CreateOne(Vector pos, Ptr< YansWifiChannel > channel)
Create one function.
Definition wifi-test.cc:330
Make sure that Ideal rate manager is able to handle non best-effort traffic.
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.
~Issue169TestCase() override
void TxCallback(std::string context, WifiConstPsduMap psdus, WifiTxVector txVector, double txPowerW)
Callback that indicates a PSDU is being transmitted.
void DoRun() override
Implementation to actually run this TestCase.
Make sure that Ideal rate manager recovers when the station is moving away from the access point.
uint16_t m_txCount
Count number of transmitted data packets.
uint16_t m_txMacFinalDataFailedCount
Count number of unsuccessfuly transmitted data packets.
void RunOne(bool useAmpdu)
Run one function.
uint16_t m_rxCount
Count number of successfully received data packets.
void RxSuccessCallback(std::string context, Ptr< const Packet > p)
Callback when packet is successfully received.
void DoRun() override
Implementation to actually run this TestCase.
void TxFinalDataFailedCallback(std::string context, Mac48Address address)
Transmit final data failed function.
void SendPackets(uint8_t numPackets, Ptr< NetDevice > sourceDevice, Address &destination)
Triggers the arrival of 1000 Byte-long packets in the source device.
~Issue40TestCase() override
Test management header.
static TypeId GetTypeId()
Register this type.
~MgtTestHeader() override=default
TypeId GetInstanceTypeId() const override
Make sure that fragmentation works with QoS stations.
Definition wifi-test.cc:786
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:847
uint32_t m_received
received packets
Definition wifi-test.cc:794
~QosFragmentationTestCase() override
Definition wifi-test.cc:821
uint32_t m_fragments
transmitted fragments
Definition wifi-test.cc:795
void Transmit(std::string context, Ptr< const Packet > p, double power)
Callback invoked when PHY transmits a packet.
Definition wifi-test.cc:835
void Receive(std::string context, Ptr< const Packet > p, const Address &adr)
Receive function.
Definition wifi-test.cc:826
Qos Utils Is Old Packet Test.
Definition wifi-test.cc:238
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:245
Set Channel Frequency Test.
Definition wifi-test.cc:942
Ptr< YansWifiPhy > GetYansWifiPhyPtr(const NetDeviceContainer &nc) const
Get yans wifi phy function.
Definition wifi-test.cc:963
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:971
Make sure that Wifi STA is correctly associating to the best AP (i.e., nearest from STA).
void DoRun() override
Implementation to actually run this TestCase.
void TurnBeaconGenerationOn(Ptr< Node > apNode)
Turn beacon generation on the AP node.
Mac48Address m_associatedApBssid
Associated AP's bssid.
~StaWifiMacScanningTestCase() override
void TurnApOff(Ptr< Node > apNode)
Turn the AP node off.
NodeContainer Setup(bool nearestApBeaconGeneration, bool staActiveProbe)
Setup test.
void AssocCallback(std::string context, Mac48Address bssid)
Callback function on STA assoc event.
Mgt header (de)serialization Test Suite.
void DoRun() override
Implementation to actually run this TestCase.
~WifiMgtHeaderTest() override=default
Wifi Test.
Definition wifi-test.cc:95
void CreateOne(Vector pos, Ptr< YansWifiChannel > channel)
Create one function.
Definition wifi-test.cc:134
void RunOne()
Run one function.
Definition wifi-test.cc:182
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:201
ObjectFactory m_mac
MAC.
Definition wifi-test.cc:117
void SendOnePacket(Ptr< WifiNetDevice > dev)
Send one packet function.
Definition wifi-test.cc:127
ObjectFactory m_manager
manager
Definition wifi-test.cc:116
ObjectFactory m_propDelay
propagation delay
Definition wifi-test.cc:118
Wifi Test Suite.
a polymophic address class
Definition address.h:90
AttributeValue implementation for Boolean.
Definition boolean.h:26
use constant rates for data and RTS transmissions
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
The Extended Supported Rates Information Element.
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition he-phy.cc:1573
RU Specification.
Definition he-ru.h:57
RuType
The different HE Resource Unit (RU) types.
Definition he-ru.h:32
@ RU_26_TONE
Definition he-ru.h:33
@ RU_484_TONE
Definition he-ru.h:37
@ RU_996_TONE
Definition he-ru.h:38
@ RU_106_TONE
Definition he-ru.h:35
@ RU_52_TONE
Definition he-ru.h:34
@ RU_242_TONE
Definition he-ru.h:36
@ RU_2x996_TONE
Definition he-ru.h:39
Protocol header serialization and deserialization.
Definition header.h:33
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.
an EUI-48 address
static Mac48Address Allocate()
Allocate a new Mac48Address.
Implement the header for management frames of type beacon.
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:153
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition node.cc:138
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
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:511
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.
Ptr< T > Get() const
Definition pointer.h:223
calculate a propagation delay.
Smart pointer class similar to boost::intrusive_ptr.
Handles the packet queue and stores DCF/EDCA access parameters (one Txop per AC).
Definition qos-txop.h:52
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:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
indicates whether the socket has a priority set.
Definition socket.h:1307
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition socket.cc:843
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:25
char * PeekString() const
Peek the SSID.
Definition ssid.cc:67
AttributeValue implementation for Ssid.
Definition ssid.h:85
Hold variables of type string.
Definition string.h:45
The Supported Rates Information Element.
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
Handles the packet queue and stores DCF/EDCA access parameters (one Txop per AC).
Definition txop.h:56
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
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:25
helps to create WifiNetDevice objects
static int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by the PHY and MAC aspects ...
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:89
void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition wifi-mac.cc:482
Implement the header for management frames.
represent a single transmission mode
Definition wifi-mode.h:40
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:174
uint64_t GetDataRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
Definition wifi-mode.cc:111
Hold together all Wifi-related objects.
void Set(std::string name, const AttributeValue &v)
void SetErrorRateModel(std::string type, Args &&... args)
Helper function used to set the error rate model.
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition wifi-phy.cc:687
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
Definition wifi-phy.h:919
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition wifi-phy.cc:1009
virtual void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition wifi-phy.cc:641
void SetOperatingChannel(const WifiPhyOperatingChannel &channel)
If the standard for this object has not been set yet, store the channel settings corresponding to the...
Definition wifi-phy.cc:1135
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition wifi-phy.cc:653
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.
MHz_u 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
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:967
void Set(std::string path, const AttributeValue &value)
Definition config.cc:869
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
#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:134
#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:820
#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:241
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1332
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
TypeOfStation
Enumeration for type of WiFi station.
Definition wifi-mac.h:57
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:156
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
@ STA
Definition wifi-mac.h:58
@ AP
Definition wifi-mac.h:59
@ WIFI_STANDARD_80211a
@ WIFI_STANDARD_80211p
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211g
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ WIFI_STANDARD_80211b
@ WIFI_PREAMBLE_HE_MU
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
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:684
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
std::map< WifiSpectrumBandInfo, Watt_u > RxPowerWattPerChannelBand
A map of the received power for each band.
Definition phy-entity.h:45
@ WIFI_MAC_MGT_ACTION
Ptr< T1 > StaticCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:587
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 wifi-types.h:65
MpduType type
type of MPDU
Definition wifi-types.h:66
SignalNoiseDbm structure.
Definition wifi-types.h:58
static void AssignWifiRandomStreams(Ptr< WifiMac > mac, int64_t stream)
Definition wifi-test.cc:58
static WifiTestSuite g_wifiTestSuite
the test suite
std::tuple< SupportedRates, std::optional< ExtendedSupportedRatesIE >, std::vector< Ssid > > MgtTestElems
List of Information Elements included in the test management frame.