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 2 {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, 2, "Only two distinct tuples expected");
1692 NS_TEST_ASSERT_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
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}
1719
1720//-----------------------------------------------------------------------------
1721/**
1722 * Make sure that the channel width and the channel number can be changed at runtime.
1723 *
1724 * The scenario considers an access point and a station using a 20 MHz channel width.
1725 * After 1s, we change the channel width and the channel number to use a 40 MHz channel.
1726 * The tests checks the operational channel width sent in Beacon frames
1727 * and verify that the association procedure is executed twice.
1728 *
1729 * See \bugid{2831}
1730 */
1731
1733{
1734 public:
1736 ~Bug2831TestCase() override;
1737 void DoRun() override;
1738
1739 private:
1740 /**
1741 * Function called to change the supported channel width at runtime
1742 */
1744 /**
1745 * Callback triggered when a packet is received by the PHYs
1746 * @param context the context
1747 * @param p the received packet
1748 * @param rxPowersW the received power per channel band in watts
1749 */
1750 void RxCallback(std::string context, Ptr<const Packet> p, RxPowerWattPerChannelBand rxPowersW);
1751
1754
1755 uint16_t m_assocReqCount; ///< count number of association requests
1756 uint16_t m_assocRespCount; ///< count number of association responses
1757 uint16_t m_countOperationalChannelWidth20; ///< count number of beacon frames announcing a 20
1758 ///< MHz operating channel width
1759 uint16_t m_countOperationalChannelWidth40; ///< count number of beacon frames announcing a 40
1760 ///< MHz operating channel width
1761};
1762
1764 : TestCase("Test case for Bug 2831"),
1765 m_assocReqCount(0),
1766 m_assocRespCount(0),
1767 m_countOperationalChannelWidth20(0),
1768 m_countOperationalChannelWidth40(0)
1769{
1770}
1771
1775
1776void
1782
1783void
1786 RxPowerWattPerChannelBand rxPowersW)
1787{
1788 Ptr<Packet> packet = p->Copy();
1789 WifiMacHeader hdr;
1790 packet->RemoveHeader(hdr);
1791 if (hdr.IsAssocReq())
1792 {
1794 }
1795 else if (hdr.IsAssocResp())
1796 {
1798 }
1799 else if (hdr.IsBeacon())
1800 {
1801 MgtBeaconHeader beacon;
1802 packet->RemoveHeader(beacon);
1803 const auto& htOperation = beacon.Get<HtOperation>();
1804 if (htOperation.has_value() && htOperation->GetStaChannelWidth() > 0)
1805 {
1807 }
1808 else
1809 {
1811 }
1812 }
1813}
1814
1815void
1817{
1819 ObjectFactory propDelay;
1820 propDelay.SetTypeId("ns3::ConstantSpeedPropagationDelayModel");
1821 Ptr<PropagationDelayModel> propagationDelay = propDelay.Create<PropagationDelayModel>();
1823 channel->SetPropagationDelayModel(propagationDelay);
1824 channel->SetPropagationLossModel(propagationLoss);
1825
1826 Ptr<Node> apNode = CreateObject<Node>();
1828 apNode->AddDevice(apDev);
1829 apDev->SetStandard(WIFI_STANDARD_80211ax);
1831 apDev->SetHtConfiguration(apHtConfiguration);
1832 ObjectFactory manager;
1833 manager.SetTypeId("ns3::ConstantRateWifiManager");
1834 apDev->SetRemoteStationManager(manager.Create<WifiRemoteStationManager>());
1835
1837 apMobility->SetPosition(Vector(0.0, 0.0, 0.0));
1838 apNode->AggregateObject(apMobility);
1839
1840 auto error = CreateObject<YansErrorRateModel>();
1842 apDev->SetPhy(m_apPhy);
1844 m_apPhy->SetInterferenceHelper(apInterferenceHelper);
1845 m_apPhy->SetErrorRateModel(error);
1846 m_apPhy->SetChannel(channel);
1847 m_apPhy->SetMobility(apMobility);
1848 m_apPhy->SetDevice(apDev);
1851
1852 ObjectFactory mac;
1853 mac.SetTypeId("ns3::ApWifiMac");
1854 mac.Set("EnableBeaconJitter", BooleanValue(false));
1855 mac.Set("QosSupported", BooleanValue(true));
1856 for (const std::string ac : {"BE", "BK", "VI", "VO"})
1857 {
1858 auto qosTxop =
1859 CreateObjectWithAttributes<QosTxop>("AcIndex", StringValue(std::string("AC_") + ac));
1860 mac.Set(ac + "_Txop", PointerValue(qosTxop));
1861 }
1862 auto apMac = mac.Create<WifiMac>();
1863 apMac->SetDevice(apDev);
1864 apMac->SetAddress(Mac48Address::Allocate());
1865 apDev->SetMac(apMac);
1866 apMac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
1867 apMac->SetFrameExchangeManagers({CreateObject<HeFrameExchangeManager>()});
1868 apMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
1869 Ptr<FrameExchangeManager> fem = apMac->GetFrameExchangeManager();
1870 fem->SetAddress(apMac->GetAddress());
1872 protectionManager->SetWifiMac(apMac);
1873 fem->SetProtectionManager(protectionManager);
1875 ackManager->SetWifiMac(apMac);
1876 fem->SetAckManager(ackManager);
1877
1878 Ptr<Node> staNode = CreateObject<Node>();
1880 staNode->AddDevice(staDev);
1881 staDev->SetStandard(WIFI_STANDARD_80211ax);
1883 staDev->SetHtConfiguration(staHtConfiguration);
1884 staDev->SetRemoteStationManager(manager.Create<WifiRemoteStationManager>());
1885
1887 staMobility->SetPosition(Vector(1.0, 0.0, 0.0));
1888 staNode->AggregateObject(staMobility);
1889
1891 staDev->SetPhy(m_staPhy);
1893 m_staPhy->SetInterferenceHelper(staInterferenceHelper);
1895 m_staPhy->SetChannel(channel);
1896 m_staPhy->SetMobility(staMobility);
1897 m_staPhy->SetDevice(apDev);
1900
1901 mac.SetTypeId("ns3::StaWifiMac");
1902 for (const std::string ac : {"BE", "BK", "VI", "VO"})
1903 {
1904 auto qosTxop =
1905 CreateObjectWithAttributes<QosTxop>("AcIndex", StringValue(std::string("AC_") + ac));
1906 mac.Set(ac + "_Txop", PointerValue(qosTxop));
1907 }
1908 auto staMac = mac.Create<WifiMac>();
1909 staDev->SetMac(staMac);
1910 staMac->SetDevice(staDev);
1911 staMac->SetAddress(Mac48Address::Allocate());
1912 staMac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
1913 staMac->SetFrameExchangeManagers({CreateObject<HeFrameExchangeManager>()});
1915 staMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
1916 fem = staMac->GetFrameExchangeManager();
1917 fem->SetAddress(staMac->GetAddress());
1918 protectionManager = CreateObject<WifiDefaultProtectionManager>();
1919 protectionManager->SetWifiMac(staMac);
1920 fem->SetProtectionManager(protectionManager);
1922 ackManager->SetWifiMac(staMac);
1923 fem->SetAckManager(ackManager);
1924
1925 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxBegin",
1927
1929
1933
1934 NS_TEST_ASSERT_MSG_EQ(m_assocReqCount, 2, "Second Association request not received");
1935 NS_TEST_ASSERT_MSG_EQ(m_assocRespCount, 2, "Second Association response not received");
1937 10,
1938 "Incorrect operational channel width before channel change");
1940 20,
1941 "Incorrect operational channel width after channel change");
1942}
1943
1944//-----------------------------------------------------------------------------
1945/**
1946 * Make sure that Wifi STA is correctly associating to the best AP (i.e.,
1947 * nearest from STA). We consider 3 AP and 1 STA. This test case consisted of
1948 * three sub tests:
1949 * - The best AP sends its beacon later than the other APs. STA is expected
1950 * to associate to the best AP.
1951 * - The STA is using active scanning instead of passive, the rest of the
1952 * APs works normally. STA is expected to associate to the best AP
1953 * - The nearest AP is turned off after sending beacon and while STA is
1954 * still scanning. STA is expected to associate to the second best AP.
1955 *
1956 * See \bugid{2399}
1957 * @todo Add explicit association refusal test if ns-3 implemented it.
1958 */
1959
1961{
1962 public:
1964 ~StaWifiMacScanningTestCase() override;
1965 void DoRun() override;
1966
1967 private:
1968 /**
1969 * Callback function on STA assoc event
1970 * @param context context string
1971 * @param bssid the associated AP's bssid
1972 */
1973 void AssocCallback(std::string context, Mac48Address bssid);
1974 /**
1975 * Turn beacon generation on the AP node
1976 * @param apNode the AP node
1977 */
1978 void TurnBeaconGenerationOn(Ptr<Node> apNode);
1979 /**
1980 * Turn the AP node off
1981 * @param apNode the AP node
1982 */
1983 void TurnApOff(Ptr<Node> apNode);
1984 /**
1985 * Setup test
1986 * @param nearestApBeaconGeneration set BeaconGeneration attribute of the nearest AP
1987 * @param staActiveProbe set ActiveProbing attribute of the STA
1988 * @return node container containing all nodes
1989 */
1990 NodeContainer Setup(bool nearestApBeaconGeneration, bool staActiveProbe);
1991
1992 Mac48Address m_associatedApBssid; ///< Associated AP's bssid
1993};
1994
1996 : TestCase("Test case for StaWifiMac scanning capability")
1997{
1998}
1999
2003
2004void
2006{
2007 m_associatedApBssid = bssid;
2008}
2009
2010void
2012{
2013 Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice>(apNode->GetDevice(0));
2014 Ptr<ApWifiMac> mac = DynamicCast<ApWifiMac>(netDevice->GetMac());
2015 mac->SetAttribute("BeaconGeneration", BooleanValue(true));
2016}
2017
2018void
2020{
2021 Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice>(apNode->GetDevice(0));
2022 Ptr<WifiPhy> phy = netDevice->GetPhy();
2023 phy->SetOffMode();
2024}
2025
2027StaWifiMacScanningTestCase::Setup(bool nearestApBeaconGeneration, bool staActiveProbe)
2028{
2031 int64_t streamNumber = 1;
2032
2033 NodeContainer apNodes;
2034 apNodes.Create(2);
2035
2036 Ptr<Node> apNodeNearest = CreateObject<Node>();
2037 Ptr<Node> staNode = CreateObject<Node>();
2038
2041 phy.SetChannel(channel.Create());
2042
2043 WifiHelper wifi;
2044 wifi.SetStandard(WIFI_STANDARD_80211n);
2045 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager");
2046
2047 WifiMacHelper mac;
2048 NetDeviceContainer apDevice;
2049 NetDeviceContainer apDeviceNearest;
2050 mac.SetType("ns3::ApWifiMac", "BeaconGeneration", BooleanValue(true));
2051 apDevice = wifi.Install(phy, mac, apNodes);
2052 mac.SetType("ns3::ApWifiMac", "BeaconGeneration", BooleanValue(nearestApBeaconGeneration));
2053 apDeviceNearest = wifi.Install(phy, mac, apNodeNearest);
2054
2055 NetDeviceContainer staDevice;
2056 mac.SetType("ns3::StaWifiMac", "ActiveProbing", BooleanValue(staActiveProbe));
2057 staDevice = wifi.Install(phy, mac, staNode);
2058
2059 // Assign fixed streams to random variables in use
2060 WifiHelper::AssignStreams(apDevice, streamNumber);
2061 WifiHelper::AssignStreams(apDeviceNearest, streamNumber + 1);
2062 WifiHelper::AssignStreams(staDevice, streamNumber + 2);
2063
2064 MobilityHelper mobility;
2066 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Furthest AP
2067 positionAlloc->Add(Vector(10.0, 0.0, 0.0)); // Second nearest AP
2068 positionAlloc->Add(Vector(5.0, 5.0, 0.0)); // Nearest AP
2069 positionAlloc->Add(Vector(6.0, 5.0, 0.0)); // STA
2070 mobility.SetPositionAllocator(positionAlloc);
2071
2072 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2073 mobility.Install(apNodes);
2074 mobility.Install(apNodeNearest);
2075 mobility.Install(staNode);
2076
2077 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/Assoc",
2079
2080 NodeContainer allNodes = NodeContainer(apNodes, apNodeNearest, staNode);
2081 return allNodes;
2082}
2083
2084void
2086{
2087 {
2088 NodeContainer nodes = Setup(false, false);
2089 Ptr<Node> nearestAp = nodes.Get(2);
2090 Mac48Address nearestApAddr =
2091 DynamicCast<WifiNetDevice>(nearestAp->GetDevice(0))->GetMac()->GetAddress();
2092
2095 this,
2096 nearestAp);
2097
2101
2103 nearestApAddr,
2104 "STA is associated to the wrong AP");
2105 }
2107 {
2108 NodeContainer nodes = Setup(true, true);
2109 Ptr<Node> nearestAp = nodes.Get(2);
2110 Mac48Address nearestApAddr =
2111 DynamicCast<WifiNetDevice>(nearestAp->GetDevice(0))->GetMac()->GetAddress();
2112
2116
2118 nearestApAddr,
2119 "STA is associated to the wrong AP");
2120 }
2122 {
2123 NodeContainer nodes = Setup(true, false);
2124 Ptr<Node> nearestAp = nodes.Get(2);
2125 Mac48Address secondNearestApAddr =
2126 DynamicCast<WifiNetDevice>(nodes.Get(1)->GetDevice(0))->GetMac()->GetAddress();
2127
2129
2133
2135 secondNearestApAddr,
2136 "STA is associated to the wrong AP");
2137 }
2138}
2139
2140//-----------------------------------------------------------------------------
2141/**
2142 * Make sure that the ADDBA handshake process is protected.
2143 *
2144 * The scenario considers an access point and a station. It utilizes
2145 * ReceiveListErrorModel to drop by force ADDBA request on STA or ADDBA
2146 * response on AP. The AP sends 5 packets of each 1000 bytes (thus generating
2147 * BA agreement), 2 times during the test at 0.5s and 0.8s. We only drop the
2148 * first ADDBA request/response of the first BA negotiation. Therefore, we
2149 * expect that the packets still in queue after the failed BA agreement will be
2150 * sent with normal MPDU, and packets queued after that should be sent with
2151 * A-MPDU.
2152 *
2153 * This test consider 2 cases:
2154 *
2155 * 1. ADDBA request packets are blocked on receive at STA, triggering
2156 * transmission failure at AP
2157 * 2. ADDBA response packets are blocked on receive at AP, STA stops
2158 * retransmission of ADDBA response
2159 *
2160 * See \bugid{2470}
2161 */
2162
2164{
2165 public:
2167 ~Bug2470TestCase() override;
2168 void DoRun() override;
2169
2170 private:
2171 /**
2172 * Callback when ADDBA state changed
2173 * @param context node context
2174 * @param t the time the state changed
2175 * @param recipient the MAC address of the recipient
2176 * @param tid the TID
2177 * @param state the state
2178 */
2179 void AddbaStateChangedCallback(std::string context,
2180 Time t,
2181 Mac48Address recipient,
2182 uint8_t tid,
2184 /**
2185 * Callback when a frame is transmitted.
2186 * @param rxErrorModel the post reception error model on the receiver
2187 * @param context the context
2188 * @param psduMap the PSDU map
2189 * @param txVector the TX vector
2190 * @param txPowerW the tx power in Watts
2191 */
2192 void TxCallback(Ptr<ListErrorModel> rxErrorModel,
2193 std::string context,
2194 WifiConstPsduMap psduMap,
2195 WifiTxVector txVector,
2196 double txPowerW);
2197
2198 /**
2199 * Callback when packet is received
2200 * @param context node context
2201 * @param p the received packet
2202 * @param channelFreqMhz the channel frequency in MHz
2203 * @param txVector the TX vector
2204 * @param aMpdu the A-MPDU info
2205 * @param signalNoise the signal noise in dBm
2206 * @param staId the STA-ID
2207 */
2208 void RxCallback(std::string context,
2210 uint16_t channelFreqMhz,
2211 WifiTxVector txVector,
2212 MpduInfo aMpdu,
2213 SignalNoiseDbm signalNoise,
2214 uint16_t staId);
2215 /**
2216 * Callback when packet is dropped
2217 * @param context node context
2218 * @param p the failed packet
2219 * @param snr the SNR of the failed packet in linear scale
2220 */
2221 void RxErrorCallback(std::string context, Ptr<const Packet> p, double snr);
2222 /**
2223 * Triggers the arrival of a burst of 1000 Byte-long packets in the source device
2224 * @param numPackets number of packets in burst
2225 * @param sourceDevice pointer to the source NetDevice
2226 * @param destination address of the destination device
2227 */
2228 void SendPacketBurst(uint32_t numPackets,
2229 Ptr<NetDevice> sourceDevice,
2230 Address& destination) const;
2231 /**
2232 * Run subtest for this test suite
2233 * @param rcvErrorType type of station (STA or AP) to install the post reception error model on
2234 */
2235 void RunSubtest(TypeOfStation rcvErrorType);
2236
2237 uint16_t m_receivedNormalMpduCount; ///< Count received normal MPDU packets on STA
2238 uint16_t m_receivedAmpduCount; ///< Count received A-MPDU packets on STA
2239 uint16_t m_failedActionCount; ///< Count failed ADDBA request/response
2240 uint16_t m_addbaEstablishedCount; ///< Count number of times ADDBA state machine is in
2241 ///< established state
2242 uint16_t m_addbaPendingCount; ///< Count number of times ADDBA state machine is in pending state
2243 uint16_t
2244 m_addbaRejectedCount; ///< Count number of times ADDBA state machine is in rejected state
2245 uint16_t
2246 m_addbaNoReplyCount; ///< Count number of times ADDBA state machine is in no_reply state
2247 uint16_t m_addbaResetCount; ///< Count number of times ADDBA state machine is in reset state
2248};
2249
2251 : TestCase("Test case for Bug 2470"),
2252 m_receivedNormalMpduCount(0),
2253 m_receivedAmpduCount(0),
2254 m_failedActionCount(0),
2255 m_addbaEstablishedCount(0),
2256 m_addbaPendingCount(0),
2257 m_addbaRejectedCount(0),
2258 m_addbaNoReplyCount(0),
2259 m_addbaResetCount(0)
2260{
2261}
2262
2266
2267void
2269 Time t,
2270 Mac48Address recipient,
2271 uint8_t tid,
2273{
2274 switch (state)
2275 {
2278 break;
2281 break;
2284 break;
2287 break;
2290 break;
2291 }
2292}
2293
2294void
2296 std::string context,
2297 WifiConstPsduMap psduMap,
2298 WifiTxVector txVector,
2299 double txPowerW)
2300{
2301 auto psdu = psduMap.begin()->second;
2302
2303 // The sender is transmitting an ADDBA_REQUEST or ADDBA_RESPONSE frame. If this is
2304 // the first attempt at establishing a BA agreement (i.e., before the second set of packets
2305 // is generated), make the reception of the frame fail at the receiver.
2306 if (psdu->GetHeader(0).GetType() == WIFI_MAC_MGT_ACTION && Simulator::Now() < Seconds(0.8))
2307 {
2308 auto uid = psdu->GetPayload(0)->GetUid();
2309 rxErrorModel->SetList({uid});
2310 }
2311}
2312
2313void
2316 uint16_t channelFreqMhz,
2317 WifiTxVector txVector,
2318 MpduInfo aMpdu,
2319 SignalNoiseDbm signalNoise,
2320 uint16_t staId)
2321{
2322 Ptr<Packet> packet = p->Copy();
2323 if (aMpdu.type != MpduType::NORMAL_MPDU)
2324 {
2326 }
2327 else
2328 {
2329 WifiMacHeader hdr;
2330 packet->RemoveHeader(hdr);
2331 if (hdr.IsData())
2332 {
2334 }
2335 }
2336}
2337
2338void
2339Bug2470TestCase::RxErrorCallback(std::string context, Ptr<const Packet> p, double snr)
2340{
2341 Ptr<Packet> packet = p->Copy();
2342 WifiMacHeader hdr;
2343 packet->RemoveHeader(hdr);
2344 if (hdr.IsAction())
2345 {
2347 }
2348}
2349
2350void
2352 Ptr<NetDevice> sourceDevice,
2353 Address& destination) const
2354{
2355 for (uint32_t i = 0; i < numPackets; i++)
2356 {
2357 Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
2358 sourceDevice->Send(pkt, destination, 0);
2359 }
2360}
2361
2362void
2364{
2367 int64_t streamNumber = 200;
2368
2369 NodeContainer wifiApNode;
2370 NodeContainer wifiStaNode;
2371 wifiApNode.Create(1);
2372 wifiStaNode.Create(1);
2373
2376 phy.SetChannel(channel.Create());
2377
2378 WifiHelper wifi;
2379 wifi.SetStandard(WIFI_STANDARD_80211n);
2380 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
2381 "DataMode",
2382 StringValue("HtMcs7"),
2383 "ControlMode",
2384 StringValue("HtMcs7"));
2385
2386 WifiMacHelper mac;
2387 NetDeviceContainer apDevice;
2388 phy.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}"));
2389 mac.SetType("ns3::ApWifiMac", "EnableBeaconJitter", BooleanValue(false));
2390 apDevice = wifi.Install(phy, mac, wifiApNode);
2391
2392 NetDeviceContainer staDevice;
2393 mac.SetType("ns3::StaWifiMac");
2394 staDevice = wifi.Install(phy, mac, wifiStaNode);
2395
2396 // Assign fixed streams to random variables in use
2397 WifiHelper::AssignStreams(apDevice, streamNumber);
2398 WifiHelper::AssignStreams(staDevice, streamNumber);
2399
2400 MobilityHelper mobility;
2402 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2403 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
2404 mobility.SetPositionAllocator(positionAlloc);
2405
2406 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2407 mobility.Install(wifiApNode);
2408 mobility.Install(wifiStaNode);
2409
2410 auto rxErrorModel = CreateObject<ListErrorModel>();
2411 Ptr<WifiMac> wifiMac;
2412 switch (rcvErrorType)
2413 {
2414 case AP:
2415 wifiMac = DynamicCast<WifiNetDevice>(apDevice.Get(0))->GetMac();
2416 break;
2417 case STA:
2418 wifiMac = DynamicCast<WifiNetDevice>(staDevice.Get(0))->GetMac();
2419 break;
2420 default:
2421 NS_ABORT_MSG("Station type " << +rcvErrorType << " cannot be used here");
2422 }
2423 wifiMac->GetWifiPhy(0)->SetPostReceptionErrorModel(rxErrorModel);
2424
2426 "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/MonitorSnifferRx",
2428 Config::Connect("/NodeList/*/DeviceList/*/Phy/State/RxError",
2430 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/BE_Txop/"
2431 "BlockAckManager/AgreementState",
2433 Config::Connect("/NodeList/" + std::to_string(rcvErrorType == STA ? 0 /* AP */ : 1 /* STA */) +
2434 "/DeviceList/*/$ns3::WifiNetDevice/Phys/0/PhyTxPsduBegin",
2435 MakeCallback(&Bug2470TestCase::TxCallback, this).Bind(rxErrorModel));
2436
2439 this,
2440 1,
2441 apDevice.Get(0),
2442 staDevice.Get(0)->GetAddress());
2445 this,
2446 4,
2447 apDevice.Get(0),
2448 staDevice.Get(0)->GetAddress());
2451 this,
2452 1,
2453 apDevice.Get(0),
2454 staDevice.Get(0)->GetAddress());
2457 this,
2458 4,
2459 apDevice.Get(0),
2460 staDevice.Get(0)->GetAddress());
2461
2465}
2466
2467void
2469{
2470 {
2471 RunSubtest(STA);
2472 NS_TEST_ASSERT_MSG_EQ(m_failedActionCount, 7, "ADDBA request packets are not failed");
2473 // There are two sets of 5 packets to be transmitted. The first 5 packets should be sent by
2474 // normal MPDU because of failed ADDBA handshake. For the second set, the first packet
2475 // should be sent by normal MPDU, and the rest with A-MPDU. In total we expect to receive 6
2476 // normal MPDU packets and 4 A-MPDU packet.
2478 6,
2479 "Receiving incorrect number of normal MPDU packet on subtest 1");
2481 4,
2482 "Receiving incorrect number of A-MPDU packets on subtest 1");
2483
2485 1,
2486 "Incorrect number of times the ADDBA state machine was in "
2487 "established state on subtest 1");
2490 2,
2491 "Incorrect number of times the ADDBA state machine was in pending state on subtest 1");
2494 0,
2495 "Incorrect number of times the ADDBA state machine was in rejected state on subtest 1");
2498 1,
2499 "Incorrect number of times the ADDBA state machine was in no_reply state on subtest 1");
2502 1,
2503 "Incorrect number of times the ADDBA state machine was in reset state on subtest 1");
2504 }
2505
2514
2515 {
2516 RunSubtest(AP);
2517 NS_TEST_ASSERT_MSG_EQ(m_failedActionCount, 7, "ADDBA response packets are not failed");
2518 // Similar to subtest 1, we also expect to receive 6 normal MPDU packets and 4 A-MPDU
2519 // packets.
2521 6,
2522 "Receiving incorrect number of normal MPDU packet on subtest 2");
2524 4,
2525 "Receiving incorrect number of A-MPDU packet on subtest 2");
2526
2528 1,
2529 "Incorrect number of times the ADDBA state machine was in "
2530 "established state on subtest 2");
2533 2,
2534 "Incorrect number of times the ADDBA state machine was in pending state on subtest 2");
2537 0,
2538 "Incorrect number of times the ADDBA state machine was in rejected state on subtest 2");
2541 1,
2542 "Incorrect number of times the ADDBA state machine was in no_reply state on subtest 2");
2545 1,
2546 "Incorrect number of times the ADDBA state machine was in reset state on subtest 2");
2547 }
2548
2549 // TODO: In the second test set, it does not go to reset state since ADDBA response is received
2550 // after timeout (NO_REPLY) but before it does not enter RESET state. More tests should be
2551 // written to verify all possible scenarios.
2552}
2553
2554//-----------------------------------------------------------------------------
2555/**
2556 * Make sure that Ideal rate manager recovers when the station is moving away from the access point.
2557 *
2558 * The scenario considers an access point and a moving station.
2559 * Initially, the station is located at 1 meter from the access point.
2560 * After 1s, the station moves away from the access for 0.5s to
2561 * reach a point away of 50 meters from the access point.
2562 * The tests checks the Ideal rate manager is reset once it has
2563 * failed to transmit a data packet, so that the next data packets
2564 * can be successfully transmitted using a lower modulation.
2565 *
2566 * See \issueid{40}
2567 */
2568
2570{
2571 public:
2573 ~Issue40TestCase() override;
2574 void DoRun() override;
2575
2576 private:
2577 /**
2578 * Run one function
2579 * @param useAmpdu flag to indicate whether the test should be run with A-MPDU
2580 */
2581 void RunOne(bool useAmpdu);
2582
2583 /**
2584 * Callback when packet is successfully received
2585 * @param context node context
2586 * @param p the received packet
2587 */
2588 void RxSuccessCallback(std::string context, Ptr<const Packet> p);
2589 /**
2590 * Triggers the arrival of 1000 Byte-long packets in the source device
2591 * @param numPackets number of packets in burst
2592 * @param sourceDevice pointer to the source NetDevice
2593 * @param destination address of the destination device
2594 */
2595 void SendPackets(uint8_t numPackets, Ptr<NetDevice> sourceDevice, Address& destination);
2596 /**
2597 * Transmit final data failed function
2598 * @param context the context
2599 * @param address the MAC address
2600 */
2601 void TxFinalDataFailedCallback(std::string context, Mac48Address address);
2602
2603 uint16_t m_rxCount; ///< Count number of successfully received data packets
2604 uint16_t m_txCount; ///< Count number of transmitted data packets
2605 uint16_t
2606 m_txMacFinalDataFailedCount; ///< Count number of unsuccessfuly transmitted data packets
2607};
2608
2610 : TestCase("Test case for issue #40"),
2611 m_rxCount(0),
2612 m_txCount(0),
2613 m_txMacFinalDataFailedCount(0)
2614{
2615}
2616
2620
2621void
2623{
2624 m_rxCount++;
2625}
2626
2627void
2628Issue40TestCase::SendPackets(uint8_t numPackets, Ptr<NetDevice> sourceDevice, Address& destination)
2629{
2630 for (uint8_t i = 0; i < numPackets; i++)
2631 {
2632 Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
2633 sourceDevice->Send(pkt, destination, 0);
2634 m_txCount++;
2635 }
2636}
2637
2638void
2643
2644void
2646{
2647 m_rxCount = 0;
2648 m_txCount = 0;
2650
2653 int64_t streamNumber = 100;
2654
2655 NodeContainer wifiApNode;
2656 NodeContainer wifiStaNode;
2657 wifiApNode.Create(1);
2658 wifiStaNode.Create(1);
2659
2662 phy.SetChannel(channel.Create());
2663
2664 WifiHelper wifi;
2665 // use HT standard so that BlockAck agreement is not established in the useAmpdu false case
2666 wifi.SetStandard(useAmpdu ? WIFI_STANDARD_80211ac : WIFI_STANDARD_80211n);
2667 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
2668
2669 WifiMacHelper mac;
2670 NetDeviceContainer apDevice;
2671 mac.SetType("ns3::ApWifiMac");
2672 apDevice = wifi.Install(phy, mac, wifiApNode);
2673
2674 NetDeviceContainer staDevice;
2675 mac.SetType("ns3::StaWifiMac");
2676 staDevice = wifi.Install(phy, mac, wifiStaNode);
2677
2678 // Assign fixed streams to random variables in use
2679 WifiHelper::AssignStreams(apDevice, streamNumber);
2680 WifiHelper::AssignStreams(staDevice, streamNumber);
2681
2682 MobilityHelper mobility;
2684 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2685 positionAlloc->Add(Vector(10.0, 0.0, 0.0));
2686 mobility.SetPositionAllocator(positionAlloc);
2687
2688 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2689 mobility.Install(wifiApNode);
2690
2691 mobility.SetMobilityModel("ns3::WaypointMobilityModel");
2692 mobility.Install(wifiStaNode);
2693
2694 Config::Connect("/NodeList/*/DeviceList/*/RemoteStationManager/MacTxFinalDataFailed",
2696 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/MacRx",
2698
2699 Ptr<WaypointMobilityModel> staWaypointMobility =
2701 staWaypointMobility->AddWaypoint(Waypoint(Seconds(1), Vector(10.0, 0.0, 0.0)));
2702 staWaypointMobility->AddWaypoint(Waypoint(Seconds(1.5), Vector(50.0, 0.0, 0.0)));
2703
2704 if (useAmpdu)
2705 {
2706 // Disable use of BAR that are sent with the lowest modulation so that we can also reproduce
2707 // the problem with A-MPDU, i.e. the lack of feedback about SNR change
2708 Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice>(apDevice.Get(0));
2709 PointerValue ptr;
2710 ap_device->GetMac()->GetAttribute("BE_Txop", ptr);
2711 ptr.Get<QosTxop>()->SetAttribute("UseExplicitBarAfterMissedBlockAck", BooleanValue(false));
2712 }
2713
2714 // Transmit a first data packet before the station moves: it should be sent with a high
2715 // modulation and successfully received
2718 this,
2719 useAmpdu ? 2 : 1,
2720 apDevice.Get(0),
2721 staDevice.Get(0)->GetAddress());
2722
2723 // Transmit a second data packet once the station is away from the access point: it should be
2724 // sent with the same high modulation and be unsuccessfuly received
2727 this,
2728 useAmpdu ? 2 : 1,
2729 apDevice.Get(0),
2730 staDevice.Get(0)->GetAddress());
2731
2732 // Keep on transmitting data packets while the station is away from the access point: it should
2733 // be sent with a lower modulation and be successfully received
2736 this,
2737 useAmpdu ? 2 : 1,
2738 apDevice.Get(0),
2739 staDevice.Get(0)->GetAddress());
2742 this,
2743 useAmpdu ? 2 : 1,
2744 apDevice.Get(0),
2745 staDevice.Get(0)->GetAddress());
2748 this,
2749 useAmpdu ? 2 : 1,
2750 apDevice.Get(0),
2751 staDevice.Get(0)->GetAddress());
2754 this,
2755 useAmpdu ? 2 : 1,
2756 apDevice.Get(0),
2757 staDevice.Get(0)->GetAddress());
2760 this,
2761 useAmpdu ? 2 : 1,
2762 apDevice.Get(0),
2763 staDevice.Get(0)->GetAddress());
2764
2767
2769 (useAmpdu ? 14 : 7),
2770 "Incorrect number of transmitted packets");
2772 (useAmpdu ? 12 : 6),
2773 "Incorrect number of successfully received packets");
2775 (useAmpdu ? 2 : 1),
2776 "Incorrect number of dropped TX packets");
2777
2779}
2780
2781void
2783{
2784 // Test without A-MPDU
2785 RunOne(false);
2786
2787 // Test with A-MPDU
2788 RunOne(true);
2789}
2790
2791//-----------------------------------------------------------------------------
2792/**
2793 * Make sure that Ideal rate manager is able to handle non best-effort traffic.
2794 *
2795 * The scenario considers an access point and a fixed station.
2796 * The station first sends a best-effort packet to the access point,
2797 * for which Ideal rate manager should select a VHT rate. Then,
2798 * the station sends a non best-effort (voice) packet to the access point,
2799 * and since SNR is unchanged, the same VHT rate should be used.
2800 *
2801 * See \issueid{169}
2802 */
2803
2805{
2806 public:
2808 ~Issue169TestCase() override;
2809 void DoRun() override;
2810
2811 private:
2812 /**
2813 * Triggers the transmission of a 1000 Byte-long data packet from the source device
2814 * @param numPackets number of packets in burst
2815 * @param sourceDevice pointer to the source NetDevice
2816 * @param destination address of the destination device
2817 * @param priority the priority of the packets to send
2818 */
2819 void SendPackets(uint8_t numPackets,
2820 Ptr<NetDevice> sourceDevice,
2821 Address& destination,
2822 uint8_t priority);
2823
2824 /**
2825 * Callback that indicates a PSDU is being transmitted
2826 * @param context the context
2827 * @param psdus the PSDU map to transmit
2828 * @param txVector the TX vector
2829 * @param txPowerW the TX power (W)
2830 */
2831 void TxCallback(std::string context,
2832 WifiConstPsduMap psdus,
2833 WifiTxVector txVector,
2834 double txPowerW);
2835};
2836
2838 : TestCase("Test case for issue #169")
2839{
2840}
2841
2845
2846void
2848 Ptr<NetDevice> sourceDevice,
2849 Address& destination,
2850 uint8_t priority)
2851{
2852 SocketPriorityTag priorityTag;
2853 priorityTag.SetPriority(priority);
2854 for (uint8_t i = 0; i < numPackets; i++)
2855 {
2856 Ptr<Packet> packet = Create<Packet>(1000); // 1000 dummy bytes of data
2857 packet->AddPacketTag(priorityTag);
2858 sourceDevice->Send(packet, destination, 0);
2859 }
2860}
2861
2862void
2864 WifiConstPsduMap psdus,
2865 WifiTxVector txVector,
2866 double txPowerW)
2867{
2868 if (psdus.begin()->second->GetSize() >= 1000)
2869 {
2871 WifiModulationClass::WIFI_MOD_CLASS_VHT,
2872 "Ideal rate manager selected incorrect modulation class");
2873 }
2874}
2875
2876void
2878{
2881 int64_t streamNumber = 100;
2882
2883 NodeContainer wifiApNode;
2884 NodeContainer wifiStaNode;
2885 wifiApNode.Create(1);
2886 wifiStaNode.Create(1);
2887
2890 phy.SetChannel(channel.Create());
2891
2892 WifiHelper wifi;
2893 wifi.SetStandard(WIFI_STANDARD_80211ac);
2894 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
2895
2896 WifiMacHelper mac;
2897 NetDeviceContainer apDevice;
2898 mac.SetType("ns3::ApWifiMac");
2899 apDevice = wifi.Install(phy, mac, wifiApNode);
2900
2901 NetDeviceContainer staDevice;
2902 mac.SetType("ns3::StaWifiMac");
2903 staDevice = wifi.Install(phy, mac, wifiStaNode);
2904
2905 // Assign fixed streams to random variables in use
2906 WifiHelper::AssignStreams(apDevice, streamNumber);
2907 WifiHelper::AssignStreams(staDevice, streamNumber);
2908
2909 MobilityHelper mobility;
2911 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2912 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
2913 mobility.SetPositionAllocator(positionAlloc);
2914
2915 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2916 mobility.Install(wifiApNode);
2917 mobility.Install(wifiStaNode);
2918
2919 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
2921
2922 // Send best-effort packet (i.e. priority 0)
2925 this,
2926 1,
2927 apDevice.Get(0),
2928 staDevice.Get(0)->GetAddress(),
2929 0);
2930
2931 // Send non best-effort (voice) packet (i.e. priority 6)
2934 this,
2935 1,
2936 apDevice.Get(0),
2937 staDevice.Get(0)->GetAddress(),
2938 6);
2939
2942
2944}
2945
2946//-----------------------------------------------------------------------------
2947/**
2948 * Make sure that Ideal rate manager properly selects MCS based on the configured channel width.
2949 *
2950 * The scenario considers an access point and a fixed station.
2951 * The access point first sends a 80 MHz PPDU to the station,
2952 * for which Ideal rate manager should select VH-MCS 0 based
2953 * on the distance (no interference generated in this test). Then,
2954 * the access point sends a 20 MHz PPDU to the station,
2955 * which corresponds to a SNR 6 dB higher than previously, hence
2956 * VHT-MCS 2 should be selected. Finally, the access point sends a
2957 * 40 MHz PPDU to the station, which means corresponds to a SNR 3 dB
2958 * lower than previously, hence VHT-MCS 1 should be selected.
2959 */
2960
2962{
2963 public:
2966 void DoRun() override;
2967
2968 private:
2969 /**
2970 * Change the configured channel width for all nodes
2971 * @param channelWidth the channel width
2972 */
2973 void ChangeChannelWidth(MHz_u channelWidth);
2974
2975 /**
2976 * Triggers the transmission of a 1000 Byte-long data packet from the source device
2977 * @param sourceDevice pointer to the source NetDevice
2978 * @param destination address of the destination device
2979 */
2980 void SendPacket(Ptr<NetDevice> sourceDevice, Address& destination);
2981
2982 /**
2983 * Callback that indicates a PSDU is being transmitted
2984 * @param context the context
2985 * @param psduMap the PSDU map to transmit
2986 * @param txVector the TX vector
2987 * @param txPowerW the TX power (W)
2988 */
2989 void TxCallback(std::string context,
2990 WifiConstPsduMap psduMap,
2991 WifiTxVector txVector,
2992 double txPowerW);
2993
2994 /**
2995 * Check if the selected WifiMode is correct
2996 * @param expectedMode the expected WifiMode
2997 */
2998 void CheckLastSelectedMode(WifiMode expectedMode);
2999
3000 WifiMode m_txMode; ///< Store the last selected mode to send data packet
3001};
3002
3004 : TestCase("Test case for use of channel bonding with Ideal rate manager")
3005{
3006}
3007
3011
3012void
3014{
3015 Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelSettings",
3016 StringValue("{0, " + std::to_string(static_cast<uint16_t>(channelWidth)) +
3017 ", BAND_5GHZ, 0}"));
3018}
3019
3020void
3022{
3023 Ptr<Packet> packet = Create<Packet>(1000);
3024 sourceDevice->Send(packet, destination, 0);
3025}
3026
3027void
3029 WifiConstPsduMap psduMap,
3030 WifiTxVector txVector,
3031 double txPowerW)
3032{
3033 if (psduMap.begin()->second->GetSize() >= 1000)
3034 {
3035 m_txMode = txVector.GetMode();
3036 }
3037}
3038
3039void
3041{
3043 expectedMode,
3044 "Last selected WifiMode "
3045 << m_txMode << " does not match expected WifiMode " << expectedMode);
3046}
3047
3048void
3050{
3053 int64_t streamNumber = 100;
3054
3055 NodeContainer wifiApNode;
3056 NodeContainer wifiStaNode;
3057 wifiApNode.Create(1);
3058 wifiStaNode.Create(1);
3059
3062 phy.SetChannel(channel.Create());
3063
3064 WifiHelper wifi;
3065 wifi.SetStandard(WIFI_STANDARD_80211ac);
3066 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
3067
3068 WifiMacHelper mac;
3069 NetDeviceContainer apDevice;
3070 mac.SetType("ns3::ApWifiMac");
3071 apDevice = wifi.Install(phy, mac, wifiApNode);
3072
3073 NetDeviceContainer staDevice;
3074 mac.SetType("ns3::StaWifiMac");
3075 staDevice = wifi.Install(phy, mac, wifiStaNode);
3076
3077 // Assign fixed streams to random variables in use
3078 WifiHelper::AssignStreams(apDevice, streamNumber);
3079 WifiHelper::AssignStreams(staDevice, streamNumber);
3080
3081 MobilityHelper mobility;
3083 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
3084 positionAlloc->Add(Vector(50.0, 0.0, 0.0));
3085 mobility.SetPositionAllocator(positionAlloc);
3086
3087 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
3088 mobility.Install(wifiApNode);
3089 mobility.Install(wifiStaNode);
3090
3091 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
3093
3094 // Set channel width to 80 MHz & send packet
3097 this,
3098 MHz_u{80});
3101 this,
3102 apDevice.Get(0),
3103 staDevice.Get(0)->GetAddress());
3104 // Selected rate should be VHT-MCS 1
3107 this,
3109
3110 // Set channel width to 20 MHz & send packet
3113 this,
3114 MHz_u{20});
3117 this,
3118 apDevice.Get(0),
3119 staDevice.Get(0)->GetAddress());
3120 // Selected rate should be VHT-MCS 3 since SNR should be 6 dB higher than previously
3123 this,
3125
3126 // Set channel width to 40 MHz & send packet
3129 this,
3130 MHz_u{40});
3133 this,
3134 apDevice.Get(0),
3135 staDevice.Get(0)->GetAddress());
3136 // Selected rate should be VHT-MCS 2 since SNR should be 3 dB lower than previously
3139 this,
3141
3144
3146}
3147
3148//-----------------------------------------------------------------------------
3149/**
3150 * Test to validate that Ideal rate manager properly selects TXVECTOR in scenarios where MIMO is
3151 * used. The test consider both balanced and unbalanced MIMO settings, and verify ideal picks the
3152 * correct number of spatial streams and the correct MCS, taking into account potential diversity in
3153 * AWGN channels when the number of antenna at the receiver is higher than the number of spatial
3154 * streams used for the transmission.
3155 */
3156
3158{
3159 public:
3161 ~IdealRateManagerMimoTest() override;
3162 void DoRun() override;
3163
3164 private:
3165 /**
3166 * Change the configured MIMO settings for AP node
3167 * @param antennas the number of active antennas
3168 * @param maxStreams the maximum number of allowed spatial streams
3169 */
3170 void SetApMimoSettings(uint8_t antennas, uint8_t maxStreams);
3171 /**
3172 * Change the configured MIMO settings for STA node
3173 * @param antennas the number of active antennas
3174 * @param maxStreams the maximum number of allowed spatial streams
3175 */
3176 void SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams);
3177 /**
3178 * Triggers the transmission of a 1000 Byte-long data packet from the source device
3179 * @param sourceDevice pointer to the source NetDevice
3180 * @param destination address of the destination device
3181 */
3182 void SendPacket(Ptr<NetDevice> sourceDevice, Address& destination);
3183
3184 /**
3185 * Callback that indicates a PSDU is being transmitted
3186 * @param context the context
3187 * @param psdus the PSDU map to transmit
3188 * @param txVector the TX vector
3189 * @param txPowerW the TX power (W)
3190 */
3191 void TxCallback(std::string context,
3192 WifiConstPsduMap psdus,
3193 WifiTxVector txVector,
3194 double txPowerW);
3195
3196 /**
3197 * Check if the selected WifiMode is correct
3198 * @param expectedMode the expected WifiMode
3199 */
3200 void CheckLastSelectedMode(WifiMode expectedMode);
3201 /**
3202 * Check if the selected Nss is correct
3203 * @param expectedNss the expected Nss
3204 */
3205 void CheckLastSelectedNss(uint8_t expectedNss);
3206
3207 WifiTxVector m_txVector; ///< Store the last TXVECTOR used to transmit Data
3208};
3209
3211 : TestCase("Test case for use of imbalanced MIMO settings with Ideal rate manager")
3212{
3213}
3214
3218
3219void
3220IdealRateManagerMimoTest::SetApMimoSettings(uint8_t antennas, uint8_t maxStreams)
3221{
3222 Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/Antennas",
3223 UintegerValue(antennas));
3224 Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedTxSpatialStreams",
3225 UintegerValue(maxStreams));
3226 Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedRxSpatialStreams",
3227 UintegerValue(maxStreams));
3228}
3229
3230void
3231IdealRateManagerMimoTest::SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams)
3232{
3233 Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/Antennas",
3234 UintegerValue(antennas));
3235 Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedTxSpatialStreams",
3236 UintegerValue(maxStreams));
3237 Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedRxSpatialStreams",
3238 UintegerValue(maxStreams));
3239}
3240
3241void
3243{
3244 Ptr<Packet> packet = Create<Packet>(1000);
3245 sourceDevice->Send(packet, destination, 0);
3246}
3247
3248void
3250 WifiConstPsduMap psdus,
3251 WifiTxVector txVector,
3252 double txPowerW)
3253{
3254 if (psdus.begin()->second->GetSize() >= 1000)
3255 {
3256 m_txVector = txVector;
3257 }
3258}
3259
3260void
3262{
3264 expectedNss,
3265 "Last selected Nss " << m_txVector.GetNss()
3266 << " does not match expected Nss " << expectedNss);
3267}
3268
3269void
3271{
3273 expectedMode,
3274 "Last selected WifiMode " << m_txVector.GetMode()
3275 << " does not match expected WifiMode "
3276 << expectedMode);
3277}
3278
3279void
3281{
3284 int64_t streamNumber = 100;
3285
3286 NodeContainer wifiApNode;
3287 NodeContainer wifiStaNode;
3288 wifiApNode.Create(1);
3289 wifiStaNode.Create(1);
3290
3293 phy.SetChannel(channel.Create());
3294
3295 WifiHelper wifi;
3296 wifi.SetStandard(WIFI_STANDARD_80211ac);
3297 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
3298
3299 WifiMacHelper mac;
3300 NetDeviceContainer apDevice;
3301 mac.SetType("ns3::ApWifiMac");
3302 apDevice = wifi.Install(phy, mac, wifiApNode);
3303
3304 NetDeviceContainer staDevice;
3305 mac.SetType("ns3::StaWifiMac");
3306 staDevice = wifi.Install(phy, mac, wifiStaNode);
3307
3308 // Assign fixed streams to random variables in use
3309 WifiHelper::AssignStreams(apDevice, streamNumber);
3310 WifiHelper::AssignStreams(staDevice, streamNumber);
3311
3312 MobilityHelper mobility;
3314 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
3315 positionAlloc->Add(Vector(40.0, 0.0, 0.0));
3316 mobility.SetPositionAllocator(positionAlloc);
3317
3318 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
3319 mobility.Install(wifiApNode);
3320 mobility.Install(wifiStaNode);
3321
3322 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
3324
3325 // TX: 1 antenna
3327 // RX: 1 antenna
3329 // Send packets (2 times to get one feedback)
3332 this,
3333 apDevice.Get(0),
3334 staDevice.Get(0)->GetAddress());
3337 this,
3338 apDevice.Get(0),
3339 staDevice.Get(0)->GetAddress());
3340 // Selected NSS should be 1 since both TX and RX support a single antenna
3342 // Selected rate should be VHT-MCS 2 because of settings and distance between TX and RX
3345 this,
3347
3348 // TX: 1 antenna
3350 // RX: 2 antennas, but only supports 1 spatial stream
3352 // Send packets (2 times to get one feedback)
3355 this,
3356 apDevice.Get(0),
3357 staDevice.Get(0)->GetAddress());
3360 this,
3361 apDevice.Get(0),
3362 staDevice.Get(0)->GetAddress());
3363 // Selected NSS should be 1 since both TX and RX support a single antenna
3365 // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3366 // improvement of about 3dB
3369 this,
3371
3372 // TX: 1 antenna
3374 // RX: 2 antennas, and supports 2 spatial streams
3376 // Send packets (2 times to get one feedback)
3379 this,
3380 apDevice.Get(0),
3381 staDevice.Get(0)->GetAddress());
3384 this,
3385 apDevice.Get(0),
3386 staDevice.Get(0)->GetAddress());
3387 // Selected NSS should be 1 since TX supports a single antenna
3389 // Selected rate should be as previously
3392 this,
3394
3395 // TX: 2 antennas, but only supports 1 spatial stream
3397 // RX: 1 antenna
3399 // Send packets (2 times to get one feedback)
3402 this,
3403 apDevice.Get(0),
3404 staDevice.Get(0)->GetAddress());
3407 this,
3408 apDevice.Get(0),
3409 staDevice.Get(0)->GetAddress());
3410 // Selected NSS should be 1 since both TX and RX support a single antenna
3412 // Selected rate should be VHT-MCS 2 because we do no longer have diversity in this scenario
3413 // (more antennas at TX does not result in SNR improvement in AWGN channel)
3416 this,
3418
3419 // TX: 2 antennas, but only supports 1 spatial stream
3421 // RX: 2 antennas, but only supports 1 spatial stream
3423 // Send packets (2 times to get one feedback)
3426 this,
3427 apDevice.Get(0),
3428 staDevice.Get(0)->GetAddress());
3431 this,
3432 apDevice.Get(0),
3433 staDevice.Get(0)->GetAddress());
3434 // Selected NSS should be 1 since both TX and RX support a single antenna
3436 // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3437 // improvement of about 3dB (more antennas at TX does not result in SNR improvement in AWGN
3438 // channel)
3441 this,
3443
3444 // TX: 2 antennas, but only supports 1 spatial stream
3446 // RX: 2 antennas, and supports 2 spatial streams
3448 // Send packets (2 times to get one feedback)
3451 this,
3452 apDevice.Get(0),
3453 staDevice.Get(0)->GetAddress());
3456 this,
3457 apDevice.Get(0),
3458 staDevice.Get(0)->GetAddress());
3459 // Selected NSS should be 1 since TX supports a single antenna
3461 // Selected rate should be as previously
3464 this,
3466
3467 // TX: 2 antennas, and supports 2 spatial streams
3469 // RX: 1 antenna
3471 // Send packets (2 times to get one feedback)
3474 this,
3475 apDevice.Get(0),
3476 staDevice.Get(0)->GetAddress());
3479 this,
3480 apDevice.Get(0),
3481 staDevice.Get(0)->GetAddress());
3482 // Selected NSS should be 1 since RX supports a single antenna
3484 // Selected rate should be VHT-MCS 2 because we do no longer have diversity in this scenario
3485 // (more antennas at TX does not result in SNR improvement in AWGN channel)
3488 this,
3490
3491 // TX: 2 antennas, and supports 2 spatial streams
3493 // RX: 2 antennas, but only supports 1 spatial stream
3495 // Send packets (2 times to get one feedback)
3498 this,
3499 apDevice.Get(0),
3500 staDevice.Get(0)->GetAddress());
3503 this,
3504 apDevice.Get(0),
3505 staDevice.Get(0)->GetAddress());
3506 // Selected NSS should be 1 since RX supports a single antenna
3508 // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3509 // improvement of about 3dB (more antennas at TX does not result in SNR improvement in AWGN
3510 // channel)
3513 this,
3515
3516 // TX: 2 antennas, and supports 2 spatial streams
3518 // RX: 2 antennas, and supports 2 spatial streams
3520 // Send packets (2 times to get one feedback)
3523 this,
3524 apDevice.Get(0),
3525 staDevice.Get(0)->GetAddress());
3528 this,
3529 apDevice.Get(0),
3530 staDevice.Get(0)->GetAddress());
3531 // Selected NSS should be 2 since both TX and RX support 2 antennas
3533 // Selected rate should be the same as without diversity, as it uses 2 spatial streams so there
3534 // is no more benefits from diversity in AWGN channels
3537 this,
3539
3540 // Verify we can go back to initial situation
3545 this,
3546 apDevice.Get(0),
3547 staDevice.Get(0)->GetAddress());
3551 this,
3553
3554 Simulator::Stop(Seconds(10.2));
3557}
3558
3559//-----------------------------------------------------------------------------
3560/**
3561 * @ingroup wifi-test
3562 * @ingroup tests
3563 *
3564 * @brief Data rate verification test for MCSs of different RU sizes
3565 */
3567{
3568 public:
3570
3571 private:
3572 /**
3573 * Compare the data rate computed for the provided combination with standard defined one.
3574 * @param ruType the RU type
3575 * @param mcs the modulation and coding scheme (as a string, e.g. HeMcs0)
3576 * @param nss the number of spatial streams
3577 * @param guardInterval the guard interval to use
3578 * @param expectedDataRate the expected data rate in 100 kbps units (minimum granularity in
3579 * standard tables)
3580 * @returns true if data rates are the same, false otherwise
3581 */
3582 bool CheckDataRate(HeRu::RuType ruType,
3583 std::string mcs,
3584 uint8_t nss,
3585 Time guardInterval,
3586 uint16_t expectedDataRate);
3587 void DoRun() override;
3588};
3589
3591 : TestCase("Check data rates for different RU types.")
3592{
3593}
3594
3595bool
3597 std::string mcs,
3598 uint8_t nss,
3599 Time guardInterval,
3600 uint16_t expectedDataRate)
3601{
3602 uint8_t staId = 1;
3603 auto txVector = WifiTxVector(HePhy::GetHeMcs(0),
3604 0,
3606 guardInterval,
3607 1,
3608 1,
3609 0,
3610 MHz_u{160},
3611 false,
3612 false);
3613 WifiMode mode(mcs);
3614 txVector.SetMode(mode, staId);
3615 txVector.SetNss(nss, staId);
3616 HeRu::RuSpec ru(ruType, 1, true);
3617 txVector.SetRu(ru, staId);
3618 uint64_t dataRate = round(mode.GetDataRate(txVector, staId) / 100000.0);
3619 NS_ABORT_MSG_IF(dataRate > 65535, "Rate is way too high");
3620 if (static_cast<uint16_t>(dataRate) != expectedDataRate)
3621 {
3622 std::cerr << "RU=" << ruType << " mode=" << mode << " Nss=" << +nss
3623 << " guardInterval=" << guardInterval << " expected=" << expectedDataRate
3624 << " x100kbps"
3625 << " computed=" << static_cast<uint16_t>(dataRate) << " x100kbps" << std::endl;
3626 return false;
3627 }
3628 return true;
3629}
3630
3631void
3633{
3634 bool retval = true;
3635
3636 // 26-tone RU, browse over all MCSs, GIs and Nss's (up to 4, current max)
3637 retval = retval && CheckDataRate(HeRu::RU_26_TONE, "HeMcs0", 1, NanoSeconds(800), 9) &&
3638 CheckDataRate(HeRu::RU_26_TONE, "HeMcs1", 1, NanoSeconds(1600), 17) &&
3639 CheckDataRate(HeRu::RU_26_TONE, "HeMcs2", 1, NanoSeconds(3200), 23) &&
3640 CheckDataRate(HeRu::RU_26_TONE, "HeMcs3", 1, NanoSeconds(3200), 30) &&
3641 CheckDataRate(HeRu::RU_26_TONE, "HeMcs4", 2, NanoSeconds(1600), 100) &&
3642 CheckDataRate(HeRu::RU_26_TONE, "HeMcs5", 3, NanoSeconds(1600), 200) &&
3643 CheckDataRate(HeRu::RU_26_TONE, "HeMcs6", 4, NanoSeconds(1600), 300) &&
3644 CheckDataRate(HeRu::RU_26_TONE, "HeMcs7", 4, NanoSeconds(3200), 300) &&
3645 CheckDataRate(HeRu::RU_26_TONE, "HeMcs8", 4, NanoSeconds(1600), 400) &&
3646 CheckDataRate(HeRu::RU_26_TONE, "HeMcs9", 4, NanoSeconds(3200), 400) &&
3647 CheckDataRate(HeRu::RU_26_TONE, "HeMcs10", 4, NanoSeconds(1600), 500) &&
3648 CheckDataRate(HeRu::RU_26_TONE, "HeMcs11", 4, NanoSeconds(3200), 500);
3649
3651 retval,
3652 true,
3653 "26-tone RU data rate verification for different MCSs, GIs, and Nss's failed");
3654
3655 // Check other RU sizes
3656 retval = retval && CheckDataRate(HeRu::RU_52_TONE, "HeMcs2", 1, NanoSeconds(1600), 50) &&
3657 CheckDataRate(HeRu::RU_106_TONE, "HeMcs9", 1, NanoSeconds(800), 500) &&
3658 CheckDataRate(HeRu::RU_242_TONE, "HeMcs5", 1, NanoSeconds(1600), 650) &&
3659 CheckDataRate(HeRu::RU_484_TONE, "HeMcs3", 1, NanoSeconds(1600), 650) &&
3660 CheckDataRate(HeRu::RU_996_TONE, "HeMcs5", 1, NanoSeconds(3200), 2450) &&
3661 CheckDataRate(HeRu::RU_2x996_TONE, "HeMcs3", 1, NanoSeconds(3200), 2450);
3662
3663 NS_TEST_EXPECT_MSG_EQ(retval,
3664 true,
3665 "Data rate verification for RUs above 52-tone RU (included) failed");
3666}
3667
3668/// List of Information Elements included in the test management frame
3670 std::tuple<SupportedRates, std::optional<ExtendedSupportedRatesIE>, std::vector<Ssid>>;
3671
3672/**
3673 * @ingroup wifi-test
3674 * @ingroup tests
3675 *
3676 * @brief Test management header
3677 */
3678class MgtTestHeader : public WifiMgtHeader<MgtTestHeader, MgtTestElems>
3679{
3680 public:
3681 ~MgtTestHeader() override = default;
3682
3683 /**
3684 * Register this type.
3685 * @return The TypeId.
3686 */
3687 static TypeId GetTypeId();
3688
3689 /**
3690 * @return the TypeId for this object.
3691 */
3692 TypeId GetInstanceTypeId() const override;
3693
3694 using WifiMgtHeader<MgtTestHeader, MgtTestElems>::GetSerializedSize;
3695 using WifiMgtHeader<MgtTestHeader, MgtTestElems>::Serialize;
3696 using WifiMgtHeader<MgtTestHeader, MgtTestElems>::Deserialize;
3697};
3698
3699TypeId
3701{
3702 static TypeId tid = TypeId("ns3::MgtTestHeader")
3703 .SetParent<Header>()
3704 .SetGroupName("Wifi")
3705 .AddConstructor<MgtTestHeader>();
3706 return tid;
3707}
3708
3709TypeId
3711{
3712 return GetTypeId();
3713}
3714
3715/**
3716 * @ingroup wifi-test
3717 * @ingroup tests
3718 *
3719 * @brief Mgt header (de)serialization Test Suite
3720 */
3722{
3723 public:
3725 ~WifiMgtHeaderTest() override = default;
3726
3727 private:
3728 void DoRun() override;
3729};
3730
3732 : HeaderSerializationTestCase("Check (de)serialization of a test management header")
3733{
3734}
3735
3736void
3738{
3739 MgtTestHeader frame;
3740
3741 // Add the mandatory Information Element (SupportedRates)
3742 AllSupportedRates allRates;
3743 allRates.AddSupportedRate(1000000);
3744 allRates.AddSupportedRate(2000000);
3745 allRates.AddSupportedRate(3000000);
3746 allRates.AddSupportedRate(4000000);
3747 allRates.AddSupportedRate(5000000);
3748
3749 frame.Get<SupportedRates>() = allRates.rates;
3750 frame.Get<ExtendedSupportedRatesIE>() = allRates.extendedRates;
3751
3752 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3753 true,
3754 "Expected a SupportedRates IE to be included");
3755 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3756 false,
3757 "Expected no ExtendedSupportedRatesIE to be included");
3758 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 0, "Expected no Ssid IE to be included");
3759
3761
3762 // Add more rates, so that the optional Information Element (ExtendedSupportedRatesIE) is added
3763 allRates.AddSupportedRate(6000000);
3764 allRates.AddSupportedRate(7000000);
3765 allRates.AddSupportedRate(8000000);
3766 allRates.AddSupportedRate(9000000);
3767 allRates.AddSupportedRate(10000000);
3768
3769 frame.Get<SupportedRates>() = allRates.rates;
3770 frame.Get<ExtendedSupportedRatesIE>() = allRates.extendedRates;
3771
3772 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3773 true,
3774 "Expected a SupportedRates IE to be included");
3775 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3776 true,
3777 "Expected an ExtendedSupportedRatesIE to be included");
3778 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 0, "Expected no Ssid IE to be included");
3779
3781
3782 // Add a first Ssid IE
3783 Ssid one("Ssid One");
3784 frame.Get<Ssid>().push_back(one);
3785
3786 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3787 true,
3788 "Expected a SupportedRates IE to be included");
3789 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3790 true,
3791 "Expected an ExtendedSupportedRatesIE to be included");
3792 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 1, "Expected one Ssid IE to be included");
3793 NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().front().PeekString()),
3794 "Ssid One",
3795 "Incorrect SSID");
3796
3798
3799 // Add a second Ssid IE
3800 frame.Get<Ssid>().emplace_back("Ssid Two");
3801
3802 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3803 true,
3804 "Expected a SupportedRates IE to be included");
3805 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3806 true,
3807 "Expected an ExtendedSupportedRatesIE to be included");
3808 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 2, "Expected two Ssid IEs to be included");
3809 NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().front().PeekString()),
3810 "Ssid One",
3811 "Incorrect first SSID");
3812 NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().back().PeekString()),
3813 "Ssid Two",
3814 "Incorrect second SSID");
3815
3817}
3818
3819//-----------------------------------------------------------------------------
3820
3821/**
3822 * Make sure that all DSSS modulation types work (see issue #1095).
3823 *
3824 * This test sends four packets from a STA to an AP, each with a different
3825 * DSSS rate (1, 2, 5.5, and 11Mbps), and checks that all four are received.
3826 */
3828{
3829 public:
3831
3832 void DoRun() override;
3833
3834 private:
3835 uint32_t m_received; ///< number of received packets
3836
3837 /**
3838 * Trace sink to receive from the PacketSocket; the address parameter is unused
3839 * @param context the context
3840 * @param p the received packet
3841 */
3842 void Receive(std::string context, Ptr<const Packet> p, const Address&);
3843};
3844
3846 : TestCase("Test case for Bug 730"),
3847 m_received(0)
3848{
3849}
3850
3851void
3853{
3854 m_received++;
3855}
3856
3857void
3859{
3860 m_received = 0;
3861
3862 NodeContainer wifiStaNode;
3863 wifiStaNode.Create(1);
3864
3865 NodeContainer wifiApNode;
3866 wifiApNode.Create(1);
3867
3868 auto channel = YansWifiChannelHelper::Default();
3870 phy.SetChannel(channel.Create());
3871
3872 WifiHelper wifi;
3873 wifi.SetStandard(WIFI_STANDARD_80211b);
3874 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
3875 "DataMode",
3876 StringValue("DsssRate1Mbps"),
3877 "ControlMode",
3878 StringValue("DsssRate1Mbps"));
3879
3880 WifiMacHelper mac;
3881 auto ssid = Ssid("ns-3-ssid");
3882 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid), "ActiveProbing", BooleanValue(false));
3883
3884 NetDeviceContainer staDevices;
3885 staDevices = wifi.Install(phy, mac, wifiStaNode);
3886
3887 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid), "BeaconGeneration", BooleanValue(true));
3888
3889 NetDeviceContainer apDevices;
3890 apDevices = wifi.Install(phy, mac, wifiApNode);
3891 auto apRemoteStationManager = apDevices.Get(0)
3892 ->GetObject<WifiNetDevice>()
3893 ->GetRemoteStationManager()
3895 apRemoteStationManager->SetAttribute("DataMode", StringValue("DsssRate1Mbps"));
3896
3897 MobilityHelper mobility;
3898 auto positionAlloc = CreateObject<ListPositionAllocator>();
3899
3900 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
3901 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
3902 mobility.SetPositionAllocator(positionAlloc);
3903
3904 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
3905 mobility.Install(wifiApNode);
3906 mobility.Install(wifiStaNode);
3907
3908 auto apDevice = DynamicCast<WifiNetDevice>(apDevices.Get(0));
3909 auto staDevice = DynamicCast<WifiNetDevice>(staDevices.Get(0));
3910
3911 PacketSocketAddress socket;
3912 socket.SetSingleDevice(staDevice->GetIfIndex());
3913 socket.SetPhysicalAddress(apDevice->GetAddress());
3914 socket.SetProtocol(1);
3915
3916 // give packet socket powers to nodes.
3917 PacketSocketHelper packetSocket;
3918 packetSocket.Install(wifiStaNode);
3919 packetSocket.Install(wifiApNode);
3920
3921 auto client = CreateObject<PacketSocketClient>();
3922 client->SetAttribute("PacketSize", UintegerValue(1460));
3923 client->SetAttribute("MaxPackets", UintegerValue(4));
3924 client->SetRemote(socket);
3925 wifiStaNode.Get(0)->AddApplication(client);
3926 client->SetStartTime(Seconds(1));
3927 client->SetStopTime(Seconds(4.5));
3928
3929 auto server = CreateObject<PacketSocketServer>();
3930 server->SetLocal(socket);
3931 wifiApNode.Get(0)->AddApplication(server);
3932 server->SetStartTime(Seconds(0));
3933 server->SetStopTime(Seconds(4.5));
3934
3935 Config::Connect("/NodeList/1/ApplicationList/0/$ns3::PacketSocketServer/Rx",
3937
3938 // The PacketSocketClient starts at time 1s, and packets are sent at times 1s, 2s, 3s, 4s.
3939 // Change the MCS in between these send times (e.g., at 1.5s, 2.5s, 3.5s)
3941 Seconds(1.5),
3943 "/NodeList/0/DeviceList/0/RemoteStationManager/$ns3::ConstantRateWifiManager/DataMode",
3944 StringValue("DsssRate2Mbps"));
3946 Seconds(2.5),
3948 "/NodeList/0/DeviceList/0/RemoteStationManager/$ns3::ConstantRateWifiManager/DataMode",
3949 StringValue("DsssRate5_5Mbps"));
3951 Seconds(3.5),
3953 "/NodeList/0/DeviceList/0/RemoteStationManager/$ns3::ConstantRateWifiManager/DataMode",
3954 StringValue("DsssRate11Mbps"));
3955
3958
3960
3961 NS_TEST_ASSERT_MSG_EQ(m_received, 4, "Did not receive four DSSS packets");
3962}
3963
3964/**
3965 * @ingroup wifi-test
3966 * @ingroup tests
3967 *
3968 * @brief Wifi Test Suite
3969 */
3971{
3972 public:
3973 WifiTestSuite();
3974};
3975
3977 : TestSuite("wifi-devices", Type::UNIT)
3978{
3979 AddTestCase(new WifiTest, TestCase::Duration::QUICK);
3980 AddTestCase(new QosUtilsIsOldPacketTest, TestCase::Duration::QUICK);
3981 AddTestCase(new InterferenceHelperSequenceTest, TestCase::Duration::QUICK); // Bug 991
3982 AddTestCase(new DcfImmediateAccessBroadcastTestCase, TestCase::Duration::QUICK);
3983 AddTestCase(new Bug730TestCase, TestCase::Duration::QUICK); // Bug 730
3984 AddTestCase(new QosFragmentationTestCase, TestCase::Duration::QUICK);
3985 AddTestCase(new SetChannelFrequencyTest, TestCase::Duration::QUICK);
3986 AddTestCase(new Bug2222TestCase, TestCase::Duration::QUICK); // Bug 2222
3987 AddTestCase(new Bug2843TestCase, TestCase::Duration::QUICK); // Bug 2843
3988 AddTestCase(new Bug2831TestCase, TestCase::Duration::QUICK); // Bug 2831
3989 AddTestCase(new StaWifiMacScanningTestCase, TestCase::Duration::QUICK); // Bug 2399
3990 AddTestCase(new Bug2470TestCase, TestCase::Duration::QUICK); // Bug 2470
3991 AddTestCase(new Issue40TestCase, TestCase::Duration::QUICK); // Issue #40
3992 AddTestCase(new Issue169TestCase, TestCase::Duration::QUICK); // Issue #169
3993 AddTestCase(new IdealRateManagerChannelWidthTest, TestCase::Duration::QUICK);
3994 AddTestCase(new IdealRateManagerMimoTest, TestCase::Duration::QUICK);
3995 AddTestCase(new HeRuMcsDataRateTestCase, TestCase::Duration::QUICK);
3996 AddTestCase(new WifiMgtHeaderTest, TestCase::Duration::QUICK);
3997 AddTestCase(new DsssModulationTest, TestCase::Duration::QUICK);
3998}
3999
4000static WifiTestSuite g_wifiTestSuite; ///< the test suite
Make sure that when virtual collision occurs the wifi remote station manager is triggered and the ret...
~Bug2222TestCase() override
uint32_t m_countInternalCollisions
count internal collisions
void DoRun() override
Implementation to actually run this TestCase.
void TxDataFailedTrace(std::string context, Mac48Address adr)
Transmit data failed function.
Make sure that the ADDBA handshake process is protected.
void RxErrorCallback(std::string context, Ptr< const Packet > p, double snr)
Callback when packet is dropped.
void RunSubtest(TypeOfStation rcvErrorType)
Run subtest for this test suite.
void DoRun() override
Implementation to actually run this TestCase.
uint16_t m_addbaResetCount
Count number of times ADDBA state machine is in reset state.
uint16_t m_addbaRejectedCount
Count number of times ADDBA state machine is in rejected state.
void AddbaStateChangedCallback(std::string context, Time t, Mac48Address recipient, uint8_t tid, OriginatorBlockAckAgreement::State state)
Callback when ADDBA state changed.
uint16_t m_failedActionCount
Count failed ADDBA request/response.
void TxCallback(Ptr< ListErrorModel > rxErrorModel, std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback when a frame is transmitted.
uint16_t m_addbaEstablishedCount
Count number of times ADDBA state machine is in established state.
void RxCallback(std::string context, Ptr< const Packet > p, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise, uint16_t staId)
Callback when packet is received.
~Bug2470TestCase() override
uint16_t m_receivedNormalMpduCount
Count received normal MPDU packets on STA.
uint16_t m_addbaNoReplyCount
Count number of times ADDBA state machine is in no_reply state.
uint16_t m_addbaPendingCount
Count number of times ADDBA state machine is in pending state.
void SendPacketBurst(uint32_t numPackets, Ptr< NetDevice > sourceDevice, Address &destination) const
Triggers the arrival of a burst of 1000 Byte-long packets in the source device.
uint16_t m_receivedAmpduCount
Count received A-MPDU packets on STA.
Make sure that the channel width and the channel number can be changed at runtime.
uint16_t m_countOperationalChannelWidth20
count number of beacon frames announcing a 20 MHz operating channel width
void ChangeSupportedChannelWidth()
Function called to change the supported channel width at runtime.
uint16_t m_countOperationalChannelWidth40
count number of beacon frames announcing a 40 MHz operating channel width
void RxCallback(std::string context, Ptr< const Packet > p, RxPowerWattPerChannelBand rxPowersW)
Callback triggered when a packet is received by the PHYs.
uint16_t m_assocReqCount
count number of association requests
Ptr< YansWifiPhy > m_apPhy
AP PHY.
void DoRun() override
Implementation to actually run this TestCase.
Ptr< YansWifiPhy > m_staPhy
STA PHY.
uint16_t m_assocRespCount
count number of association responses
~Bug2831TestCase() override
Make sure that the correct channel width and center frequency have been set for OFDM basic rate trans...
void SendPacketBurst(uint8_t numPackets, Ptr< NetDevice > sourceDevice, Address &destination) const
Triggers the arrival of a burst of 1000 Byte-long packets in the source device.
void StoreDistinctTuple(std::string context, Ptr< SpectrumSignalParameters > txParams)
Stores the distinct {starting frequency, channelWidth, Number of subbands in SpectrumModel,...
std::vector< FreqWidthSubbandModulationTuple > m_distinctTuples
vector of distinct {starting frequency, channelWidth, Number of subbands in SpectrumModel,...
void DoRun() override
Implementation to actually run this TestCase.
MHz_u m_channelWidth
channel width
std::tuple< Hz_u, MHz_u, uint32_t, WifiModulationClass > FreqWidthSubbandModulationTuple
A tuple of {starting frequency, channelWidth, Number of subbands in SpectrumModel,...
~Bug2843TestCase() override
Make sure that when changing the fragmentation threshold during the simulation, the TCP transmission ...
Definition wifi-test.cc:647
~Bug730TestCase() override
Definition wifi-test.cc:672
void Receive(std::string context, Ptr< const Packet > p, const Address &adr)
Receive function.
Definition wifi-test.cc:677
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:686
uint32_t m_received
received
Definition wifi-test.cc:655
Make sure that when multiple broadcast packets are queued on the same device in a short succession,...
Definition wifi-test.cc:475
void NotifyPhyTxBegin(Ptr< const Packet > p, double txPowerW)
Notify Phy transmit begin.
Definition wifi-test.cc:510
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:531
ObjectFactory m_propDelay
propagation delay
Definition wifi-test.cc:490
unsigned int m_numSentPackets
number of sent packets
Definition wifi-test.cc:494
Time m_secondTransmissionTime
second transmission time
Definition wifi-test.cc:493
Time m_firstTransmissionTime
first transmission time
Definition wifi-test.cc:492
void SendOnePacket(Ptr< WifiNetDevice > dev)
Send one packet function.
Definition wifi-test.cc:524
Make sure that all DSSS modulation types work (see issue #1095).
void Receive(std::string context, Ptr< const Packet > p, const Address &)
Trace sink to receive from the PacketSocket; the address parameter is unused.
void DoRun() override
Implementation to actually run this TestCase.
uint32_t m_received
number of received packets
Data rate verification test for MCSs of different RU sizes.
void DoRun() override
Implementation to actually run this TestCase.
bool CheckDataRate(HeRu::RuType ruType, std::string mcs, uint8_t nss, Time guardInterval, uint16_t expectedDataRate)
Compare the data rate computed for the provided combination with standard defined one.
Make sure that Ideal rate manager properly selects MCS based on the configured channel width.
WifiMode m_txMode
Store the last selected mode to send data packet.
void ChangeChannelWidth(MHz_u channelWidth)
Change the configured channel width for all nodes.
void DoRun() override
Implementation to actually run this TestCase.
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
Triggers the transmission of a 1000 Byte-long data packet from the source device.
void CheckLastSelectedMode(WifiMode expectedMode)
Check if the selected WifiMode is correct.
void TxCallback(std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback that indicates a PSDU is being transmitted.
Test to validate that Ideal rate manager properly selects TXVECTOR in scenarios where MIMO is used.
~IdealRateManagerMimoTest() override
void CheckLastSelectedNss(uint8_t expectedNss)
Check if the selected Nss is correct.
void DoRun() override
Implementation to actually run this TestCase.
void TxCallback(std::string context, WifiConstPsduMap psdus, WifiTxVector txVector, double txPowerW)
Callback that indicates a PSDU is being transmitted.
void SetApMimoSettings(uint8_t antennas, uint8_t maxStreams)
Change the configured MIMO settings for AP node.
WifiTxVector m_txVector
Store the last TXVECTOR used to transmit Data.
void SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams)
Change the configured MIMO settings for STA node.
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
Triggers the transmission of a 1000 Byte-long data packet from the source device.
void CheckLastSelectedMode(WifiMode expectedMode)
Check if the selected WifiMode is correct.
void SwitchCh(Ptr< WifiNetDevice > dev)
Switch channel function.
Definition wifi-test.cc:323
void SendOnePacket(Ptr< WifiNetDevice > dev)
Send one packet function.
Definition wifi-test.cc:316
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:375
ObjectFactory m_manager
manager
Definition wifi-test.cc:305
ObjectFactory m_propDelay
propagation delay
Definition wifi-test.cc:307
Ptr< Node > CreateOne(Vector pos, Ptr< YansWifiChannel > channel)
Create one function.
Definition wifi-test.cc:330
Make sure that Ideal rate manager is able to handle non best-effort traffic.
void SendPackets(uint8_t numPackets, Ptr< NetDevice > sourceDevice, Address &destination, uint8_t priority)
Triggers the transmission of a 1000 Byte-long data packet from the source device.
~Issue169TestCase() override
void TxCallback(std::string context, WifiConstPsduMap psdus, WifiTxVector txVector, double txPowerW)
Callback that indicates a PSDU is being transmitted.
void DoRun() override
Implementation to actually run this TestCase.
Make sure that Ideal rate manager recovers when the station is moving away from the access point.
uint16_t m_txCount
Count number of transmitted data packets.
uint16_t m_txMacFinalDataFailedCount
Count number of unsuccessfuly transmitted data packets.
void RunOne(bool useAmpdu)
Run one function.
uint16_t m_rxCount
Count number of successfully received data packets.
void RxSuccessCallback(std::string context, Ptr< const Packet > p)
Callback when packet is successfully received.
void DoRun() override
Implementation to actually run this TestCase.
void TxFinalDataFailedCallback(std::string context, Mac48Address address)
Transmit final data failed function.
void SendPackets(uint8_t numPackets, Ptr< NetDevice > sourceDevice, Address &destination)
Triggers the arrival of 1000 Byte-long packets in the source device.
~Issue40TestCase() override
Test management header.
static TypeId GetTypeId()
Register this type.
~MgtTestHeader() override=default
TypeId GetInstanceTypeId() const override
Make sure that fragmentation works with QoS stations.
Definition wifi-test.cc:786
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:847
uint32_t m_received
received packets
Definition wifi-test.cc:794
~QosFragmentationTestCase() override
Definition wifi-test.cc:821
uint32_t m_fragments
transmitted fragments
Definition wifi-test.cc:795
void Transmit(std::string context, Ptr< const Packet > p, double power)
Callback invoked when PHY transmits a packet.
Definition wifi-test.cc:835
void Receive(std::string context, Ptr< const Packet > p, const Address &adr)
Receive function.
Definition wifi-test.cc:826
Qos Utils Is Old Packet Test.
Definition wifi-test.cc:238
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:245
Set Channel Frequency Test.
Definition wifi-test.cc:942
Ptr< YansWifiPhy > GetYansWifiPhyPtr(const NetDeviceContainer &nc) const
Get yans wifi phy function.
Definition wifi-test.cc:963
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:971
Make sure that Wifi STA is correctly associating to the best AP (i.e., nearest from STA).
void DoRun() override
Implementation to actually run this TestCase.
void TurnBeaconGenerationOn(Ptr< Node > apNode)
Turn beacon generation on the AP node.
Mac48Address m_associatedApBssid
Associated AP's bssid.
~StaWifiMacScanningTestCase() override
void TurnApOff(Ptr< Node > apNode)
Turn the AP node off.
NodeContainer Setup(bool nearestApBeaconGeneration, bool staActiveProbe)
Setup test.
void AssocCallback(std::string context, Mac48Address bssid)
Callback function on STA assoc event.
Mgt header (de)serialization Test Suite.
void DoRun() override
Implementation to actually run this TestCase.
~WifiMgtHeaderTest() override=default
Wifi Test.
Definition wifi-test.cc:95
void CreateOne(Vector pos, Ptr< YansWifiChannel > channel)
Create one function.
Definition wifi-test.cc:134
void RunOne()
Run one function.
Definition wifi-test.cc:182
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:201
ObjectFactory m_mac
MAC.
Definition wifi-test.cc:117
void SendOnePacket(Ptr< WifiNetDevice > dev)
Send one packet function.
Definition wifi-test.cc:127
ObjectFactory m_manager
manager
Definition wifi-test.cc:116
ObjectFactory m_propDelay
propagation delay
Definition wifi-test.cc:118
Wifi Test Suite.
a polymophic address class
Definition address.h:90
AttributeValue implementation for Boolean.
Definition boolean.h:26
use constant rates for data and RTS transmissions
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
The Extended Supported Rates Information Element.
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition he-phy.cc:1580
RU Specification.
Definition he-ru.h:57
RuType
The different HE Resource Unit (RU) types.
Definition he-ru.h:32
@ RU_26_TONE
Definition he-ru.h:33
@ RU_484_TONE
Definition he-ru.h:37
@ RU_996_TONE
Definition he-ru.h:38
@ RU_106_TONE
Definition he-ru.h:35
@ RU_52_TONE
Definition he-ru.h:34
@ RU_242_TONE
Definition he-ru.h:36
@ RU_2x996_TONE
Definition he-ru.h:39
Protocol header serialization and deserialization.
Definition header.h:33
Subclass of TestCase class adding the ability to test the serialization and deserialization of a Head...
void TestHeaderSerialization(const T &hdr, Args &&... args)
Serialize the given header in a buffer, then create a new header by deserializing from the buffer and...
The HT Operation Information Element.
an EUI-48 address
static Mac48Address Allocate()
Allocate a new Mac48Address.
Implement the header for management frames of type beacon.
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition node.cc:153
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition node.cc:138
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void Set(const std::string &name, const AttributeValue &value, Args &&... args)
Set an attribute to be set during construction.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
State
Represents the state for this agreement.
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
AttributeValue implementation for Pointer.
Ptr< T > Get() const
Definition pointer.h:223
calculate a propagation delay.
Smart pointer class similar to boost::intrusive_ptr.
Handles the packet queue and stores DCF/EDCA access parameters (one Txop per AC).
Definition qos-txop.h:52
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
indicates whether the socket has a priority set.
Definition socket.h:1307
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition socket.cc:843
Make it easy to create and manage PHY objects for the spectrum model.
void SetChannel(const Ptr< SpectrumChannel > channel)
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
char * PeekString() const
Peek the SSID.
Definition ssid.cc:67
AttributeValue implementation for Ssid.
Definition ssid.h:85
Hold variables of type string.
Definition string.h:45
The Supported Rates Information Element.
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
Handles the packet queue and stores DCF/EDCA access parameters (one Txop per AC).
Definition txop.h:56
a unique identifier for an interface.
Definition type-id.h: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:174
Hold together all Wifi-related objects.
void Set(std::string name, const AttributeValue &v)
void SetErrorRateModel(std::string type, Args &&... args)
Helper function used to set the error rate model.
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition wifi-phy.cc:687
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
Definition wifi-phy.h:930
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition wifi-phy.cc:1009
virtual void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition wifi-phy.cc:641
void SetOperatingChannel(const WifiPhyOperatingChannel &channel)
If the standard for this object has not been set yet, store the channel settings corresponding to the...
Definition wifi-phy.cc:1135
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition wifi-phy.cc:653
hold a list of per-remote-station state.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode.
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
MHz_u GetChannelWidth() const
manage and create wifi channel objects for the YANS model.
static YansWifiChannelHelper Default()
Create a channel helper in a default working state.
Make it easy to create and manage PHY objects for the YANS model.
802.11 PHY layer model
void SetChannel(const Ptr< YansWifiChannel > channel)
Set the YansWifiChannel this YansWifiPhy is to be connected to.
void SetInterferenceHelper(const Ptr< InterferenceHelper > helper) override
Sets the interference helper.
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:967
void Set(std::string path, const AttributeValue &value)
Definition config.cc:869
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:134
#define NS_TEST_EXPECT_MSG_LT_OR_EQ(actual, limit, msg)
Test that an actual value is less than or equal to a limit and report if not.
Definition test.h:820
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition test.h:241
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1368
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1380
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
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
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:65
MpduType type
type of MPDU
Definition wifi-types.h:66
SignalNoiseDbm structure.
Definition wifi-types.h:58
static void AssignWifiRandomStreams(Ptr< WifiMac > mac, int64_t stream)
Definition wifi-test.cc:58
static WifiTestSuite g_wifiTestSuite
the test suite
std::tuple< SupportedRates, std::optional< ExtendedSupportedRatesIE >, std::vector< Ssid > > MgtTestElems
List of Information Elements included in the test management frame.