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
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) + 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));
750
752 server->SetLocal(socket);
753 wifiApNode.Get(0)->AddApplication(server);
754 server->SetStartTime(Seconds(0));
755 server->SetStopTime(Seconds(52));
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));
911
913 server->SetLocal(socket);
914 wifiApNode.Get(0)->AddApplication(server);
915 server->SetStartTime(Seconds(0));
916 server->SetStopTime(Seconds(4));
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(), MHz_u{20}, "default configuration");
1014 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{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(), MHz_u{22}, "802.11b configuration");
1025 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{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(), MHz_u{20}, "802.11g configuration");
1036 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{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(), MHz_u{20}, "802.11n-5GHz configuration");
1048 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{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(), MHz_u{20}, "802.11n-2.4GHz configuration");
1060 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{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(), MHz_u{80}, "802.11ac configuration");
1071 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{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(),
1083 MHz_u{20},
1084 "802.11ax-2.4GHz configuration");
1085 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{2412}, "802.11ax-2.4GHz configuration");
1086 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1087 }
1088 {
1089 // case 8:
1090 WifiHelper wifi;
1091 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1092 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1093 phySta = GetYansWifiPhyPtr(staDevice);
1094 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 42, "802.11ax-5GHz configuration");
1095 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{80}, "802.11ax-5GHz configuration");
1096 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{5210}, "802.11ax-5GHz configuration");
1097 }
1098 {
1099 // case 9:
1100 WifiHelper wifi;
1101 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1102 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_6GHZ, 0}"));
1103 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1104 phySta = GetYansWifiPhyPtr(staDevice);
1105 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 7, "802.11ax-6GHz configuration");
1106 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{80}, "802.11ax-6GHz configuration");
1107 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{5985}, "802.11ax-6GHz configuration");
1108 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1109 }
1110 {
1111 // case 10:
1112 WifiHelper wifi;
1113 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1114 wifi.SetStandard(WIFI_STANDARD_80211p);
1115 phy.Set("ChannelSettings", StringValue("{0, 10, BAND_5GHZ, 0}"));
1116 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1117 phySta = GetYansWifiPhyPtr(staDevice);
1118 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 172, "802.11p 10Mhz configuration");
1119 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{10}, "802.11p 10Mhz configuration");
1120 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{5860}, "802.11p 10Mhz configuration");
1121 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1122 }
1123 {
1124 // case 11:
1125 WifiHelper wifi;
1126 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1127 wifi.SetStandard(WIFI_STANDARD_80211p);
1128 phy.Set("ChannelSettings", StringValue("{0, 5, BAND_5GHZ, 0}"));
1129 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1130 phySta = GetYansWifiPhyPtr(staDevice);
1131 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 171, "802.11p 5Mhz configuration");
1132 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{5}, "802.11p 5Mhz configuration");
1133 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{5860}, "802.11p 5Mhz configuration");
1134 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1135 }
1136 {
1137 // case 12:
1138 WifiHelper wifi;
1139 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1140 wifi.SetStandard(WIFI_STANDARD_80211n);
1141 phy.Set("ChannelSettings", StringValue("{44, 20, BAND_5GHZ, 0}"));
1142 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1143 phySta = GetYansWifiPhyPtr(staDevice);
1144 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 44, "802.11 5GHz configuration");
1145 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{20}, "802.11 5GHz configuration");
1146 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{5220}, "802.11 5GHz configuration");
1147 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1148 }
1149 {
1150 // case 13:
1151 WifiHelper wifi;
1152 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1153 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1154 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1155 phySta = GetYansWifiPhyPtr(staDevice);
1156 // Post-install reconfiguration to channel number 40
1157 std::ostringstream path;
1158 path << "/NodeList/*/DeviceList/" << staDevice.Get(0)->GetIfIndex()
1159 << "/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelSettings";
1160 Config::Set(path.str(), StringValue("{40, 0, BAND_5GHZ, 0}"));
1161 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 40, "802.11 5GHz configuration");
1162 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{20}, "802.11 5GHz configuration");
1163 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{5200}, "802.11 5GHz configuration");
1164 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1165 }
1166 {
1167 // case 14:
1168 WifiHelper wifi;
1169 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1170 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1171 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1172 phySta = GetYansWifiPhyPtr(staDevice);
1173 // Post-install reconfiguration to a 40 MHz channel
1174 std::ostringstream path;
1175 path << "/NodeList/*/DeviceList/" << staDevice.Get(0)->GetIfIndex()
1176 << "/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelSettings";
1177 Config::Set(path.str(), StringValue("{46, 0, BAND_5GHZ, 0}"));
1178 // Although channel 44 is configured originally for 20 MHz, we
1179 // allow it to be used for 40 MHz here
1180 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 46, "802.11 5GHz configuration");
1181 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{40}, "802.11 5GHz configuration");
1182 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{5230}, "802.11 5GHz configuration");
1183 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1184 }
1185 {
1186 // case 15:
1187 WifiHelper wifi;
1188 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1189 wifi.SetStandard(WIFI_STANDARD_80211n);
1190 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1191 phySta = GetYansWifiPhyPtr(staDevice);
1192 phySta->SetAttribute("ChannelSettings", StringValue("{3, 20, BAND_2_4GHZ, 0}"));
1193 // Post-install reconfiguration to a 40 MHz channel
1194 std::ostringstream path;
1195 path << "/NodeList/*/DeviceList/" << staDevice.Get(0)->GetIfIndex()
1196 << "/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelSettings";
1197 Config::Set(path.str(), StringValue("{4, 40, BAND_2_4GHZ, 0}"));
1198 // Although channel 44 is configured originally for 20 MHz, we
1199 // allow it to be used for 40 MHz here
1200 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 4, "802.11 5GHz configuration");
1201 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{40}, "802.11 5GHz configuration");
1202 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{2427}, "802.11 5GHz configuration");
1203 phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1204 }
1205 {
1206 // case 16:
1207 WifiHelper wifi;
1208 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1209 // Test that setting Frequency to a non-standard value will throw an exception
1210 wifi.SetStandard(WIFI_STANDARD_80211n);
1211 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1212 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1213 phySta = GetYansWifiPhyPtr(staDevice);
1214 bool exceptionThrown = false;
1215 try
1216 {
1217 phySta->SetAttribute("ChannelSettings", StringValue("{45, 0, BAND_5GHZ, 0}"));
1218 }
1219 catch (const std::runtime_error&)
1220 {
1221 exceptionThrown = true;
1222 }
1223 // We expect that an exception is thrown
1224 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1225 }
1226 {
1227 // case 17:
1228 WifiHelper wifi;
1229 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1230 wifi.SetStandard(WIFI_STANDARD_80211n);
1231 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1232 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1233 phySta = GetYansWifiPhyPtr(staDevice);
1234 // Test that setting channel to a standard value will set the
1235 // frequency correctly
1236 phySta->SetAttribute("ChannelSettings", StringValue("{100, 0, BAND_5GHZ, 0}"));
1237 // We expect frequency to be 5500 due to channel number being 100
1238 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 100, "802.11 5GHz configuration");
1239 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{20}, "802.11 5GHz configuration");
1240 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{5500}, "802.11 5GHz configuration");
1241 }
1242 {
1243 // case 18:
1244 // Set a wrong channel after initialization
1245 WifiHelper wifi;
1246 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1247 wifi.SetStandard(WIFI_STANDARD_80211n);
1248 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1249 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1250 phySta = GetYansWifiPhyPtr(staDevice);
1251 bool exceptionThrown = false;
1252 try
1253 {
1254 phySta->SetOperatingChannel(WifiPhy::ChannelTuple{99, 40, WIFI_PHY_BAND_5GHZ, 0});
1255 }
1256 catch (const std::runtime_error&)
1257 {
1258 exceptionThrown = true;
1259 }
1260 // We expect that an exception is thrown
1261 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1262 }
1263 {
1264 // case 19:
1265 WifiHelper wifi;
1266 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1267 // Test how channel number behaves when frequency is non-standard
1268 wifi.SetStandard(WIFI_STANDARD_80211n);
1269 phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1270 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1271 phySta = GetYansWifiPhyPtr(staDevice);
1272 bool exceptionThrown = false;
1273 try
1274 {
1275 phySta->SetAttribute("ChannelSettings", StringValue("{45, 0, BAND_5GHZ, 0}"));
1276 }
1277 catch (const std::runtime_error&)
1278 {
1279 exceptionThrown = true;
1280 }
1281 // We expect that an exception is thrown due to unknown channel number 45
1282 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1283 phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1284 // We expect channel number to be 36 due to known center frequency 5180
1285 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1286 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{20}, "802.11 5GHz configuration");
1287 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{5180}, "802.11 5GHz configuration");
1288 exceptionThrown = false;
1289 try
1290 {
1291 phySta->SetAttribute("ChannelSettings", StringValue("{43, 0, BAND_5GHZ, 0}"));
1292 }
1293 catch (const std::runtime_error&)
1294 {
1295 exceptionThrown = true;
1296 }
1297 // We expect that an exception is thrown due to unknown channel number 43
1298 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1299 phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1300 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1301 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{20}, "802.11 5GHz configuration");
1302 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{5180}, "802.11 5GHz configuration");
1303 }
1304 {
1305 // case 20:
1306 WifiHelper wifi;
1307 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1308 phy.Set("ChannelSettings", StringValue("{40, 0, BAND_5GHZ, 0}"));
1309 wifi.SetStandard(WIFI_STANDARD_80211n);
1310 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1311 phySta = GetYansWifiPhyPtr(staDevice);
1312 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 40, "802.11 5GHz configuration");
1313 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{20}, "802.11 5GHz configuration");
1314 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{5200}, "802.11 5GHz configuration");
1315 // Set both channel and frequency to consistent values after initialization
1316 wifi.SetStandard(WIFI_STANDARD_80211n);
1317 staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1318 phySta = GetYansWifiPhyPtr(staDevice);
1319 phySta->SetAttribute("ChannelSettings", StringValue("{40, 0, BAND_5GHZ, 0}"));
1320 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 40, "802.11 5GHz configuration");
1321 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{20}, "802.11 5GHz configuration");
1322 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{5200}, "802.11 5GHz configuration");
1323
1324 phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1325 // We expect channel number to be 36
1326 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1327 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{20}, "802.11 5GHz configuration");
1328 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{5180}, "802.11 5GHz configuration");
1329 phySta->SetAttribute("ChannelSettings", StringValue("{40, 0, BAND_5GHZ, 0}"));
1330 // We expect channel number to be 40
1331 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 40, "802.11 5GHz configuration");
1332 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{20}, "802.11 5GHz configuration");
1333 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{5200}, "802.11 5GHz configuration");
1334 bool exceptionThrown = false;
1335 try
1336 {
1337 phySta->SetAttribute("ChannelSettings", StringValue("{45, 0, BAND_5GHZ, 0}"));
1338 }
1339 catch (const std::runtime_error&)
1340 {
1341 exceptionThrown = true;
1342 }
1343 phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1344 // We expect channel number to be 36 and an exception to be thrown
1345 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1346 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{20}, "802.11 5GHz configuration");
1347 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{5180}, "802.11 5GHz configuration");
1348 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1349 phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1350 exceptionThrown = false;
1351 try
1352 {
1353 phySta->SetAttribute("ChannelSettings", StringValue("{43, 0, BAND_5GHZ, 0}"));
1354 }
1355 catch (const std::runtime_error&)
1356 {
1357 exceptionThrown = true;
1358 }
1359 // We expect channel number to be 36 and an exception to be thrown
1360 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1361 NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), MHz_u{20}, "802.11 5GHz configuration");
1362 NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), MHz_u{5180}, "802.11 5GHz configuration");
1363 NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1364 }
1365
1367}
1368
1369//-----------------------------------------------------------------------------
1370/**
1371 * Make sure that when virtual collision occurs the wifi remote station manager
1372 * is triggered and the retry counter is increased.
1373 *
1374 * See \bugid{2222}
1375 */
1376
1378{
1379 public:
1381 ~Bug2222TestCase() override;
1382
1383 void DoRun() override;
1384
1385 private:
1386 uint32_t m_countInternalCollisions; ///< count internal collisions
1387
1388 /**
1389 * Transmit data failed function
1390 * @param context the context
1391 * @param adr the MAC address
1392 */
1393 void TxDataFailedTrace(std::string context, Mac48Address adr);
1394};
1395
1397 : TestCase("Test case for Bug 2222"),
1398 m_countInternalCollisions(0)
1399{
1400}
1401
1405
1406void
1408{
1409 // Indicate the long retry counter has been increased in the wifi remote station manager
1411}
1412
1413void
1415{
1417
1418 // Generate same backoff for AC_VI and AC_VO
1419 // The below combination will work
1422 int64_t streamNumber = 100;
1423
1424 NodeContainer wifiNodes;
1425 wifiNodes.Create(2);
1426
1429 phy.SetChannel(channel.Create());
1430
1431 WifiHelper wifi;
1432 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
1433 "DataMode",
1434 StringValue("OfdmRate54Mbps"),
1435 "ControlMode",
1436 StringValue("OfdmRate24Mbps"));
1437 WifiMacHelper mac;
1438 Ssid ssid = Ssid("ns-3-ssid");
1439 mac.SetType("ns3::AdhocWifiMac", "QosSupported", BooleanValue(true));
1440
1441 NetDeviceContainer wifiDevices;
1442 wifiDevices = wifi.Install(phy, mac, wifiNodes);
1443
1444 // Assign fixed streams to random variables in use
1445 WifiHelper::AssignStreams(wifiDevices, streamNumber);
1446
1447 MobilityHelper mobility;
1449
1450 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
1451 positionAlloc->Add(Vector(10.0, 0.0, 0.0));
1452 mobility.SetPositionAllocator(positionAlloc);
1453
1454 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1455 mobility.Install(wifiNodes);
1456
1457 Ptr<WifiNetDevice> device1 = DynamicCast<WifiNetDevice>(wifiDevices.Get(0));
1458 Ptr<WifiNetDevice> device2 = DynamicCast<WifiNetDevice>(wifiDevices.Get(1));
1459
1460 PacketSocketAddress socket;
1461 socket.SetSingleDevice(device1->GetIfIndex());
1462 socket.SetPhysicalAddress(device2->GetAddress());
1463 socket.SetProtocol(1);
1464
1465 PacketSocketHelper packetSocket;
1466 packetSocket.Install(wifiNodes);
1467
1469 clientLowPriority->SetAttribute("PacketSize", UintegerValue(1460));
1470 clientLowPriority->SetAttribute("MaxPackets", UintegerValue(1));
1471 clientLowPriority->SetAttribute("Priority", UintegerValue(4)); // AC_VI
1472 clientLowPriority->SetRemote(socket);
1473 wifiNodes.Get(0)->AddApplication(clientLowPriority);
1474 clientLowPriority->SetStartTime(Seconds(0));
1475 clientLowPriority->SetStopTime(Seconds(1));
1476
1478 clientHighPriority->SetAttribute("PacketSize", UintegerValue(1460));
1479 clientHighPriority->SetAttribute("MaxPackets", UintegerValue(1));
1480 clientHighPriority->SetAttribute("Priority", UintegerValue(6)); // AC_VO
1481 clientHighPriority->SetRemote(socket);
1482 wifiNodes.Get(0)->AddApplication(clientHighPriority);
1483 clientHighPriority->SetStartTime(Seconds(0));
1484 clientHighPriority->SetStopTime(Seconds(1));
1485
1487 server->SetLocal(socket);
1488 wifiNodes.Get(1)->AddApplication(server);
1489 server->SetStartTime(Seconds(0));
1490 server->SetStopTime(Seconds(1));
1491
1492 Config::Connect("/NodeList/*/DeviceList/*/RemoteStationManager/MacTxDataFailed",
1494
1498
1500 1,
1501 "unexpected number of internal collisions!");
1502}
1503
1504//-----------------------------------------------------------------------------
1505/**
1506 * Make sure that the correct channel width and center frequency have been set
1507 * for OFDM basic rate transmissions and BSS channel widths larger than 20 MHz.
1508 *
1509 * The scenario considers a UDP transmission between a 40 MHz 802.11ac station and a
1510 * 40 MHz 802.11ac access point. All transmission parameters are checked so as
1511 * to ensure that only 3 {starting frequency, channelWidth, Number of subbands
1512 * in SpectrumModel, modulation type} tuples are used.
1513 *
1514 * See \bugid{2843}
1515 */
1516
1518{
1519 public:
1521 ~Bug2843TestCase() override;
1522 void DoRun() override;
1523
1524 private:
1525 /**
1526 * A tuple of {starting frequency, channelWidth, Number of subbands in SpectrumModel, modulation
1527 * type}
1528 */
1529 typedef std::tuple<Hz_u, MHz_u, uint32_t, WifiModulationClass> FreqWidthSubbandModulationTuple;
1530 std::vector<FreqWidthSubbandModulationTuple>
1531 m_distinctTuples; ///< vector of distinct {starting frequency, channelWidth, Number of
1532 ///< subbands in SpectrumModel, modulation type} tuples
1533
1534 /**
1535 * Stores the distinct {starting frequency, channelWidth, Number of subbands in SpectrumModel,
1536 * modulation type} tuples that have been used during the testcase run.
1537 * @param context the context
1538 * @param txParams spectrum signal parameters set by transmitter
1539 */
1540 void StoreDistinctTuple(std::string context, Ptr<SpectrumSignalParameters> txParams);
1541 /**
1542 * Triggers the arrival of a burst of 1000 Byte-long packets in the source device
1543 * @param numPackets number of packets in burst
1544 * @param sourceDevice pointer to the source NetDevice
1545 * @param destination address of the destination device
1546 */
1547 void SendPacketBurst(uint8_t numPackets,
1548 Ptr<NetDevice> sourceDevice,
1549 Address& destination) const;
1550
1551 MHz_u m_channelWidth; ///< channel width
1552};
1553
1555 : TestCase("Test case for Bug 2843"),
1556 m_channelWidth(MHz_u{20})
1557{
1558}
1559
1563
1564void
1566{
1567 // Extract starting frequency and number of subbands
1568 Ptr<const SpectrumModel> c = txParams->psd->GetSpectrumModel();
1569 std::size_t numBands = c->GetNumBands();
1570 const Hz_u startingFreq{c->Begin()->fl};
1571
1572 // Get channel bandwidth and modulation class
1575
1576 Ptr<WifiPpdu> ppdu = wifiTxParams->ppdu->Copy();
1577 WifiTxVector txVector = ppdu->GetTxVector();
1578 m_channelWidth = txVector.GetChannelWidth();
1579 WifiModulationClass modulationClass = txVector.GetMode().GetModulationClass();
1580
1581 // Build a tuple and check if seen before (if so store it)
1582 FreqWidthSubbandModulationTuple tupleForCurrentTx =
1583 std::make_tuple(startingFreq, m_channelWidth, numBands, modulationClass);
1584 bool found = false;
1585 for (auto it = m_distinctTuples.begin(); it != m_distinctTuples.end(); it++)
1586 {
1587 if (*it == tupleForCurrentTx)
1588 {
1589 found = true;
1590 }
1591 }
1592 if (!found)
1593 {
1594 m_distinctTuples.push_back(tupleForCurrentTx);
1595 }
1596}
1597
1598void
1600 Ptr<NetDevice> sourceDevice,
1601 Address& destination) const
1602{
1603 for (uint8_t i = 0; i < numPackets; i++)
1604 {
1605 Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
1606 sourceDevice->Send(pkt, destination, 0);
1607 }
1608}
1609
1610void
1612{
1613 MHz_u channelWidth{40}; // at least 40 MHz expected here
1614
1615 NodeContainer wifiStaNode;
1616 wifiStaNode.Create(1);
1617
1618 NodeContainer wifiApNode;
1619 wifiApNode.Create(1);
1620
1621 SpectrumWifiPhyHelper spectrumPhy;
1624 lossModel->SetFrequency(5.190e9);
1625 spectrumChannel->AddPropagationLossModel(lossModel);
1626
1629 spectrumChannel->SetPropagationDelayModel(delayModel);
1630
1631 spectrumPhy.SetChannel(spectrumChannel);
1632 spectrumPhy.SetErrorRateModel("ns3::NistErrorRateModel");
1633 spectrumPhy.Set("ChannelSettings", StringValue("{38, 40, BAND_5GHZ, 0}"));
1634 spectrumPhy.Set("TxPowerStart", DoubleValue(10));
1635 spectrumPhy.Set("TxPowerEnd", DoubleValue(10));
1636
1637 WifiHelper wifi;
1638 wifi.SetStandard(WIFI_STANDARD_80211ac);
1639 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
1640 "DataMode",
1641 StringValue("VhtMcs8"),
1642 "ControlMode",
1643 StringValue("VhtMcs8"),
1644 "RtsCtsThreshold",
1645 StringValue("500")); // so as to force RTS/CTS for data frames
1646
1647 WifiMacHelper mac;
1648 mac.SetType("ns3::StaWifiMac");
1649 NetDeviceContainer staDevice;
1650 staDevice = wifi.Install(spectrumPhy, mac, wifiStaNode);
1651
1652 mac.SetType("ns3::ApWifiMac");
1653 NetDeviceContainer apDevice;
1654 apDevice = wifi.Install(spectrumPhy, mac, wifiApNode);
1655
1656 MobilityHelper mobility;
1658 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
1659 positionAlloc->Add(Vector(1.0, 0.0, 0.0)); // put close enough in order to use MCS
1660 mobility.SetPositionAllocator(positionAlloc);
1661
1662 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1663 mobility.Install(wifiApNode);
1664 mobility.Install(wifiStaNode);
1665
1666 // Send two 5 packet-bursts
1669 this,
1670 5,
1671 apDevice.Get(0),
1672 staDevice.Get(0)->GetAddress());
1675 this,
1676 5,
1677 apDevice.Get(0),
1678 staDevice.Get(0)->GetAddress());
1679
1680 Config::Connect("/ChannelList/*/$ns3::MultiModelSpectrumChannel/TxSigParams",
1682
1685
1687
1688 // {starting frequency, channelWidth, Number of subbands in SpectrumModel, modulation type}
1689 // tuples
1690 std::size_t numberTuples = m_distinctTuples.size();
1691 NS_TEST_ASSERT_MSG_EQ(numberTuples, 3, "Only three distinct tuples expected");
1692 NS_TEST_EXPECT_MSG_EQ(std::get<0>(m_distinctTuples[0]) - Hz_u{20e6},
1693 std::get<0>(m_distinctTuples[1]),
1694 "The starting frequency of the first tuple should be shifted 20 MHz to "
1695 "the right wrt second tuple");
1696 // Note that the first tuple should the one initiated by the beacon, i.e. non-HT OFDM (20 MHz)
1698 MHz_u{20},
1699 "First tuple's channel width should be 20 MHz");
1701 193,
1702 "First tuple should have 193 subbands (64+DC, 20MHz+DC, inband and 64*2 "
1703 "out-of-band, 20MHz on each side)");
1705 WifiModulationClass::WIFI_MOD_CLASS_OFDM,
1706 "First tuple should be OFDM");
1707 // Second tuple: data frames, VHT (40 MHz)
1709 channelWidth,
1710 "Second tuple's channel width should be 40 MHz");
1712 385,
1713 "Second tuple should have 385 subbands (128+DC, 40MHz+DC, inband and "
1714 "128*2 out-of-band, 40MHz on each side)");
1716 WifiModulationClass::WIFI_MOD_CLASS_VHT,
1717 "Second tuple should be VHT_OFDM");
1718 // Third tuple: control response frames, non-HT (OFDM) duplicate (40 MHz)
1720 std::get<0>(m_distinctTuples[2]),
1721 "The starting frequency of the third tuple should be the same as the "
1722 "second tuple");
1724 channelWidth,
1725 "Third tuple's channel width should be 40 MHz");
1727 385,
1728 "Third tuple should have 385 subbands (128+DC, 40MHz+DC, inband and "
1729 "128*2 out-of-band, 40MHz on each side)");
1731 WifiModulationClass::WIFI_MOD_CLASS_OFDM,
1732 "Third tuple should be OFDM");
1733}
1734
1735//-----------------------------------------------------------------------------
1736/**
1737 * Make sure that the channel width and the channel number can be changed at runtime.
1738 *
1739 * The scenario considers an access point and a station using a 20 MHz channel width.
1740 * After 1s, we change the channel width and the channel number to use a 40 MHz channel.
1741 * The tests checks the operational channel width sent in Beacon frames
1742 * and verify that the association procedure is executed twice.
1743 *
1744 * See \bugid{2831}
1745 */
1746
1748{
1749 public:
1751 ~Bug2831TestCase() override;
1752 void DoRun() override;
1753
1754 private:
1755 /**
1756 * Function called to change the supported channel width at runtime
1757 */
1759 /**
1760 * Callback triggered when a packet is received by the PHYs
1761 * @param context the context
1762 * @param p the received packet
1763 * @param rxPowersW the received power per channel band in watts
1764 */
1765 void RxCallback(std::string context, Ptr<const Packet> p, RxPowerWattPerChannelBand rxPowersW);
1766
1769
1770 uint16_t m_assocReqCount; ///< count number of association requests
1771 uint16_t m_assocRespCount; ///< count number of association responses
1772 uint16_t m_countOperationalChannelWidth20; ///< count number of beacon frames announcing a 20
1773 ///< MHz operating channel width
1774 uint16_t m_countOperationalChannelWidth40; ///< count number of beacon frames announcing a 40
1775 ///< MHz operating channel width
1776};
1777
1779 : TestCase("Test case for Bug 2831"),
1780 m_assocReqCount(0),
1781 m_assocRespCount(0),
1782 m_countOperationalChannelWidth20(0),
1783 m_countOperationalChannelWidth40(0)
1784{
1785}
1786
1790
1791void
1797
1798void
1801 RxPowerWattPerChannelBand rxPowersW)
1802{
1803 Ptr<Packet> packet = p->Copy();
1804 WifiMacHeader hdr;
1805 packet->RemoveHeader(hdr);
1806 if (hdr.IsAssocReq())
1807 {
1809 }
1810 else if (hdr.IsAssocResp())
1811 {
1813 }
1814 else if (hdr.IsBeacon())
1815 {
1816 MgtBeaconHeader beacon;
1817 packet->RemoveHeader(beacon);
1818 const auto& htOperation = beacon.Get<HtOperation>();
1819 if (htOperation.has_value() && htOperation->GetStaChannelWidth() > 0)
1820 {
1822 }
1823 else
1824 {
1826 }
1827 }
1828}
1829
1830void
1832{
1834 ObjectFactory propDelay;
1835 propDelay.SetTypeId("ns3::ConstantSpeedPropagationDelayModel");
1836 Ptr<PropagationDelayModel> propagationDelay = propDelay.Create<PropagationDelayModel>();
1838 channel->SetPropagationDelayModel(propagationDelay);
1839 channel->SetPropagationLossModel(propagationLoss);
1840
1841 Ptr<Node> apNode = CreateObject<Node>();
1843 apNode->AddDevice(apDev);
1844 apDev->SetStandard(WIFI_STANDARD_80211ax);
1846 apDev->SetHtConfiguration(apHtConfiguration);
1847 ObjectFactory manager;
1848 manager.SetTypeId("ns3::ConstantRateWifiManager");
1849 apDev->SetRemoteStationManager(manager.Create<WifiRemoteStationManager>());
1850
1852 apMobility->SetPosition(Vector(0.0, 0.0, 0.0));
1853 apNode->AggregateObject(apMobility);
1854
1855 auto error = CreateObject<YansErrorRateModel>();
1857 apDev->SetPhy(m_apPhy);
1859 m_apPhy->SetInterferenceHelper(apInterferenceHelper);
1860 m_apPhy->SetErrorRateModel(error);
1861 m_apPhy->SetChannel(channel);
1862 m_apPhy->SetMobility(apMobility);
1863 m_apPhy->SetDevice(apDev);
1866
1867 ObjectFactory mac;
1868 mac.SetTypeId("ns3::ApWifiMac");
1869 mac.Set("EnableBeaconJitter", BooleanValue(false));
1870 mac.Set("QosSupported", BooleanValue(true));
1871 for (const std::string ac : {"BE", "BK", "VI", "VO"})
1872 {
1873 auto qosTxop =
1874 CreateObjectWithAttributes<QosTxop>("AcIndex", StringValue(std::string("AC_") + ac));
1875 mac.Set(ac + "_Txop", PointerValue(qosTxop));
1876 }
1877 auto apMac = mac.Create<WifiMac>();
1878 apMac->SetDevice(apDev);
1879 apMac->SetAddress(Mac48Address::Allocate());
1880 apDev->SetMac(apMac);
1881 apMac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
1882 apMac->SetFrameExchangeManagers({CreateObject<HeFrameExchangeManager>()});
1883 apMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
1884 Ptr<FrameExchangeManager> fem = apMac->GetFrameExchangeManager();
1885 fem->SetAddress(apMac->GetAddress());
1887 protectionManager->SetWifiMac(apMac);
1888 fem->SetProtectionManager(protectionManager);
1890 ackManager->SetWifiMac(apMac);
1891 fem->SetAckManager(ackManager);
1892
1893 Ptr<Node> staNode = CreateObject<Node>();
1895 staNode->AddDevice(staDev);
1896 staDev->SetStandard(WIFI_STANDARD_80211ax);
1898 staDev->SetHtConfiguration(staHtConfiguration);
1899 staDev->SetRemoteStationManager(manager.Create<WifiRemoteStationManager>());
1900
1902 staMobility->SetPosition(Vector(1.0, 0.0, 0.0));
1903 staNode->AggregateObject(staMobility);
1904
1906 staDev->SetPhy(m_staPhy);
1908 m_staPhy->SetInterferenceHelper(staInterferenceHelper);
1910 m_staPhy->SetChannel(channel);
1911 m_staPhy->SetMobility(staMobility);
1912 m_staPhy->SetDevice(apDev);
1915
1916 mac.SetTypeId("ns3::StaWifiMac");
1917 for (const std::string ac : {"BE", "BK", "VI", "VO"})
1918 {
1919 auto qosTxop =
1920 CreateObjectWithAttributes<QosTxop>("AcIndex", StringValue(std::string("AC_") + ac));
1921 mac.Set(ac + "_Txop", PointerValue(qosTxop));
1922 }
1923 auto staMac = mac.Create<WifiMac>();
1924 staDev->SetMac(staMac);
1925 staMac->SetDevice(staDev);
1926 staMac->SetAddress(Mac48Address::Allocate());
1927 staMac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
1928 staMac->SetFrameExchangeManagers({CreateObject<HeFrameExchangeManager>()});
1930 staMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
1931 fem = staMac->GetFrameExchangeManager();
1932 fem->SetAddress(staMac->GetAddress());
1933 protectionManager = CreateObject<WifiDefaultProtectionManager>();
1934 protectionManager->SetWifiMac(staMac);
1935 fem->SetProtectionManager(protectionManager);
1937 ackManager->SetWifiMac(staMac);
1938 fem->SetAckManager(ackManager);
1939
1940 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxBegin",
1942
1944
1948
1949 NS_TEST_ASSERT_MSG_EQ(m_assocReqCount, 2, "Second Association request not received");
1950 NS_TEST_ASSERT_MSG_EQ(m_assocRespCount, 2, "Second Association response not received");
1952 10,
1953 "Incorrect operational channel width before channel change");
1955 20,
1956 "Incorrect operational channel width after channel change");
1957}
1958
1959//-----------------------------------------------------------------------------
1960/**
1961 * Make sure that Wifi STA is correctly associating to the best AP (i.e.,
1962 * nearest from STA). We consider 3 AP and 1 STA. This test case consisted of
1963 * three sub tests:
1964 * - The best AP sends its beacon later than the other APs. STA is expected
1965 * to associate to the best AP.
1966 * - The STA is using active scanning instead of passive, the rest of the
1967 * APs works normally. STA is expected to associate to the best AP
1968 * - The nearest AP is turned off after sending beacon and while STA is
1969 * still scanning. STA is expected to associate to the second best AP.
1970 *
1971 * See \bugid{2399}
1972 * @todo Add explicit association refusal test if ns-3 implemented it.
1973 */
1974
1976{
1977 public:
1979 ~StaWifiMacScanningTestCase() override;
1980 void DoRun() override;
1981
1982 private:
1983 /**
1984 * Callback function on STA assoc event
1985 * @param context context string
1986 * @param bssid the associated AP's bssid
1987 */
1988 void AssocCallback(std::string context, Mac48Address bssid);
1989 /**
1990 * Turn beacon generation on the AP node
1991 * @param apNode the AP node
1992 */
1993 void TurnBeaconGenerationOn(Ptr<Node> apNode);
1994 /**
1995 * Turn the AP node off
1996 * @param apNode the AP node
1997 */
1998 void TurnApOff(Ptr<Node> apNode);
1999 /**
2000 * Setup test
2001 * @param nearestApBeaconGeneration set BeaconGeneration attribute of the nearest AP
2002 * @param staActiveProbe set ActiveProbing attribute of the STA
2003 * @return node container containing all nodes
2004 */
2005 NodeContainer Setup(bool nearestApBeaconGeneration, bool staActiveProbe);
2006
2007 Mac48Address m_associatedApBssid; ///< Associated AP's bssid
2008};
2009
2011 : TestCase("Test case for StaWifiMac scanning capability")
2012{
2013}
2014
2018
2019void
2021{
2022 m_associatedApBssid = bssid;
2023}
2024
2025void
2027{
2028 Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice>(apNode->GetDevice(0));
2029 Ptr<ApWifiMac> mac = DynamicCast<ApWifiMac>(netDevice->GetMac());
2030 mac->SetAttribute("BeaconGeneration", BooleanValue(true));
2031}
2032
2033void
2035{
2036 Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice>(apNode->GetDevice(0));
2037 Ptr<WifiPhy> phy = netDevice->GetPhy();
2038 phy->SetOffMode();
2039}
2040
2042StaWifiMacScanningTestCase::Setup(bool nearestApBeaconGeneration, bool staActiveProbe)
2043{
2046 int64_t streamNumber = 1;
2047
2048 NodeContainer apNodes;
2049 apNodes.Create(2);
2050
2051 Ptr<Node> apNodeNearest = CreateObject<Node>();
2052 Ptr<Node> staNode = CreateObject<Node>();
2053
2056 phy.SetChannel(channel.Create());
2057
2058 WifiHelper wifi;
2059 wifi.SetStandard(WIFI_STANDARD_80211n);
2060 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager");
2061
2062 WifiMacHelper mac;
2063 NetDeviceContainer apDevice;
2064 NetDeviceContainer apDeviceNearest;
2065 mac.SetType("ns3::ApWifiMac", "BeaconGeneration", BooleanValue(true));
2066 apDevice = wifi.Install(phy, mac, apNodes);
2067 mac.SetType("ns3::ApWifiMac", "BeaconGeneration", BooleanValue(nearestApBeaconGeneration));
2068 apDeviceNearest = wifi.Install(phy, mac, apNodeNearest);
2069
2070 NetDeviceContainer staDevice;
2071 mac.SetType("ns3::StaWifiMac", "ActiveProbing", BooleanValue(staActiveProbe));
2072 staDevice = wifi.Install(phy, mac, staNode);
2073
2074 // Assign fixed streams to random variables in use
2075 WifiHelper::AssignStreams(apDevice, streamNumber);
2076 WifiHelper::AssignStreams(apDeviceNearest, streamNumber + 1);
2077 WifiHelper::AssignStreams(staDevice, streamNumber + 2);
2078
2079 MobilityHelper mobility;
2081 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Furthest AP
2082 positionAlloc->Add(Vector(10.0, 0.0, 0.0)); // Second nearest AP
2083 positionAlloc->Add(Vector(5.0, 5.0, 0.0)); // Nearest AP
2084 positionAlloc->Add(Vector(6.0, 5.0, 0.0)); // STA
2085 mobility.SetPositionAllocator(positionAlloc);
2086
2087 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2088 mobility.Install(apNodes);
2089 mobility.Install(apNodeNearest);
2090 mobility.Install(staNode);
2091
2092 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/Assoc",
2094
2095 NodeContainer allNodes = NodeContainer(apNodes, apNodeNearest, staNode);
2096 return allNodes;
2097}
2098
2099void
2101{
2102 {
2103 NodeContainer nodes = Setup(false, false);
2104 Ptr<Node> nearestAp = nodes.Get(2);
2105 Mac48Address nearestApAddr =
2106 DynamicCast<WifiNetDevice>(nearestAp->GetDevice(0))->GetMac()->GetAddress();
2107
2110 this,
2111 nearestAp);
2112
2116
2118 nearestApAddr,
2119 "STA is associated to the wrong AP");
2120 }
2122 {
2123 NodeContainer nodes = Setup(true, true);
2124 Ptr<Node> nearestAp = nodes.Get(2);
2125 Mac48Address nearestApAddr =
2126 DynamicCast<WifiNetDevice>(nearestAp->GetDevice(0))->GetMac()->GetAddress();
2127
2131
2133 nearestApAddr,
2134 "STA is associated to the wrong AP");
2135 }
2137 {
2138 NodeContainer nodes = Setup(true, false);
2139 Ptr<Node> nearestAp = nodes.Get(2);
2140 Mac48Address secondNearestApAddr =
2141 DynamicCast<WifiNetDevice>(nodes.Get(1)->GetDevice(0))->GetMac()->GetAddress();
2142
2144
2148
2150 secondNearestApAddr,
2151 "STA is associated to the wrong AP");
2152 }
2153}
2154
2155//-----------------------------------------------------------------------------
2156/**
2157 * Make sure that the ADDBA handshake process is protected.
2158 *
2159 * The scenario considers an access point and a station. It utilizes
2160 * ReceiveListErrorModel to drop by force ADDBA request on STA or ADDBA
2161 * response on AP. The AP sends 5 packets of each 1000 bytes (thus generating
2162 * BA agreement), 2 times during the test at 0.5s and 0.8s. We only drop the
2163 * first ADDBA request/response of the first BA negotiation. Therefore, we
2164 * expect that the packets still in queue after the failed BA agreement will be
2165 * sent with normal MPDU, and packets queued after that should be sent with
2166 * A-MPDU.
2167 *
2168 * This test consider 2 cases:
2169 *
2170 * 1. ADDBA request packets are blocked on receive at STA, triggering
2171 * transmission failure at AP
2172 * 2. ADDBA response packets are blocked on receive at AP, STA stops
2173 * retransmission of ADDBA response
2174 *
2175 * See \bugid{2470}
2176 */
2177
2179{
2180 public:
2182 ~Bug2470TestCase() override;
2183 void DoRun() override;
2184
2185 private:
2186 /**
2187 * Callback when ADDBA state changed
2188 * @param context node context
2189 * @param t the time the state changed
2190 * @param recipient the MAC address of the recipient
2191 * @param tid the TID
2192 * @param state the state
2193 */
2194 void AddbaStateChangedCallback(std::string context,
2195 Time t,
2196 Mac48Address recipient,
2197 uint8_t tid,
2199 /**
2200 * Callback when a frame is transmitted.
2201 * @param rxErrorModel the post reception error model on the receiver
2202 * @param context the context
2203 * @param psduMap the PSDU map
2204 * @param txVector the TX vector
2205 * @param txPowerW the tx power in Watts
2206 */
2207 void TxCallback(Ptr<ListErrorModel> rxErrorModel,
2208 std::string context,
2209 WifiConstPsduMap psduMap,
2210 WifiTxVector txVector,
2211 double txPowerW);
2212
2213 /**
2214 * Callback when packet is received
2215 * @param context node context
2216 * @param p the received packet
2217 * @param channelFreqMhz the channel frequency in MHz
2218 * @param txVector the TX vector
2219 * @param aMpdu the A-MPDU info
2220 * @param signalNoise the signal noise in dBm
2221 * @param staId the STA-ID
2222 */
2223 void RxCallback(std::string context,
2225 uint16_t channelFreqMhz,
2226 WifiTxVector txVector,
2227 MpduInfo aMpdu,
2228 SignalNoiseDbm signalNoise,
2229 uint16_t staId);
2230 /**
2231 * Callback when packet is dropped
2232 * @param context node context
2233 * @param p the failed packet
2234 * @param snr the SNR of the failed packet in linear scale
2235 */
2236 void RxErrorCallback(std::string context, Ptr<const Packet> p, double snr);
2237 /**
2238 * Triggers the arrival of a burst of 1000 Byte-long packets in the source device
2239 * @param numPackets number of packets in burst
2240 * @param sourceDevice pointer to the source NetDevice
2241 * @param destination address of the destination device
2242 */
2243 void SendPacketBurst(uint32_t numPackets,
2244 Ptr<NetDevice> sourceDevice,
2245 Address& destination) const;
2246 /**
2247 * Run subtest for this test suite
2248 * @param rcvErrorType type of station (STA or AP) to install the post reception error model on
2249 */
2250 void RunSubtest(TypeOfStation rcvErrorType);
2251
2252 uint16_t m_receivedNormalMpduCount; ///< Count received normal MPDU packets on STA
2253 uint16_t m_receivedAmpduCount; ///< Count received A-MPDU packets on STA
2254 uint16_t m_failedActionCount; ///< Count failed ADDBA request/response
2255 uint16_t m_addbaEstablishedCount; ///< Count number of times ADDBA state machine is in
2256 ///< established state
2257 uint16_t m_addbaPendingCount; ///< Count number of times ADDBA state machine is in pending state
2258 uint16_t
2259 m_addbaRejectedCount; ///< Count number of times ADDBA state machine is in rejected state
2260 uint16_t
2261 m_addbaNoReplyCount; ///< Count number of times ADDBA state machine is in no_reply state
2262 uint16_t m_addbaResetCount; ///< Count number of times ADDBA state machine is in reset state
2263};
2264
2266 : TestCase("Test case for Bug 2470"),
2267 m_receivedNormalMpduCount(0),
2268 m_receivedAmpduCount(0),
2269 m_failedActionCount(0),
2270 m_addbaEstablishedCount(0),
2271 m_addbaPendingCount(0),
2272 m_addbaRejectedCount(0),
2273 m_addbaNoReplyCount(0),
2274 m_addbaResetCount(0)
2275{
2276}
2277
2281
2282void
2284 Time t,
2285 Mac48Address recipient,
2286 uint8_t tid,
2288{
2289 switch (state)
2290 {
2293 break;
2296 break;
2299 break;
2302 break;
2305 break;
2306 }
2307}
2308
2309void
2311 std::string context,
2312 WifiConstPsduMap psduMap,
2313 WifiTxVector txVector,
2314 double txPowerW)
2315{
2316 auto psdu = psduMap.begin()->second;
2317
2318 // The sender is transmitting an ADDBA_REQUEST or ADDBA_RESPONSE frame. If this is
2319 // the first attempt at establishing a BA agreement (i.e., before the second set of packets
2320 // is generated), make the reception of the frame fail at the receiver.
2321 if (psdu->GetHeader(0).GetType() == WIFI_MAC_MGT_ACTION && Simulator::Now() < Seconds(0.8))
2322 {
2323 auto uid = psdu->GetPayload(0)->GetUid();
2324 rxErrorModel->SetList({uid});
2325 }
2326}
2327
2328void
2331 uint16_t channelFreqMhz,
2332 WifiTxVector txVector,
2333 MpduInfo aMpdu,
2334 SignalNoiseDbm signalNoise,
2335 uint16_t staId)
2336{
2337 Ptr<Packet> packet = p->Copy();
2338 if (aMpdu.type != MpduType::NORMAL_MPDU)
2339 {
2341 }
2342 else
2343 {
2344 WifiMacHeader hdr;
2345 packet->RemoveHeader(hdr);
2346 if (hdr.IsData())
2347 {
2349 }
2350 }
2351}
2352
2353void
2354Bug2470TestCase::RxErrorCallback(std::string context, Ptr<const Packet> p, double snr)
2355{
2356 Ptr<Packet> packet = p->Copy();
2357 WifiMacHeader hdr;
2358 packet->RemoveHeader(hdr);
2359 if (hdr.IsAction())
2360 {
2362 }
2363}
2364
2365void
2367 Ptr<NetDevice> sourceDevice,
2368 Address& destination) const
2369{
2370 for (uint32_t i = 0; i < numPackets; i++)
2371 {
2372 Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
2373 sourceDevice->Send(pkt, destination, 0);
2374 }
2375}
2376
2377void
2379{
2382 int64_t streamNumber = 200;
2383
2384 NodeContainer wifiApNode;
2385 NodeContainer wifiStaNode;
2386 wifiApNode.Create(1);
2387 wifiStaNode.Create(1);
2388
2391 phy.SetChannel(channel.Create());
2392
2393 WifiHelper wifi;
2394 wifi.SetStandard(WIFI_STANDARD_80211n);
2395 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
2396 "DataMode",
2397 StringValue("HtMcs7"),
2398 "ControlMode",
2399 StringValue("HtMcs7"));
2400
2401 WifiMacHelper mac;
2402 NetDeviceContainer apDevice;
2403 phy.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}"));
2404 mac.SetType("ns3::ApWifiMac", "EnableBeaconJitter", BooleanValue(false));
2405 apDevice = wifi.Install(phy, mac, wifiApNode);
2406
2407 NetDeviceContainer staDevice;
2408 mac.SetType("ns3::StaWifiMac");
2409 staDevice = wifi.Install(phy, mac, wifiStaNode);
2410
2411 // Assign fixed streams to random variables in use
2412 WifiHelper::AssignStreams(apDevice, streamNumber);
2413 WifiHelper::AssignStreams(staDevice, streamNumber);
2414
2415 MobilityHelper mobility;
2417 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2418 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
2419 mobility.SetPositionAllocator(positionAlloc);
2420
2421 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2422 mobility.Install(wifiApNode);
2423 mobility.Install(wifiStaNode);
2424
2425 auto rxErrorModel = CreateObject<ListErrorModel>();
2426 Ptr<WifiMac> wifiMac;
2427 switch (rcvErrorType)
2428 {
2429 case AP:
2430 wifiMac = DynamicCast<WifiNetDevice>(apDevice.Get(0))->GetMac();
2431 break;
2432 case STA:
2433 wifiMac = DynamicCast<WifiNetDevice>(staDevice.Get(0))->GetMac();
2434 break;
2435 default:
2436 NS_ABORT_MSG("Station type " << +rcvErrorType << " cannot be used here");
2437 }
2438 wifiMac->GetWifiPhy(0)->SetPostReceptionErrorModel(rxErrorModel);
2439
2441 "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/MonitorSnifferRx",
2443 Config::Connect("/NodeList/*/DeviceList/*/Phy/State/RxError",
2445 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/BE_Txop/"
2446 "BlockAckManager/AgreementState",
2448 Config::Connect("/NodeList/" + std::to_string(rcvErrorType == STA ? 0 /* AP */ : 1 /* STA */) +
2449 "/DeviceList/*/$ns3::WifiNetDevice/Phys/0/PhyTxPsduBegin",
2450 MakeCallback(&Bug2470TestCase::TxCallback, this).Bind(rxErrorModel));
2451
2454 this,
2455 1,
2456 apDevice.Get(0),
2457 staDevice.Get(0)->GetAddress());
2460 this,
2461 4,
2462 apDevice.Get(0),
2463 staDevice.Get(0)->GetAddress());
2466 this,
2467 1,
2468 apDevice.Get(0),
2469 staDevice.Get(0)->GetAddress());
2472 this,
2473 4,
2474 apDevice.Get(0),
2475 staDevice.Get(0)->GetAddress());
2476
2480}
2481
2482void
2484{
2485 {
2486 RunSubtest(STA);
2487 NS_TEST_ASSERT_MSG_EQ(m_failedActionCount, 7, "ADDBA request packets are not failed");
2488 // There are two sets of 5 packets to be transmitted. The first 5 packets should be sent by
2489 // normal MPDU because of failed ADDBA handshake. For the second set, the first packet
2490 // should be sent by normal MPDU, and the rest with A-MPDU. In total we expect to receive 6
2491 // normal MPDU packets and 4 A-MPDU packet.
2493 6,
2494 "Receiving incorrect number of normal MPDU packet on subtest 1");
2496 4,
2497 "Receiving incorrect number of A-MPDU packets on subtest 1");
2498
2500 1,
2501 "Incorrect number of times the ADDBA state machine was in "
2502 "established state on subtest 1");
2505 2,
2506 "Incorrect number of times the ADDBA state machine was in pending state on subtest 1");
2509 0,
2510 "Incorrect number of times the ADDBA state machine was in rejected state on subtest 1");
2513 1,
2514 "Incorrect number of times the ADDBA state machine was in no_reply state on subtest 1");
2517 1,
2518 "Incorrect number of times the ADDBA state machine was in reset state on subtest 1");
2519 }
2520
2529
2530 {
2531 RunSubtest(AP);
2532 NS_TEST_ASSERT_MSG_EQ(m_failedActionCount, 7, "ADDBA response packets are not failed");
2533 // Similar to subtest 1, we also expect to receive 6 normal MPDU packets and 4 A-MPDU
2534 // packets.
2536 6,
2537 "Receiving incorrect number of normal MPDU packet on subtest 2");
2539 4,
2540 "Receiving incorrect number of A-MPDU packet on subtest 2");
2541
2543 1,
2544 "Incorrect number of times the ADDBA state machine was in "
2545 "established state on subtest 2");
2548 2,
2549 "Incorrect number of times the ADDBA state machine was in pending state on subtest 2");
2552 0,
2553 "Incorrect number of times the ADDBA state machine was in rejected state on subtest 2");
2556 1,
2557 "Incorrect number of times the ADDBA state machine was in no_reply state on subtest 2");
2560 1,
2561 "Incorrect number of times the ADDBA state machine was in reset state on subtest 2");
2562 }
2563
2564 // TODO: In the second test set, it does not go to reset state since ADDBA response is received
2565 // after timeout (NO_REPLY) but before it does not enter RESET state. More tests should be
2566 // written to verify all possible scenarios.
2567}
2568
2569//-----------------------------------------------------------------------------
2570/**
2571 * Make sure that Ideal rate manager recovers when the station is moving away from the access point.
2572 *
2573 * The scenario considers an access point and a moving station.
2574 * Initially, the station is located at 1 meter from the access point.
2575 * After 1s, the station moves away from the access for 0.5s to
2576 * reach a point away of 50 meters from the access point.
2577 * The tests checks the Ideal rate manager is reset once it has
2578 * failed to transmit a data packet, so that the next data packets
2579 * can be successfully transmitted using a lower modulation.
2580 *
2581 * See \issueid{40}
2582 */
2583
2585{
2586 public:
2588 ~Issue40TestCase() override;
2589 void DoRun() override;
2590
2591 private:
2592 /**
2593 * Run one function
2594 * @param useAmpdu flag to indicate whether the test should be run with A-MPDU
2595 */
2596 void RunOne(bool useAmpdu);
2597
2598 /**
2599 * Callback when packet is successfully received
2600 * @param context node context
2601 * @param p the received packet
2602 */
2603 void RxSuccessCallback(std::string context, Ptr<const Packet> p);
2604 /**
2605 * Triggers the arrival of 1000 Byte-long packets in the source device
2606 * @param numPackets number of packets in burst
2607 * @param sourceDevice pointer to the source NetDevice
2608 * @param destination address of the destination device
2609 */
2610 void SendPackets(uint8_t numPackets, Ptr<NetDevice> sourceDevice, Address& destination);
2611 /**
2612 * Transmit final data failed function
2613 * @param context the context
2614 * @param address the MAC address
2615 */
2616 void TxFinalDataFailedCallback(std::string context, Mac48Address address);
2617
2618 uint16_t m_rxCount; ///< Count number of successfully received data packets
2619 uint16_t m_txCount; ///< Count number of transmitted data packets
2620 uint16_t
2621 m_txMacFinalDataFailedCount; ///< Count number of unsuccessfuly transmitted data packets
2622};
2623
2625 : TestCase("Test case for issue #40"),
2626 m_rxCount(0),
2627 m_txCount(0),
2628 m_txMacFinalDataFailedCount(0)
2629{
2630}
2631
2635
2636void
2638{
2639 m_rxCount++;
2640}
2641
2642void
2643Issue40TestCase::SendPackets(uint8_t numPackets, Ptr<NetDevice> sourceDevice, Address& destination)
2644{
2645 for (uint8_t i = 0; i < numPackets; i++)
2646 {
2647 Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
2648 sourceDevice->Send(pkt, destination, 0);
2649 m_txCount++;
2650 }
2651}
2652
2653void
2658
2659void
2661{
2662 m_rxCount = 0;
2663 m_txCount = 0;
2665
2668 int64_t streamNumber = 100;
2669
2670 NodeContainer wifiApNode;
2671 NodeContainer wifiStaNode;
2672 wifiApNode.Create(1);
2673 wifiStaNode.Create(1);
2674
2677 phy.SetChannel(channel.Create());
2678
2679 WifiHelper wifi;
2680 // use HT standard so that BlockAck agreement is not established in the useAmpdu false case
2681 wifi.SetStandard(useAmpdu ? WIFI_STANDARD_80211ac : WIFI_STANDARD_80211n);
2682 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
2683
2684 WifiMacHelper mac;
2685 NetDeviceContainer apDevice;
2686 mac.SetType("ns3::ApWifiMac");
2687 apDevice = wifi.Install(phy, mac, wifiApNode);
2688
2689 NetDeviceContainer staDevice;
2690 mac.SetType("ns3::StaWifiMac");
2691 staDevice = wifi.Install(phy, mac, wifiStaNode);
2692
2693 // Assign fixed streams to random variables in use
2694 WifiHelper::AssignStreams(apDevice, streamNumber);
2695 WifiHelper::AssignStreams(staDevice, streamNumber);
2696
2697 MobilityHelper mobility;
2699 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2700 positionAlloc->Add(Vector(10.0, 0.0, 0.0));
2701 mobility.SetPositionAllocator(positionAlloc);
2702
2703 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2704 mobility.Install(wifiApNode);
2705
2706 mobility.SetMobilityModel("ns3::WaypointMobilityModel");
2707 mobility.Install(wifiStaNode);
2708
2709 Config::Connect("/NodeList/*/DeviceList/*/RemoteStationManager/MacTxFinalDataFailed",
2711 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/MacRx",
2713
2714 Ptr<WaypointMobilityModel> staWaypointMobility =
2716 staWaypointMobility->AddWaypoint(Waypoint(Seconds(1), Vector(10.0, 0.0, 0.0)));
2717 staWaypointMobility->AddWaypoint(Waypoint(Seconds(1.5), Vector(50.0, 0.0, 0.0)));
2718
2719 if (useAmpdu)
2720 {
2721 // Disable use of BAR that are sent with the lowest modulation so that we can also reproduce
2722 // the problem with A-MPDU, i.e. the lack of feedback about SNR change
2723 Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice>(apDevice.Get(0));
2724 PointerValue ptr;
2725 ap_device->GetMac()->GetAttribute("BE_Txop", ptr);
2726 ptr.Get<QosTxop>()->SetAttribute("UseExplicitBarAfterMissedBlockAck", BooleanValue(false));
2727 }
2728
2729 // Transmit a first data packet before the station moves: it should be sent with a high
2730 // modulation and successfully received
2733 this,
2734 useAmpdu ? 2 : 1,
2735 apDevice.Get(0),
2736 staDevice.Get(0)->GetAddress());
2737
2738 // Transmit a second data packet once the station is away from the access point: it should be
2739 // sent with the same high modulation and be unsuccessfuly received
2742 this,
2743 useAmpdu ? 2 : 1,
2744 apDevice.Get(0),
2745 staDevice.Get(0)->GetAddress());
2746
2747 // Keep on transmitting data packets while the station is away from the access point: it should
2748 // be sent with a lower modulation and be successfully received
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());
2763 this,
2764 useAmpdu ? 2 : 1,
2765 apDevice.Get(0),
2766 staDevice.Get(0)->GetAddress());
2769 this,
2770 useAmpdu ? 2 : 1,
2771 apDevice.Get(0),
2772 staDevice.Get(0)->GetAddress());
2775 this,
2776 useAmpdu ? 2 : 1,
2777 apDevice.Get(0),
2778 staDevice.Get(0)->GetAddress());
2779
2782
2784 (useAmpdu ? 14 : 7),
2785 "Incorrect number of transmitted packets");
2787 (useAmpdu ? 12 : 6),
2788 "Incorrect number of successfully received packets");
2790 (useAmpdu ? 2 : 1),
2791 "Incorrect number of dropped TX packets");
2792
2794}
2795
2796void
2798{
2799 // Test without A-MPDU
2800 RunOne(false);
2801
2802 // Test with A-MPDU
2803 RunOne(true);
2804}
2805
2806//-----------------------------------------------------------------------------
2807/**
2808 * Make sure that Ideal rate manager is able to handle non best-effort traffic.
2809 *
2810 * The scenario considers an access point and a fixed station.
2811 * The station first sends a best-effort packet to the access point,
2812 * for which Ideal rate manager should select a VHT rate. Then,
2813 * the station sends a non best-effort (voice) packet to the access point,
2814 * and since SNR is unchanged, the same VHT rate should be used.
2815 *
2816 * See \issueid{169}
2817 */
2818
2820{
2821 public:
2823 ~Issue169TestCase() override;
2824 void DoRun() override;
2825
2826 private:
2827 /**
2828 * Triggers the transmission of a 1000 Byte-long data packet from the source device
2829 * @param numPackets number of packets in burst
2830 * @param sourceDevice pointer to the source NetDevice
2831 * @param destination address of the destination device
2832 * @param priority the priority of the packets to send
2833 */
2834 void SendPackets(uint8_t numPackets,
2835 Ptr<NetDevice> sourceDevice,
2836 Address& destination,
2837 uint8_t priority);
2838
2839 /**
2840 * Callback that indicates a PSDU is being transmitted
2841 * @param context the context
2842 * @param psdus the PSDU map to transmit
2843 * @param txVector the TX vector
2844 * @param txPowerW the TX power (W)
2845 */
2846 void TxCallback(std::string context,
2847 WifiConstPsduMap psdus,
2848 WifiTxVector txVector,
2849 double txPowerW);
2850};
2851
2853 : TestCase("Test case for issue #169")
2854{
2855}
2856
2860
2861void
2863 Ptr<NetDevice> sourceDevice,
2864 Address& destination,
2865 uint8_t priority)
2866{
2867 SocketPriorityTag priorityTag;
2868 priorityTag.SetPriority(priority);
2869 for (uint8_t i = 0; i < numPackets; i++)
2870 {
2871 Ptr<Packet> packet = Create<Packet>(1000); // 1000 dummy bytes of data
2872 packet->AddPacketTag(priorityTag);
2873 sourceDevice->Send(packet, destination, 0);
2874 }
2875}
2876
2877void
2879 WifiConstPsduMap psdus,
2880 WifiTxVector txVector,
2881 double txPowerW)
2882{
2883 if (psdus.begin()->second->GetSize() >= 1000)
2884 {
2886 WifiModulationClass::WIFI_MOD_CLASS_VHT,
2887 "Ideal rate manager selected incorrect modulation class");
2888 }
2889}
2890
2891void
2893{
2896 int64_t streamNumber = 100;
2897
2898 NodeContainer wifiApNode;
2899 NodeContainer wifiStaNode;
2900 wifiApNode.Create(1);
2901 wifiStaNode.Create(1);
2902
2905 phy.SetChannel(channel.Create());
2906
2907 WifiHelper wifi;
2908 wifi.SetStandard(WIFI_STANDARD_80211ac);
2909 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
2910
2911 WifiMacHelper mac;
2912 NetDeviceContainer apDevice;
2913 mac.SetType("ns3::ApWifiMac");
2914 apDevice = wifi.Install(phy, mac, wifiApNode);
2915
2916 NetDeviceContainer staDevice;
2917 mac.SetType("ns3::StaWifiMac");
2918 staDevice = wifi.Install(phy, mac, wifiStaNode);
2919
2920 // Assign fixed streams to random variables in use
2921 WifiHelper::AssignStreams(apDevice, streamNumber);
2922 WifiHelper::AssignStreams(staDevice, streamNumber);
2923
2924 MobilityHelper mobility;
2926 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2927 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
2928 mobility.SetPositionAllocator(positionAlloc);
2929
2930 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2931 mobility.Install(wifiApNode);
2932 mobility.Install(wifiStaNode);
2933
2934 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
2936
2937 // Send best-effort packet (i.e. priority 0)
2940 this,
2941 1,
2942 apDevice.Get(0),
2943 staDevice.Get(0)->GetAddress(),
2944 0);
2945
2946 // Send non best-effort (voice) packet (i.e. priority 6)
2949 this,
2950 1,
2951 apDevice.Get(0),
2952 staDevice.Get(0)->GetAddress(),
2953 6);
2954
2957
2959}
2960
2961//-----------------------------------------------------------------------------
2962/**
2963 * Make sure that Ideal rate manager properly selects MCS based on the configured channel width.
2964 *
2965 * The scenario considers an access point and a fixed station.
2966 * The access point first sends a 80 MHz PPDU to the station,
2967 * for which Ideal rate manager should select VH-MCS 0 based
2968 * on the distance (no interference generated in this test). Then,
2969 * the access point sends a 20 MHz PPDU to the station,
2970 * which corresponds to a SNR 6 dB higher than previously, hence
2971 * VHT-MCS 2 should be selected. Finally, the access point sends a
2972 * 40 MHz PPDU to the station, which means corresponds to a SNR 3 dB
2973 * lower than previously, hence VHT-MCS 1 should be selected.
2974 */
2975
2977{
2978 public:
2981 void DoRun() override;
2982
2983 private:
2984 /**
2985 * Change the configured channel width for all nodes
2986 * @param channelWidth the channel width
2987 */
2988 void ChangeChannelWidth(MHz_u channelWidth);
2989
2990 /**
2991 * Triggers the transmission of a 1000 Byte-long data packet from the source device
2992 * @param sourceDevice pointer to the source NetDevice
2993 * @param destination address of the destination device
2994 */
2995 void SendPacket(Ptr<NetDevice> sourceDevice, Address& destination);
2996
2997 /**
2998 * Callback that indicates a PSDU is being transmitted
2999 * @param context the context
3000 * @param psduMap the PSDU map to transmit
3001 * @param txVector the TX vector
3002 * @param txPowerW the TX power (W)
3003 */
3004 void TxCallback(std::string context,
3005 WifiConstPsduMap psduMap,
3006 WifiTxVector txVector,
3007 double txPowerW);
3008
3009 /**
3010 * Check if the selected WifiMode is correct
3011 * @param expectedMode the expected WifiMode
3012 */
3013 void CheckLastSelectedMode(WifiMode expectedMode);
3014
3015 WifiMode m_txMode; ///< Store the last selected mode to send data packet
3016};
3017
3019 : TestCase("Test case for use of channel bonding with Ideal rate manager")
3020{
3021}
3022
3026
3027void
3029{
3030 Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelSettings",
3031 StringValue("{0, " + std::to_string(static_cast<uint16_t>(channelWidth)) +
3032 ", BAND_5GHZ, 0}"));
3033}
3034
3035void
3037{
3038 Ptr<Packet> packet = Create<Packet>(1000);
3039 sourceDevice->Send(packet, destination, 0);
3040}
3041
3042void
3044 WifiConstPsduMap psduMap,
3045 WifiTxVector txVector,
3046 double txPowerW)
3047{
3048 if (psduMap.begin()->second->GetSize() >= 1000)
3049 {
3050 m_txMode = txVector.GetMode();
3051 }
3052}
3053
3054void
3056{
3058 expectedMode,
3059 "Last selected WifiMode "
3060 << m_txMode << " does not match expected WifiMode " << expectedMode);
3061}
3062
3063void
3065{
3068 int64_t streamNumber = 100;
3069
3070 NodeContainer wifiApNode;
3071 NodeContainer wifiStaNode;
3072 wifiApNode.Create(1);
3073 wifiStaNode.Create(1);
3074
3077 phy.SetChannel(channel.Create());
3078
3079 WifiHelper wifi;
3080 wifi.SetStandard(WIFI_STANDARD_80211ac);
3081 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
3082
3083 WifiMacHelper mac;
3084 NetDeviceContainer apDevice;
3085 mac.SetType("ns3::ApWifiMac");
3086 apDevice = wifi.Install(phy, mac, wifiApNode);
3087
3088 NetDeviceContainer staDevice;
3089 mac.SetType("ns3::StaWifiMac");
3090 staDevice = wifi.Install(phy, mac, wifiStaNode);
3091
3092 // Assign fixed streams to random variables in use
3093 WifiHelper::AssignStreams(apDevice, streamNumber);
3094 WifiHelper::AssignStreams(staDevice, streamNumber);
3095
3096 MobilityHelper mobility;
3098 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
3099 positionAlloc->Add(Vector(50.0, 0.0, 0.0));
3100 mobility.SetPositionAllocator(positionAlloc);
3101
3102 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
3103 mobility.Install(wifiApNode);
3104 mobility.Install(wifiStaNode);
3105
3106 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
3108
3109 // Set channel width to 80 MHz & send packet
3112 this,
3113 MHz_u{80});
3116 this,
3117 apDevice.Get(0),
3118 staDevice.Get(0)->GetAddress());
3119 // Selected rate should be VHT-MCS 1
3122 this,
3124
3125 // Set channel width to 20 MHz & send packet
3128 this,
3129 MHz_u{20});
3132 this,
3133 apDevice.Get(0),
3134 staDevice.Get(0)->GetAddress());
3135 // Selected rate should be VHT-MCS 3 since SNR should be 6 dB higher than previously
3138 this,
3140
3141 // Set channel width to 40 MHz & send packet
3144 this,
3145 MHz_u{40});
3148 this,
3149 apDevice.Get(0),
3150 staDevice.Get(0)->GetAddress());
3151 // Selected rate should be VHT-MCS 2 since SNR should be 3 dB lower than previously
3154 this,
3156
3159
3161}
3162
3163//-----------------------------------------------------------------------------
3164/**
3165 * Test to validate that Ideal rate manager properly selects TXVECTOR in scenarios where MIMO is
3166 * used. The test consider both balanced and unbalanced MIMO settings, and verify ideal picks the
3167 * correct number of spatial streams and the correct MCS, taking into account potential diversity in
3168 * AWGN channels when the number of antenna at the receiver is higher than the number of spatial
3169 * streams used for the transmission.
3170 */
3171
3173{
3174 public:
3176 ~IdealRateManagerMimoTest() override;
3177 void DoRun() override;
3178
3179 private:
3180 /**
3181 * Change the configured MIMO settings for AP node
3182 * @param antennas the number of active antennas
3183 * @param maxStreams the maximum number of allowed spatial streams
3184 */
3185 void SetApMimoSettings(uint8_t antennas, uint8_t maxStreams);
3186 /**
3187 * Change the configured MIMO settings for STA node
3188 * @param antennas the number of active antennas
3189 * @param maxStreams the maximum number of allowed spatial streams
3190 */
3191 void SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams);
3192 /**
3193 * Triggers the transmission of a 1000 Byte-long data packet from the source device
3194 * @param sourceDevice pointer to the source NetDevice
3195 * @param destination address of the destination device
3196 */
3197 void SendPacket(Ptr<NetDevice> sourceDevice, Address& destination);
3198
3199 /**
3200 * Callback that indicates a PSDU is being transmitted
3201 * @param context the context
3202 * @param psdus the PSDU map to transmit
3203 * @param txVector the TX vector
3204 * @param txPowerW the TX power (W)
3205 */
3206 void TxCallback(std::string context,
3207 WifiConstPsduMap psdus,
3208 WifiTxVector txVector,
3209 double txPowerW);
3210
3211 /**
3212 * Check if the selected WifiMode is correct
3213 * @param expectedMode the expected WifiMode
3214 */
3215 void CheckLastSelectedMode(WifiMode expectedMode);
3216 /**
3217 * Check if the selected Nss is correct
3218 * @param expectedNss the expected Nss
3219 */
3220 void CheckLastSelectedNss(uint8_t expectedNss);
3221
3222 WifiTxVector m_txVector; ///< Store the last TXVECTOR used to transmit Data
3223};
3224
3226 : TestCase("Test case for use of imbalanced MIMO settings with Ideal rate manager")
3227{
3228}
3229
3233
3234void
3235IdealRateManagerMimoTest::SetApMimoSettings(uint8_t antennas, uint8_t maxStreams)
3236{
3237 Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/Antennas",
3238 UintegerValue(antennas));
3239 Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedTxSpatialStreams",
3240 UintegerValue(maxStreams));
3241 Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedRxSpatialStreams",
3242 UintegerValue(maxStreams));
3243}
3244
3245void
3246IdealRateManagerMimoTest::SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams)
3247{
3248 Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/Antennas",
3249 UintegerValue(antennas));
3250 Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedTxSpatialStreams",
3251 UintegerValue(maxStreams));
3252 Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedRxSpatialStreams",
3253 UintegerValue(maxStreams));
3254}
3255
3256void
3258{
3259 Ptr<Packet> packet = Create<Packet>(1000);
3260 sourceDevice->Send(packet, destination, 0);
3261}
3262
3263void
3265 WifiConstPsduMap psdus,
3266 WifiTxVector txVector,
3267 double txPowerW)
3268{
3269 if (psdus.begin()->second->GetSize() >= 1000)
3270 {
3271 m_txVector = txVector;
3272 }
3273}
3274
3275void
3277{
3279 expectedNss,
3280 "Last selected Nss " << m_txVector.GetNss()
3281 << " does not match expected Nss " << expectedNss);
3282}
3283
3284void
3286{
3288 expectedMode,
3289 "Last selected WifiMode " << m_txVector.GetMode()
3290 << " does not match expected WifiMode "
3291 << expectedMode);
3292}
3293
3294void
3296{
3299 int64_t streamNumber = 100;
3300
3301 NodeContainer wifiApNode;
3302 NodeContainer wifiStaNode;
3303 wifiApNode.Create(1);
3304 wifiStaNode.Create(1);
3305
3308 phy.SetChannel(channel.Create());
3309
3310 WifiHelper wifi;
3311 wifi.SetStandard(WIFI_STANDARD_80211ac);
3312 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
3313
3314 WifiMacHelper mac;
3315 NetDeviceContainer apDevice;
3316 mac.SetType("ns3::ApWifiMac");
3317 apDevice = wifi.Install(phy, mac, wifiApNode);
3318
3319 NetDeviceContainer staDevice;
3320 mac.SetType("ns3::StaWifiMac");
3321 staDevice = wifi.Install(phy, mac, wifiStaNode);
3322
3323 // Assign fixed streams to random variables in use
3324 WifiHelper::AssignStreams(apDevice, streamNumber);
3325 WifiHelper::AssignStreams(staDevice, streamNumber);
3326
3327 MobilityHelper mobility;
3329 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
3330 positionAlloc->Add(Vector(40.0, 0.0, 0.0));
3331 mobility.SetPositionAllocator(positionAlloc);
3332
3333 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
3334 mobility.Install(wifiApNode);
3335 mobility.Install(wifiStaNode);
3336
3337 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
3339
3340 // TX: 1 antenna
3342 // RX: 1 antenna
3344 // Send packets (2 times to get one feedback)
3347 this,
3348 apDevice.Get(0),
3349 staDevice.Get(0)->GetAddress());
3352 this,
3353 apDevice.Get(0),
3354 staDevice.Get(0)->GetAddress());
3355 // Selected NSS should be 1 since both TX and RX support a single antenna
3357 // Selected rate should be VHT-MCS 2 because of settings and distance between TX and RX
3360 this,
3362
3363 // TX: 1 antenna
3365 // RX: 2 antennas, but only supports 1 spatial stream
3367 // Send packets (2 times to get one feedback)
3370 this,
3371 apDevice.Get(0),
3372 staDevice.Get(0)->GetAddress());
3375 this,
3376 apDevice.Get(0),
3377 staDevice.Get(0)->GetAddress());
3378 // Selected NSS should be 1 since both TX and RX support a single antenna
3380 // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3381 // improvement of about 3dB
3384 this,
3386
3387 // TX: 1 antenna
3389 // RX: 2 antennas, and supports 2 spatial streams
3391 // Send packets (2 times to get one feedback)
3394 this,
3395 apDevice.Get(0),
3396 staDevice.Get(0)->GetAddress());
3399 this,
3400 apDevice.Get(0),
3401 staDevice.Get(0)->GetAddress());
3402 // Selected NSS should be 1 since TX supports a single antenna
3404 // Selected rate should be as previously
3407 this,
3409
3410 // TX: 2 antennas, but only supports 1 spatial stream
3412 // RX: 1 antenna
3414 // Send packets (2 times to get one feedback)
3417 this,
3418 apDevice.Get(0),
3419 staDevice.Get(0)->GetAddress());
3422 this,
3423 apDevice.Get(0),
3424 staDevice.Get(0)->GetAddress());
3425 // Selected NSS should be 1 since both TX and RX support a single antenna
3427 // Selected rate should be VHT-MCS 2 because we do no longer have diversity in this scenario
3428 // (more antennas at TX does not result in SNR improvement in AWGN channel)
3431 this,
3433
3434 // TX: 2 antennas, but only supports 1 spatial stream
3436 // RX: 2 antennas, but only supports 1 spatial stream
3438 // Send packets (2 times to get one feedback)
3441 this,
3442 apDevice.Get(0),
3443 staDevice.Get(0)->GetAddress());
3446 this,
3447 apDevice.Get(0),
3448 staDevice.Get(0)->GetAddress());
3449 // Selected NSS should be 1 since both TX and RX support a single antenna
3451 // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3452 // improvement of about 3dB (more antennas at TX does not result in SNR improvement in AWGN
3453 // channel)
3456 this,
3458
3459 // TX: 2 antennas, but only supports 1 spatial stream
3461 // RX: 2 antennas, and supports 2 spatial streams
3463 // Send packets (2 times to get one feedback)
3466 this,
3467 apDevice.Get(0),
3468 staDevice.Get(0)->GetAddress());
3471 this,
3472 apDevice.Get(0),
3473 staDevice.Get(0)->GetAddress());
3474 // Selected NSS should be 1 since TX supports a single antenna
3476 // Selected rate should be as previously
3479 this,
3481
3482 // TX: 2 antennas, and supports 2 spatial streams
3484 // RX: 1 antenna
3486 // Send packets (2 times to get one feedback)
3489 this,
3490 apDevice.Get(0),
3491 staDevice.Get(0)->GetAddress());
3494 this,
3495 apDevice.Get(0),
3496 staDevice.Get(0)->GetAddress());
3497 // Selected NSS should be 1 since RX supports a single antenna
3499 // Selected rate should be VHT-MCS 2 because we do no longer have diversity in this scenario
3500 // (more antennas at TX does not result in SNR improvement in AWGN channel)
3503 this,
3505
3506 // TX: 2 antennas, and supports 2 spatial streams
3508 // RX: 2 antennas, but only supports 1 spatial stream
3510 // Send packets (2 times to get one feedback)
3513 this,
3514 apDevice.Get(0),
3515 staDevice.Get(0)->GetAddress());
3518 this,
3519 apDevice.Get(0),
3520 staDevice.Get(0)->GetAddress());
3521 // Selected NSS should be 1 since RX supports a single antenna
3523 // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3524 // improvement of about 3dB (more antennas at TX does not result in SNR improvement in AWGN
3525 // channel)
3528 this,
3530
3531 // TX: 2 antennas, and supports 2 spatial streams
3533 // RX: 2 antennas, and supports 2 spatial streams
3535 // Send packets (2 times to get one feedback)
3538 this,
3539 apDevice.Get(0),
3540 staDevice.Get(0)->GetAddress());
3543 this,
3544 apDevice.Get(0),
3545 staDevice.Get(0)->GetAddress());
3546 // Selected NSS should be 2 since both TX and RX support 2 antennas
3548 // Selected rate should be the same as without diversity, as it uses 2 spatial streams so there
3549 // is no more benefits from diversity in AWGN channels
3552 this,
3554
3555 // Verify we can go back to initial situation
3560 this,
3561 apDevice.Get(0),
3562 staDevice.Get(0)->GetAddress());
3566 this,
3568
3569 Simulator::Stop(Seconds(10.2));
3572}
3573
3574//-----------------------------------------------------------------------------
3575/**
3576 * @ingroup wifi-test
3577 * @ingroup tests
3578 *
3579 * @brief Data rate verification test for MCSs of different RU sizes
3580 */
3582{
3583 public:
3585
3586 private:
3587 /**
3588 * Compare the data rate computed for the provided combination with standard defined one.
3589 * @param ruType the RU type
3590 * @param mcs the modulation and coding scheme (as a string, e.g. HeMcs0)
3591 * @param nss the number of spatial streams
3592 * @param guardInterval the guard interval to use
3593 * @param expectedDataRate the expected data rate in 100 kbps units (minimum granularity in
3594 * standard tables)
3595 * @returns true if data rates are the same, false otherwise
3596 */
3597 bool CheckDataRate(RuType ruType,
3598 std::string mcs,
3599 uint8_t nss,
3600 Time guardInterval,
3601 uint16_t expectedDataRate);
3602 void DoRun() override;
3603};
3604
3606 : TestCase("Check data rates for different RU types.")
3607{
3608}
3609
3610bool
3612 std::string mcs,
3613 uint8_t nss,
3614 Time guardInterval,
3615 uint16_t expectedDataRate)
3616{
3617 uint8_t staId = 1;
3618 auto txVector = WifiTxVector(HePhy::GetHeMcs(0),
3619 0,
3621 guardInterval,
3622 1,
3623 1,
3624 0,
3625 MHz_u{160},
3626 false,
3627 false);
3628 WifiMode mode(mcs);
3629 txVector.SetMode(mode, staId);
3630 txVector.SetNss(nss, staId);
3631 HeRu::RuSpec ru(ruType, 1, true);
3632 txVector.SetRu(ru, staId);
3633 uint64_t dataRate = round(mode.GetDataRate(txVector, staId) / 100000.0);
3634 NS_ABORT_MSG_IF(dataRate > 65535, "Rate is way too high");
3635 if (static_cast<uint16_t>(dataRate) != expectedDataRate)
3636 {
3637 std::cerr << "RU=" << ruType << " mode=" << mode << " Nss=" << +nss
3638 << " guardInterval=" << guardInterval << " expected=" << expectedDataRate
3639 << " x100kbps"
3640 << " computed=" << static_cast<uint16_t>(dataRate) << " x100kbps" << std::endl;
3641 return false;
3642 }
3643 return true;
3644}
3645
3646void
3648{
3649 bool retval = true;
3650
3651 // 26-tone RU, browse over all MCSs, GIs and Nss's (up to 4, current max)
3652 retval = retval && CheckDataRate(RuType::RU_26_TONE, "HeMcs0", 1, NanoSeconds(800), 9) &&
3653 CheckDataRate(RuType::RU_26_TONE, "HeMcs1", 1, NanoSeconds(1600), 17) &&
3654 CheckDataRate(RuType::RU_26_TONE, "HeMcs2", 1, NanoSeconds(3200), 23) &&
3655 CheckDataRate(RuType::RU_26_TONE, "HeMcs3", 1, NanoSeconds(3200), 30) &&
3656 CheckDataRate(RuType::RU_26_TONE, "HeMcs4", 2, NanoSeconds(1600), 100) &&
3657 CheckDataRate(RuType::RU_26_TONE, "HeMcs5", 3, NanoSeconds(1600), 200) &&
3658 CheckDataRate(RuType::RU_26_TONE, "HeMcs6", 4, NanoSeconds(1600), 300) &&
3659 CheckDataRate(RuType::RU_26_TONE, "HeMcs7", 4, NanoSeconds(3200), 300) &&
3660 CheckDataRate(RuType::RU_26_TONE, "HeMcs8", 4, NanoSeconds(1600), 400) &&
3661 CheckDataRate(RuType::RU_26_TONE, "HeMcs9", 4, NanoSeconds(3200), 400) &&
3662 CheckDataRate(RuType::RU_26_TONE, "HeMcs10", 4, NanoSeconds(1600), 500) &&
3663 CheckDataRate(RuType::RU_26_TONE, "HeMcs11", 4, NanoSeconds(3200), 500);
3664
3666 retval,
3667 true,
3668 "26-tone RU data rate verification for different MCSs, GIs, and Nss's failed");
3669
3670 // Check other RU sizes
3671 retval = retval && CheckDataRate(RuType::RU_52_TONE, "HeMcs2", 1, NanoSeconds(1600), 50) &&
3672 CheckDataRate(RuType::RU_106_TONE, "HeMcs9", 1, NanoSeconds(800), 500) &&
3673 CheckDataRate(RuType::RU_242_TONE, "HeMcs5", 1, NanoSeconds(1600), 650) &&
3674 CheckDataRate(RuType::RU_484_TONE, "HeMcs3", 1, NanoSeconds(1600), 650) &&
3675 CheckDataRate(RuType::RU_996_TONE, "HeMcs5", 1, NanoSeconds(3200), 2450) &&
3676 CheckDataRate(RuType::RU_2x996_TONE, "HeMcs3", 1, NanoSeconds(3200), 2450);
3677
3678 NS_TEST_EXPECT_MSG_EQ(retval,
3679 true,
3680 "Data rate verification for RUs above 52-tone RU (included) failed");
3681}
3682
3683/// List of Information Elements included in the test management frame
3685 std::tuple<SupportedRates, std::optional<ExtendedSupportedRatesIE>, std::vector<Ssid>>;
3686
3687/**
3688 * @ingroup wifi-test
3689 * @ingroup tests
3690 *
3691 * @brief Test management header
3692 */
3693class MgtTestHeader : public WifiMgtHeader<MgtTestHeader, MgtTestElems>
3694{
3695 public:
3696 ~MgtTestHeader() override = default;
3697
3698 /**
3699 * Register this type.
3700 * @return The TypeId.
3701 */
3702 static TypeId GetTypeId();
3703
3704 /**
3705 * @return the TypeId for this object.
3706 */
3707 TypeId GetInstanceTypeId() const override;
3708
3709 using WifiMgtHeader<MgtTestHeader, MgtTestElems>::GetSerializedSize;
3710 using WifiMgtHeader<MgtTestHeader, MgtTestElems>::Serialize;
3711 using WifiMgtHeader<MgtTestHeader, MgtTestElems>::Deserialize;
3712};
3713
3714TypeId
3716{
3717 static TypeId tid = TypeId("ns3::MgtTestHeader")
3718 .SetParent<Header>()
3719 .SetGroupName("Wifi")
3720 .AddConstructor<MgtTestHeader>();
3721 return tid;
3722}
3723
3724TypeId
3726{
3727 return GetTypeId();
3728}
3729
3730/**
3731 * @ingroup wifi-test
3732 * @ingroup tests
3733 *
3734 * @brief Mgt header (de)serialization Test Suite
3735 */
3737{
3738 public:
3740 ~WifiMgtHeaderTest() override = default;
3741
3742 private:
3743 void DoRun() override;
3744};
3745
3747 : HeaderSerializationTestCase("Check (de)serialization of a test management header")
3748{
3749}
3750
3751void
3753{
3754 MgtTestHeader frame;
3755
3756 // Add the mandatory Information Element (SupportedRates)
3757 AllSupportedRates allRates;
3758 allRates.AddSupportedRate(1000000);
3759 allRates.AddSupportedRate(2000000);
3760 allRates.AddSupportedRate(3000000);
3761 allRates.AddSupportedRate(4000000);
3762 allRates.AddSupportedRate(5000000);
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 false,
3772 "Expected no 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 more rates, so that the optional Information Element (ExtendedSupportedRatesIE) is added
3778 allRates.AddSupportedRate(6000000);
3779 allRates.AddSupportedRate(7000000);
3780 allRates.AddSupportedRate(8000000);
3781 allRates.AddSupportedRate(9000000);
3782 allRates.AddSupportedRate(10000000);
3783
3784 frame.Get<SupportedRates>() = allRates.rates;
3785 frame.Get<ExtendedSupportedRatesIE>() = allRates.extendedRates;
3786
3787 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3788 true,
3789 "Expected a SupportedRates IE to be included");
3790 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3791 true,
3792 "Expected an ExtendedSupportedRatesIE to be included");
3793 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 0, "Expected no Ssid IE to be included");
3794
3796
3797 // Add a first Ssid IE
3798 Ssid one("Ssid One");
3799 frame.Get<Ssid>().push_back(one);
3800
3801 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3802 true,
3803 "Expected a SupportedRates IE to be included");
3804 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3805 true,
3806 "Expected an ExtendedSupportedRatesIE to be included");
3807 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 1, "Expected one Ssid IE to be included");
3808 NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().front().PeekString()),
3809 "Ssid One",
3810 "Incorrect SSID");
3811
3813
3814 // Add a second Ssid IE
3815 frame.Get<Ssid>().emplace_back("Ssid Two");
3816
3817 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3818 true,
3819 "Expected a SupportedRates IE to be included");
3820 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3821 true,
3822 "Expected an ExtendedSupportedRatesIE to be included");
3823 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 2, "Expected two Ssid IEs to be included");
3824 NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().front().PeekString()),
3825 "Ssid One",
3826 "Incorrect first SSID");
3827 NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().back().PeekString()),
3828 "Ssid Two",
3829 "Incorrect second SSID");
3830
3832}
3833
3834//-----------------------------------------------------------------------------
3835
3836/**
3837 * Make sure that all DSSS modulation types work (see issue #1095).
3838 *
3839 * This test sends four packets from a STA to an AP, each with a different
3840 * DSSS rate (1, 2, 5.5, and 11Mbps), and checks that all four are received.
3841 */
3843{
3844 public:
3846
3847 void DoRun() override;
3848
3849 private:
3850 uint32_t m_received; ///< number of received packets
3851
3852 /**
3853 * Trace sink to receive from the PacketSocket; the address parameter is unused
3854 * @param context the context
3855 * @param p the received packet
3856 */
3857 void Receive(std::string context, Ptr<const Packet> p, const Address&);
3858};
3859
3861 : TestCase("Test case for Bug 730"),
3862 m_received(0)
3863{
3864}
3865
3866void
3868{
3869 m_received++;
3870}
3871
3872void
3874{
3875 m_received = 0;
3876
3877 NodeContainer wifiStaNode;
3878 wifiStaNode.Create(1);
3879
3880 NodeContainer wifiApNode;
3881 wifiApNode.Create(1);
3882
3883 auto channel = YansWifiChannelHelper::Default();
3885 phy.SetChannel(channel.Create());
3886
3887 WifiHelper wifi;
3888 wifi.SetStandard(WIFI_STANDARD_80211b);
3889 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
3890 "DataMode",
3891 StringValue("DsssRate1Mbps"),
3892 "ControlMode",
3893 StringValue("DsssRate1Mbps"));
3894
3895 WifiMacHelper mac;
3896 auto ssid = Ssid("ns-3-ssid");
3897 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid), "ActiveProbing", BooleanValue(false));
3898
3899 NetDeviceContainer staDevices;
3900 staDevices = wifi.Install(phy, mac, wifiStaNode);
3901
3902 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid), "BeaconGeneration", BooleanValue(true));
3903
3904 NetDeviceContainer apDevices;
3905 apDevices = wifi.Install(phy, mac, wifiApNode);
3906 auto apRemoteStationManager = apDevices.Get(0)
3907 ->GetObject<WifiNetDevice>()
3908 ->GetRemoteStationManager()
3910 apRemoteStationManager->SetAttribute("DataMode", StringValue("DsssRate1Mbps"));
3911
3912 MobilityHelper mobility;
3913 auto positionAlloc = CreateObject<ListPositionAllocator>();
3914
3915 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
3916 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
3917 mobility.SetPositionAllocator(positionAlloc);
3918
3919 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
3920 mobility.Install(wifiApNode);
3921 mobility.Install(wifiStaNode);
3922
3923 auto apDevice = DynamicCast<WifiNetDevice>(apDevices.Get(0));
3924 auto staDevice = DynamicCast<WifiNetDevice>(staDevices.Get(0));
3925
3926 PacketSocketAddress socket;
3927 socket.SetSingleDevice(staDevice->GetIfIndex());
3928 socket.SetPhysicalAddress(apDevice->GetAddress());
3929 socket.SetProtocol(1);
3930
3931 // give packet socket powers to nodes.
3932 PacketSocketHelper packetSocket;
3933 packetSocket.Install(wifiStaNode);
3934 packetSocket.Install(wifiApNode);
3935
3936 auto client = CreateObject<PacketSocketClient>();
3937 client->SetAttribute("PacketSize", UintegerValue(1460));
3938 client->SetAttribute("MaxPackets", UintegerValue(4));
3939 client->SetRemote(socket);
3940 wifiStaNode.Get(0)->AddApplication(client);
3941 client->SetStartTime(Seconds(1));
3942 client->SetStopTime(Seconds(4.5));
3943
3944 auto server = CreateObject<PacketSocketServer>();
3945 server->SetLocal(socket);
3946 wifiApNode.Get(0)->AddApplication(server);
3947 server->SetStartTime(Seconds(0));
3948 server->SetStopTime(Seconds(4.5));
3949
3950 Config::Connect("/NodeList/1/ApplicationList/0/$ns3::PacketSocketServer/Rx",
3952
3953 // The PacketSocketClient starts at time 1s, and packets are sent at times 1s, 2s, 3s, 4s.
3954 // Change the MCS in between these send times (e.g., at 1.5s, 2.5s, 3.5s)
3956 Seconds(1.5),
3958 "/NodeList/0/DeviceList/0/RemoteStationManager/$ns3::ConstantRateWifiManager/DataMode",
3959 StringValue("DsssRate2Mbps"));
3961 Seconds(2.5),
3963 "/NodeList/0/DeviceList/0/RemoteStationManager/$ns3::ConstantRateWifiManager/DataMode",
3964 StringValue("DsssRate5_5Mbps"));
3966 Seconds(3.5),
3968 "/NodeList/0/DeviceList/0/RemoteStationManager/$ns3::ConstantRateWifiManager/DataMode",
3969 StringValue("DsssRate11Mbps"));
3970
3973
3975
3976 NS_TEST_ASSERT_MSG_EQ(m_received, 4, "Did not receive four DSSS packets");
3977}
3978
3979/**
3980 * @ingroup wifi-test
3981 * @ingroup tests
3982 *
3983 * @brief Wifi Test Suite
3984 */
3986{
3987 public:
3988 WifiTestSuite();
3989};
3990
3992 : TestSuite("wifi-devices", Type::UNIT)
3993{
3994 AddTestCase(new WifiTest, TestCase::Duration::QUICK);
3995 AddTestCase(new QosUtilsIsOldPacketTest, TestCase::Duration::QUICK);
3996 AddTestCase(new InterferenceHelperSequenceTest, TestCase::Duration::QUICK); // Bug 991
3997 AddTestCase(new DcfImmediateAccessBroadcastTestCase, TestCase::Duration::QUICK);
3998 AddTestCase(new Bug730TestCase, TestCase::Duration::QUICK); // Bug 730
3999 AddTestCase(new QosFragmentationTestCase, TestCase::Duration::QUICK);
4000 AddTestCase(new SetChannelFrequencyTest, TestCase::Duration::QUICK);
4001 AddTestCase(new Bug2222TestCase, TestCase::Duration::QUICK); // Bug 2222
4002 AddTestCase(new Bug2843TestCase, TestCase::Duration::QUICK); // Bug 2843
4003 AddTestCase(new Bug2831TestCase, TestCase::Duration::QUICK); // Bug 2831
4004 AddTestCase(new StaWifiMacScanningTestCase, TestCase::Duration::QUICK); // Bug 2399
4005 AddTestCase(new Bug2470TestCase, TestCase::Duration::QUICK); // Bug 2470
4006 AddTestCase(new Issue40TestCase, TestCase::Duration::QUICK); // Issue #40
4007 AddTestCase(new Issue169TestCase, TestCase::Duration::QUICK); // Issue #169
4008 AddTestCase(new IdealRateManagerChannelWidthTest, TestCase::Duration::QUICK);
4009 AddTestCase(new IdealRateManagerMimoTest, TestCase::Duration::QUICK);
4010 AddTestCase(new HeRuMcsDataRateTestCase, TestCase::Duration::QUICK);
4011 AddTestCase(new WifiMgtHeaderTest, TestCase::Duration::QUICK);
4012 AddTestCase(new DsssModulationTest, TestCase::Duration::QUICK);
4013}
4014
4015static 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.
bool CheckDataRate(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.
void DoRun() override
Implementation to actually run this TestCase.
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:1550
RU Specification.
Definition he-ru.h:37
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:561
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:49
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:90
void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition wifi-mac.cc:497
Implement the header for management frames.
represent a single transmission mode
Definition wifi-mode.h:40
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:172
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:695
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
Definition wifi-phy.h:937
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition wifi-phy.cc:997
virtual void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition wifi-phy.cc:649
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:1123
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition wifi-phy.cc:661
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:970
void Set(std::string path, const AttributeValue &value)
Definition config.cc:872
#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:1369
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1381
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1345
TypeOfStation
Enumeration for type of WiFi station.
Definition wifi-mac.h:58
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:59
@ AP
Definition wifi-mac.h:60
@ 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.
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
RuType
The different Resource Unit (RU) types.
Definition wifi-types.h:98
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
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Definition wifi-ppdu.h:38
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:71
MpduType type
type of MPDU
Definition wifi-types.h:72
SignalNoiseDbm structure.
Definition wifi-types.h:64
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.