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"),
1399{
1400}
1401
1405
1406void
1408{
1409 // Indicate the long retry counter has been increased in the wifi remote station manager
1411}
1412
1413void
1415{
1417
1418 // Generate same backoff for AC_VI and AC_VO
1419 // The below combination will work
1422 int64_t streamNumber = 100;
1423
1424 NodeContainer wifiNodes;
1425 wifiNodes.Create(2);
1426
1429 phy.SetChannel(channel.Create());
1430
1431 WifiHelper wifi;
1432 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
1433 "DataMode",
1434 StringValue("OfdmRate54Mbps"),
1435 "ControlMode",
1436 StringValue("OfdmRate24Mbps"));
1437 WifiMacHelper mac;
1438 Ssid ssid = Ssid("ns-3-ssid");
1439 mac.SetType("ns3::AdhocWifiMac", "QosSupported", BooleanValue(true));
1440
1441 NetDeviceContainer wifiDevices;
1442 wifiDevices = wifi.Install(phy, mac, wifiNodes);
1443
1444 // Assign fixed streams to random variables in use
1445 WifiHelper::AssignStreams(wifiDevices, streamNumber);
1446
1447 MobilityHelper mobility;
1449
1450 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
1451 positionAlloc->Add(Vector(10.0, 0.0, 0.0));
1452 mobility.SetPositionAllocator(positionAlloc);
1453
1454 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1455 mobility.Install(wifiNodes);
1456
1457 Ptr<WifiNetDevice> device1 = DynamicCast<WifiNetDevice>(wifiDevices.Get(0));
1458 Ptr<WifiNetDevice> device2 = DynamicCast<WifiNetDevice>(wifiDevices.Get(1));
1459
1460 PacketSocketAddress socket;
1461 socket.SetSingleDevice(device1->GetIfIndex());
1462 socket.SetPhysicalAddress(device2->GetAddress());
1463 socket.SetProtocol(1);
1464
1465 PacketSocketHelper packetSocket;
1466 packetSocket.Install(wifiNodes);
1467
1469 clientLowPriority->SetAttribute("PacketSize", UintegerValue(1460));
1470 clientLowPriority->SetAttribute("MaxPackets", UintegerValue(1));
1471 clientLowPriority->SetAttribute("Priority", UintegerValue(4)); // AC_VI
1472 clientLowPriority->SetRemote(socket);
1473 wifiNodes.Get(0)->AddApplication(clientLowPriority);
1474 clientLowPriority->SetStartTime(Seconds(0));
1475 clientLowPriority->SetStopTime(Seconds(1));
1476
1478 clientHighPriority->SetAttribute("PacketSize", UintegerValue(1460));
1479 clientHighPriority->SetAttribute("MaxPackets", UintegerValue(1));
1480 clientHighPriority->SetAttribute("Priority", UintegerValue(6)); // AC_VO
1481 clientHighPriority->SetRemote(socket);
1482 wifiNodes.Get(0)->AddApplication(clientHighPriority);
1483 clientHighPriority->SetStartTime(Seconds(0));
1484 clientHighPriority->SetStopTime(Seconds(1));
1485
1487 server->SetLocal(socket);
1488 wifiNodes.Get(1)->AddApplication(server);
1489 server->SetStartTime(Seconds(0));
1490 server->SetStopTime(Seconds(1));
1491
1492 Config::Connect("/NodeList/*/DeviceList/*/RemoteStationManager/MacTxDataFailed",
1494
1498
1500 1,
1501 "unexpected number of internal collisions!");
1502}
1503
1504//-----------------------------------------------------------------------------
1505/**
1506 * Make sure that the correct channel width and center frequency have been set
1507 * for OFDM basic rate transmissions and BSS channel widths larger than 20 MHz.
1508 *
1509 * The scenario considers a UDP transmission between a 40 MHz 802.11ac station and a
1510 * 40 MHz 802.11ac access point. All transmission parameters are checked so as
1511 * to ensure that only 3 {starting frequency, channelWidth, Number of subbands
1512 * in SpectrumModel, modulation type} tuples are used.
1513 *
1514 * See \bugid{2843}
1515 */
1516
1518{
1519 public:
1521 ~Bug2843TestCase() override;
1522 void DoRun() override;
1523
1524 private:
1525 /**
1526 * A tuple of {starting frequency, channelWidth, Number of subbands in SpectrumModel, modulation
1527 * type}
1528 */
1529 typedef std::tuple<Hz_u, MHz_u, uint32_t, WifiModulationClass> FreqWidthSubbandModulationTuple;
1530 std::vector<FreqWidthSubbandModulationTuple>
1531 m_distinctTuples; ///< vector of distinct {starting frequency, channelWidth, Number of
1532 ///< subbands in SpectrumModel, modulation type} tuples
1533
1534 /**
1535 * Stores the distinct {starting frequency, channelWidth, Number of subbands in SpectrumModel,
1536 * modulation type} tuples that have been used during the testcase run.
1537 * @param context the context
1538 * @param txParams spectrum signal parameters set by transmitter
1539 */
1540 void StoreDistinctTuple(std::string context, Ptr<SpectrumSignalParameters> txParams);
1541 /**
1542 * Triggers the arrival of a burst of 1000 Byte-long packets in the source device
1543 * @param numPackets number of packets in burst
1544 * @param sourceDevice pointer to the source NetDevice
1545 * @param destination address of the destination device
1546 */
1547 void SendPacketBurst(uint8_t numPackets,
1548 Ptr<NetDevice> sourceDevice,
1549 Address& destination) const;
1550
1551 MHz_u m_channelWidth; ///< channel width
1552};
1553
1555 : TestCase("Test case for Bug 2843"),
1557{
1558}
1559
1563
1564void
1566{
1567 // Extract starting frequency and number of subbands
1568 Ptr<const SpectrumModel> c = txParams->psd->GetSpectrumModel();
1569 std::size_t numBands = c->GetNumBands();
1570 const Hz_u startingFreq{c->Begin()->fl};
1571
1572 // Get channel bandwidth and modulation class
1575
1576 Ptr<WifiPpdu> ppdu = wifiTxParams->ppdu->Copy();
1577 WifiTxVector txVector = ppdu->GetTxVector();
1578 m_channelWidth = txVector.GetChannelWidth();
1579 WifiModulationClass modulationClass = txVector.GetMode().GetModulationClass();
1580
1581 // Build a tuple and check if seen before (if so store it)
1582 FreqWidthSubbandModulationTuple tupleForCurrentTx =
1583 std::make_tuple(startingFreq, m_channelWidth, numBands, modulationClass);
1584 bool found = false;
1585 for (auto it = m_distinctTuples.begin(); it != m_distinctTuples.end(); it++)
1586 {
1587 if (*it == tupleForCurrentTx)
1588 {
1589 found = true;
1590 }
1591 }
1592 if (!found)
1593 {
1594 m_distinctTuples.push_back(tupleForCurrentTx);
1595 }
1596}
1597
1598void
1600 Ptr<NetDevice> sourceDevice,
1601 Address& destination) const
1602{
1603 for (uint8_t i = 0; i < numPackets; i++)
1604 {
1605 Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
1606 sourceDevice->Send(pkt, destination, 0);
1607 }
1608}
1609
1610void
1612{
1613 MHz_u channelWidth{40}; // at least 40 MHz expected here
1614
1615 NodeContainer wifiStaNode;
1616 wifiStaNode.Create(1);
1617
1618 NodeContainer wifiApNode;
1619 wifiApNode.Create(1);
1620
1621 SpectrumWifiPhyHelper spectrumPhy;
1624 lossModel->SetFrequency(5.190e9);
1625 spectrumChannel->AddPropagationLossModel(lossModel);
1626
1629 spectrumChannel->SetPropagationDelayModel(delayModel);
1630
1631 spectrumPhy.SetChannel(spectrumChannel);
1632 spectrumPhy.SetErrorRateModel("ns3::NistErrorRateModel");
1633 spectrumPhy.Set("ChannelSettings", StringValue("{38, 40, BAND_5GHZ, 0}"));
1634 spectrumPhy.Set("TxPowerStart", DoubleValue(10));
1635 spectrumPhy.Set("TxPowerEnd", DoubleValue(10));
1636
1637 WifiHelper wifi;
1638 wifi.SetStandard(WIFI_STANDARD_80211ac);
1639 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
1640 "DataMode",
1641 StringValue("VhtMcs8"),
1642 "ControlMode",
1643 StringValue("VhtMcs8"),
1644 "RtsCtsThreshold",
1645 StringValue("500")); // so as to force RTS/CTS for data frames
1646
1647 WifiMacHelper mac;
1648 mac.SetType("ns3::StaWifiMac");
1649 NetDeviceContainer staDevice;
1650 staDevice = wifi.Install(spectrumPhy, mac, wifiStaNode);
1651
1652 mac.SetType("ns3::ApWifiMac");
1653 NetDeviceContainer apDevice;
1654 apDevice = wifi.Install(spectrumPhy, mac, wifiApNode);
1655
1656 MobilityHelper mobility;
1658 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
1659 positionAlloc->Add(Vector(1.0, 0.0, 0.0)); // put close enough in order to use MCS
1660 mobility.SetPositionAllocator(positionAlloc);
1661
1662 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1663 mobility.Install(wifiApNode);
1664 mobility.Install(wifiStaNode);
1665
1666 // Send two 5 packet-bursts
1669 this,
1670 5,
1671 apDevice.Get(0),
1672 staDevice.Get(0)->GetAddress());
1675 this,
1676 5,
1677 apDevice.Get(0),
1678 staDevice.Get(0)->GetAddress());
1679
1680 Config::Connect("/ChannelList/*/$ns3::MultiModelSpectrumChannel/TxSigParams",
1682
1685
1687
1688 // {starting frequency, channelWidth, Number of subbands in SpectrumModel, modulation type}
1689 // tuples
1690 std::size_t numberTuples = m_distinctTuples.size();
1691 NS_TEST_ASSERT_MSG_EQ(numberTuples, 3, "Only three distinct tuples expected");
1692 NS_TEST_EXPECT_MSG_EQ(std::get<0>(m_distinctTuples[0]) - Hz_u{20e6},
1693 std::get<0>(m_distinctTuples[1]),
1694 "The starting frequency of the first tuple should be shifted 20 MHz to "
1695 "the right wrt second tuple");
1696 // Note that the first tuple should the one initiated by the beacon, i.e. non-HT OFDM (20 MHz)
1698 MHz_u{20},
1699 "First tuple's channel width should be 20 MHz");
1701 193,
1702 "First tuple should have 193 subbands (64+DC, 20MHz+DC, inband and 64*2 "
1703 "out-of-band, 20MHz on each side)");
1706 "First tuple should be OFDM");
1707 // Second tuple: data frames, VHT (40 MHz)
1709 channelWidth,
1710 "Second tuple's channel width should be 40 MHz");
1712 385,
1713 "Second tuple should have 385 subbands (128+DC, 40MHz+DC, inband and "
1714 "128*2 out-of-band, 40MHz on each side)");
1717 "Second tuple should be VHT_OFDM");
1718 // Third tuple: control response frames, non-HT (OFDM) duplicate (40 MHz)
1720 std::get<0>(m_distinctTuples[2]),
1721 "The starting frequency of the third tuple should be the same as the "
1722 "second tuple");
1724 channelWidth,
1725 "Third tuple's channel width should be 40 MHz");
1727 385,
1728 "Third tuple should have 385 subbands (128+DC, 40MHz+DC, inband and "
1729 "128*2 out-of-band, 40MHz on each side)");
1732 "Third tuple should be OFDM");
1733}
1734
1735//-----------------------------------------------------------------------------
1736/**
1737 * Make sure that the channel width and the channel number can be changed at runtime.
1738 *
1739 * The scenario considers an access point and a station using a 20 MHz channel width.
1740 * After 1s, we change the channel width and the channel number to use a 40 MHz channel.
1741 * The tests checks the operational channel width sent in Beacon frames
1742 * and verify that the association procedure is executed twice.
1743 *
1744 * See \bugid{2831}
1745 */
1746
1748{
1749 public:
1751 ~Bug2831TestCase() override;
1752 void DoRun() override;
1753
1754 private:
1755 /**
1756 * Function called to change the supported channel width at runtime
1757 */
1759 /**
1760 * Callback triggered when a packet is received by the PHYs
1761 * @param context the context
1762 * @param p the received packet
1763 * @param rxPowersW the received power per channel band in watts
1764 */
1765 void RxCallback(std::string context, Ptr<const Packet> p, RxPowerWattPerChannelBand rxPowersW);
1766
1769
1770 uint16_t m_assocReqCount; ///< count number of association requests
1771 uint16_t m_assocRespCount; ///< count number of association responses
1772 uint16_t m_countOperationalChannelWidth20; ///< count number of beacon frames announcing a 20
1773 ///< MHz operating channel width
1774 uint16_t m_countOperationalChannelWidth40; ///< count number of beacon frames announcing a 40
1775 ///< MHz operating channel width
1776};
1777
1786
1790
1791void
1793{
1794 m_apPhy->SetOperatingChannel(WifiPhy::ChannelTuple{38, 40, WIFI_PHY_BAND_5GHZ, 0});
1795 m_staPhy->SetOperatingChannel(WifiPhy::ChannelTuple{38, 40, WIFI_PHY_BAND_5GHZ, 0});
1796}
1797
1798void
1801 RxPowerWattPerChannelBand rxPowersW)
1802{
1803 Ptr<Packet> packet = p->Copy();
1804 WifiMacHeader hdr;
1805 packet->RemoveHeader(hdr);
1806 if (hdr.IsAssocReq())
1807 {
1809 }
1810 else if (hdr.IsAssocResp())
1811 {
1813 }
1814 else if (hdr.IsBeacon())
1815 {
1816 MgtBeaconHeader beacon;
1817 packet->RemoveHeader(beacon);
1818 const auto& htOperation = beacon.Get<HtOperation>();
1819 if (htOperation.has_value() && htOperation->GetStaChannelWidth() > 0)
1820 {
1822 }
1823 else
1824 {
1826 }
1827 }
1828}
1829
1830void
1832{
1834 ObjectFactory propDelay;
1835 propDelay.SetTypeId("ns3::ConstantSpeedPropagationDelayModel");
1836 Ptr<PropagationDelayModel> propagationDelay = propDelay.Create<PropagationDelayModel>();
1838 channel->SetPropagationDelayModel(propagationDelay);
1839 channel->SetPropagationLossModel(propagationLoss);
1840
1841 Ptr<Node> apNode = CreateObject<Node>();
1843 apNode->AddDevice(apDev);
1844 apDev->SetStandard(WIFI_STANDARD_80211ax);
1846 apDev->SetHtConfiguration(apHtConfiguration);
1847 ObjectFactory manager;
1848 manager.SetTypeId("ns3::ConstantRateWifiManager");
1849 apDev->SetRemoteStationManager(manager.Create<WifiRemoteStationManager>());
1850
1852 apMobility->SetPosition(Vector(0.0, 0.0, 0.0));
1853 apNode->AggregateObject(apMobility);
1854
1855 auto error = CreateObject<YansErrorRateModel>();
1857 apDev->SetPhy(m_apPhy);
1859 m_apPhy->SetInterferenceHelper(apInterferenceHelper);
1860 m_apPhy->SetErrorRateModel(error);
1861 m_apPhy->SetChannel(channel);
1862 m_apPhy->SetMobility(apMobility);
1863 m_apPhy->SetDevice(apDev);
1864 m_apPhy->ConfigureStandard(WIFI_STANDARD_80211ax);
1865 m_apPhy->SetOperatingChannel(WifiPhy::ChannelTuple{36, 20, WIFI_PHY_BAND_5GHZ, 0});
1866
1867 ObjectFactory mac;
1868 mac.SetTypeId("ns3::ApWifiMac");
1869 mac.Set("EnableBeaconJitter", BooleanValue(false));
1870 mac.Set("QosSupported", BooleanValue(true));
1871 for (const std::string ac : {"BE", "BK", "VI", "VO"})
1872 {
1873 auto qosTxop =
1874 CreateObjectWithAttributes<QosTxop>("AcIndex", StringValue(std::string("AC_") + ac));
1875 mac.Set(ac + "_Txop", PointerValue(qosTxop));
1876 }
1877 auto apMac = mac.Create<WifiMac>();
1878 apMac->SetDevice(apDev);
1879 apMac->SetAddress(Mac48Address::Allocate());
1880 apDev->SetMac(apMac);
1881 apMac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
1882 apMac->SetFrameExchangeManagers({CreateObject<HeFrameExchangeManager>()});
1883 apMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
1884 Ptr<FrameExchangeManager> fem = apMac->GetFrameExchangeManager();
1885 fem->SetAddress(apMac->GetAddress());
1887 protectionManager->SetWifiMac(apMac);
1888 fem->SetProtectionManager(protectionManager);
1890 ackManager->SetWifiMac(apMac);
1891 fem->SetAckManager(ackManager);
1892
1893 Ptr<Node> staNode = CreateObject<Node>();
1895 staNode->AddDevice(staDev);
1896 staDev->SetStandard(WIFI_STANDARD_80211ax);
1898 staDev->SetHtConfiguration(staHtConfiguration);
1899 staDev->SetRemoteStationManager(manager.Create<WifiRemoteStationManager>());
1900
1902 staMobility->SetPosition(Vector(1.0, 0.0, 0.0));
1903 staNode->AggregateObject(staMobility);
1904
1906 staDev->SetPhy(m_staPhy);
1908 m_staPhy->SetInterferenceHelper(staInterferenceHelper);
1909 m_staPhy->SetErrorRateModel(error);
1910 m_staPhy->SetChannel(channel);
1911 m_staPhy->SetMobility(staMobility);
1912 m_staPhy->SetDevice(apDev);
1913 m_staPhy->ConfigureStandard(WIFI_STANDARD_80211ax);
1914 m_staPhy->SetOperatingChannel(WifiPhy::ChannelTuple{36, 20, WIFI_PHY_BAND_5GHZ, 0});
1915
1916 mac.SetTypeId("ns3::StaWifiMac");
1917 for (const std::string ac : {"BE", "BK", "VI", "VO"})
1918 {
1919 auto qosTxop =
1920 CreateObjectWithAttributes<QosTxop>("AcIndex", StringValue(std::string("AC_") + ac));
1921 mac.Set(ac + "_Txop", PointerValue(qosTxop));
1922 }
1923 auto staMac = mac.Create<WifiMac>();
1924 staDev->SetMac(staMac);
1925 staMac->SetDevice(staDev);
1926 staMac->SetAddress(Mac48Address::Allocate());
1927 staMac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
1928 staMac->SetFrameExchangeManagers({CreateObject<HeFrameExchangeManager>()});
1930 staMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
1931 fem = staMac->GetFrameExchangeManager();
1932 fem->SetAddress(staMac->GetAddress());
1933 protectionManager = CreateObject<WifiDefaultProtectionManager>();
1934 protectionManager->SetWifiMac(staMac);
1935 fem->SetProtectionManager(protectionManager);
1937 ackManager->SetWifiMac(staMac);
1938 fem->SetAckManager(ackManager);
1939
1940 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxBegin",
1942
1944
1948
1949 NS_TEST_ASSERT_MSG_EQ(m_assocReqCount, 2, "Second Association request not received");
1950 NS_TEST_ASSERT_MSG_EQ(m_assocRespCount, 2, "Second Association response not received");
1952 10,
1953 "Incorrect operational channel width before channel change");
1955 20,
1956 "Incorrect operational channel width after channel change");
1957}
1958
1959//-----------------------------------------------------------------------------
1960/**
1961 * Make sure that Wifi STA is correctly associating to the best AP (i.e.,
1962 * nearest from STA). We consider 3 AP and 1 STA. This test case consisted of
1963 * three sub tests:
1964 * - The best AP sends its beacon later than the other APs. STA is expected
1965 * to associate to the best AP.
1966 * - The STA is using active scanning instead of passive, the rest of the
1967 * APs works normally. STA is expected to associate to the best AP
1968 * - The nearest AP is turned off after sending beacon and while STA is
1969 * still scanning. STA is expected to associate to the second best AP.
1970 *
1971 * See \bugid{2399}
1972 * @todo Add explicit association refusal test if ns-3 implemented it.
1973 */
1974
1976{
1977 public:
1979 ~StaWifiMacScanningTestCase() override;
1980 void DoRun() override;
1981
1982 private:
1983 /**
1984 * Callback function on STA assoc event
1985 * @param context context string
1986 * @param bssid the associated AP's bssid
1987 */
1988 void AssocCallback(std::string context, Mac48Address bssid);
1989 /**
1990 * Turn beacon generation on the AP node
1991 * @param apNode the AP node
1992 */
1993 void TurnBeaconGenerationOn(Ptr<Node> apNode);
1994 /**
1995 * Turn the AP node off
1996 * @param apNode the AP node
1997 */
1998 void TurnApOff(Ptr<Node> apNode);
1999 /**
2000 * Setup test
2001 * @param nearestApBeaconGeneration set BeaconGeneration attribute of the nearest AP
2002 * @param staActiveProbe set ActiveProbing attribute of the STA
2003 * @return node container containing all nodes
2004 */
2005 NodeContainer Setup(bool nearestApBeaconGeneration, bool staActiveProbe);
2006
2007 Mac48Address m_associatedApBssid; ///< Associated AP's bssid
2008};
2009
2011 : TestCase("Test case for StaWifiMac scanning capability")
2012{
2013}
2014
2018
2019void
2021{
2022 m_associatedApBssid = bssid;
2023}
2024
2025void
2027{
2028 Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice>(apNode->GetDevice(0));
2029 Ptr<ApWifiMac> mac = DynamicCast<ApWifiMac>(netDevice->GetMac());
2030 mac->SetAttribute("BeaconGeneration", BooleanValue(true));
2031}
2032
2033void
2035{
2036 Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice>(apNode->GetDevice(0));
2037 Ptr<WifiPhy> phy = netDevice->GetPhy();
2038 phy->SetOffMode();
2039}
2040
2042StaWifiMacScanningTestCase::Setup(bool nearestApBeaconGeneration, bool staActiveProbe)
2043{
2046 int64_t streamNumber = 1;
2047
2048 NodeContainer apNodes;
2049 apNodes.Create(2);
2050
2051 Ptr<Node> apNodeNearest = CreateObject<Node>();
2052 Ptr<Node> staNode = CreateObject<Node>();
2053
2056 phy.SetChannel(channel.Create());
2057
2058 WifiHelper wifi;
2059 wifi.SetStandard(WIFI_STANDARD_80211n);
2060 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager");
2061
2062 WifiMacHelper mac;
2063 NetDeviceContainer apDevice;
2064 NetDeviceContainer apDeviceNearest;
2065 mac.SetType("ns3::ApWifiMac", "BeaconGeneration", BooleanValue(true));
2066 apDevice = wifi.Install(phy, mac, apNodes);
2067 mac.SetType("ns3::ApWifiMac", "BeaconGeneration", BooleanValue(nearestApBeaconGeneration));
2068 apDeviceNearest = wifi.Install(phy, mac, apNodeNearest);
2069
2070 NetDeviceContainer staDevice;
2071 mac.SetType("ns3::StaWifiMac", "ActiveProbing", BooleanValue(staActiveProbe));
2072 staDevice = wifi.Install(phy, mac, staNode);
2073
2074 // Assign fixed streams to random variables in use
2075 WifiHelper::AssignStreams(apDevice, streamNumber);
2076 WifiHelper::AssignStreams(apDeviceNearest, streamNumber + 1);
2077 WifiHelper::AssignStreams(staDevice, streamNumber + 2);
2078
2079 MobilityHelper mobility;
2081 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Furthest AP
2082 positionAlloc->Add(Vector(10.0, 0.0, 0.0)); // Second nearest AP
2083 positionAlloc->Add(Vector(5.0, 5.0, 0.0)); // Nearest AP
2084 positionAlloc->Add(Vector(6.0, 5.0, 0.0)); // STA
2085 mobility.SetPositionAllocator(positionAlloc);
2086
2087 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2088 mobility.Install(apNodes);
2089 mobility.Install(apNodeNearest);
2090 mobility.Install(staNode);
2091
2092 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/Assoc",
2094
2095 NodeContainer allNodes = NodeContainer(apNodes, apNodeNearest, staNode);
2096 return allNodes;
2097}
2098
2099void
2101{
2102 {
2103 NodeContainer nodes = Setup(false, false);
2104 Ptr<Node> nearestAp = nodes.Get(2);
2105 Mac48Address nearestApAddr =
2106 DynamicCast<WifiNetDevice>(nearestAp->GetDevice(0))->GetMac()->GetAddress();
2107
2110 this,
2111 nearestAp);
2112
2116
2118 nearestApAddr,
2119 "STA is associated to the wrong AP");
2120 }
2122 {
2123 NodeContainer nodes = Setup(true, true);
2124 Ptr<Node> nearestAp = nodes.Get(2);
2125 Mac48Address nearestApAddr =
2126 DynamicCast<WifiNetDevice>(nearestAp->GetDevice(0))->GetMac()->GetAddress();
2127
2131
2133 nearestApAddr,
2134 "STA is associated to the wrong AP");
2135 }
2137 {
2138 NodeContainer nodes = Setup(true, false);
2139 Ptr<Node> nearestAp = nodes.Get(2);
2140 Mac48Address secondNearestApAddr =
2141 DynamicCast<WifiNetDevice>(nodes.Get(1)->GetDevice(0))->GetMac()->GetAddress();
2142
2144
2148
2150 secondNearestApAddr,
2151 "STA is associated to the wrong AP");
2152 }
2153}
2154
2155//-----------------------------------------------------------------------------
2156/**
2157 * Make sure that the ADDBA handshake process is protected.
2158 *
2159 * The scenario considers an access point and a station. It utilizes
2160 * ReceiveListErrorModel to drop by force ADDBA request on STA or ADDBA
2161 * response on AP. The AP sends 5 packets of each 1000 bytes (thus generating
2162 * BA agreement), 2 times during the test at 0.5s and 0.8s. We only drop the
2163 * first ADDBA request/response of the first BA negotiation. Therefore, we
2164 * expect that the packets still in queue after the failed BA agreement will be
2165 * sent with normal MPDU, and packets queued after that should be sent with
2166 * A-MPDU.
2167 *
2168 * This test consider 2 cases:
2169 *
2170 * 1. ADDBA request packets are blocked on receive at STA, triggering
2171 * transmission failure at AP
2172 * 2. ADDBA response packets are blocked on receive at AP, STA stops
2173 * retransmission of ADDBA response
2174 *
2175 * See \bugid{2470}
2176 */
2177
2179{
2180 public:
2182 ~Bug2470TestCase() override;
2183 void DoRun() override;
2184
2185 private:
2186 /**
2187 * Callback when ADDBA state changed
2188 * @param context node context
2189 * @param t the time the state changed
2190 * @param recipient the MAC address of the recipient
2191 * @param tid the TID
2192 * @param state the state
2193 */
2194 void AddbaStateChangedCallback(std::string context,
2195 Time t,
2196 Mac48Address recipient,
2197 uint8_t tid,
2199 /**
2200 * Callback when a frame is transmitted.
2201 * @param rxErrorModel the post reception error model on the receiver
2202 * @param context the context
2203 * @param psduMap the PSDU map
2204 * @param txVector the TX vector
2205 * @param txPowerW the tx power in Watts
2206 */
2207 void TxCallback(Ptr<ListErrorModel> rxErrorModel,
2208 std::string context,
2209 WifiConstPsduMap psduMap,
2210 WifiTxVector txVector,
2211 double txPowerW);
2212
2213 /**
2214 * Callback when packet is received
2215 * @param context node context
2216 * @param p the received packet
2217 * @param channelFreqMhz the channel frequency in MHz
2218 * @param txVector the TX vector
2219 * @param aMpdu the A-MPDU info
2220 * @param signalNoise the signal noise in dBm
2221 * @param staId the STA-ID
2222 */
2223 void RxCallback(std::string context,
2225 uint16_t channelFreqMhz,
2226 WifiTxVector txVector,
2227 MpduInfo aMpdu,
2228 SignalNoiseDbm signalNoise,
2229 uint16_t staId);
2230 /**
2231 * Callback when packet is dropped
2232 * @param context node context
2233 * @param p the failed packet
2234 * @param snr the SNR of the failed packet in linear scale
2235 */
2236 void RxErrorCallback(std::string context, Ptr<const Packet> p, double snr);
2237 /**
2238 * Triggers the arrival of a burst of 1000 Byte-long packets in the source device
2239 * @param numPackets number of packets in burst
2240 * @param sourceDevice pointer to the source NetDevice
2241 * @param destination address of the destination device
2242 */
2243 void SendPacketBurst(uint32_t numPackets,
2244 Ptr<NetDevice> sourceDevice,
2245 Address& destination) const;
2246 /**
2247 * Run subtest for this test suite
2248 * @param rcvErrorType type of station (STA or AP) to install the post reception error model on
2249 */
2250 void RunSubtest(TypeOfStation rcvErrorType);
2251
2252 uint16_t m_receivedNormalMpduCount; ///< Count received normal MPDU packets on STA
2253 uint16_t m_receivedAmpduCount; ///< Count received A-MPDU packets on STA
2254 uint16_t m_failedActionCount; ///< Count failed ADDBA request/response
2255 uint16_t m_addbaEstablishedCount; ///< Count number of times ADDBA state machine is in
2256 ///< established state
2257 uint16_t m_addbaPendingCount; ///< Count number of times ADDBA state machine is in pending state
2258 uint16_t
2259 m_addbaRejectedCount; ///< Count number of times ADDBA state machine is in rejected state
2260 uint16_t
2261 m_addbaNoReplyCount; ///< Count number of times ADDBA state machine is in no_reply state
2262 uint16_t m_addbaResetCount; ///< Count number of times ADDBA state machine is in reset state
2263 Time m_2ndPktSetStart; ///< time the second set of packets is generated
2264};
2265
2279
2283
2284void
2286 Time t,
2287 Mac48Address recipient,
2288 uint8_t tid,
2290{
2291 switch (state)
2292 {
2295 break;
2298 break;
2301 break;
2304 break;
2307 break;
2308 }
2309}
2310
2311void
2313 std::string context,
2314 WifiConstPsduMap psduMap,
2315 WifiTxVector txVector,
2316 double txPowerW)
2317{
2318 auto psdu = psduMap.begin()->second;
2319
2320 // The sender is transmitting an ADDBA_REQUEST or ADDBA_RESPONSE frame. If this is
2321 // the first attempt at establishing a BA agreement (i.e., before the second set of packets
2322 // is generated), make the reception of the frame fail at the receiver.
2323 if (psdu->GetHeader(0).GetType() == WIFI_MAC_MGT_ACTION && Simulator::Now() < m_2ndPktSetStart)
2324 {
2325 auto uid = psdu->GetPayload(0)->GetUid();
2326 rxErrorModel->SetList({uid});
2327 }
2328}
2329
2330void
2333 uint16_t channelFreqMhz,
2334 WifiTxVector txVector,
2335 MpduInfo aMpdu,
2336 SignalNoiseDbm signalNoise,
2337 uint16_t staId)
2338{
2339 Ptr<Packet> packet = p->Copy();
2340 if (aMpdu.type != MpduType::NORMAL_MPDU)
2341 {
2343 }
2344 else
2345 {
2346 WifiMacHeader hdr;
2347 packet->RemoveHeader(hdr);
2348 if (hdr.IsData())
2349 {
2351 }
2352 }
2353}
2354
2355void
2356Bug2470TestCase::RxErrorCallback(std::string context, Ptr<const Packet> p, double snr)
2357{
2358 Ptr<Packet> packet = p->Copy();
2359 WifiMacHeader hdr;
2360 packet->RemoveHeader(hdr);
2361 if (hdr.IsAction())
2362 {
2364 }
2365}
2366
2367void
2369 Ptr<NetDevice> sourceDevice,
2370 Address& destination) const
2371{
2372 for (uint32_t i = 0; i < numPackets; i++)
2373 {
2374 Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
2375 sourceDevice->Send(pkt, destination, 0);
2376 }
2377}
2378
2379void
2381{
2384 int64_t streamNumber = 200;
2385
2386 NodeContainer wifiApNode;
2387 NodeContainer wifiStaNode;
2388 wifiApNode.Create(1);
2389 wifiStaNode.Create(1);
2390
2393 phy.SetChannel(channel.Create());
2394
2395 WifiHelper wifi;
2396 wifi.SetStandard(WIFI_STANDARD_80211n);
2397 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
2398 "DataMode",
2399 StringValue("HtMcs7"),
2400 "ControlMode",
2401 StringValue("HtMcs7"));
2402
2403 WifiMacHelper mac;
2404 NetDeviceContainer apDevice;
2405 phy.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}"));
2406 mac.SetType("ns3::ApWifiMac", "EnableBeaconJitter", BooleanValue(false));
2407 apDevice = wifi.Install(phy, mac, wifiApNode);
2408
2409 NetDeviceContainer staDevice;
2410 mac.SetType("ns3::StaWifiMac");
2411 staDevice = wifi.Install(phy, mac, wifiStaNode);
2412
2413 // Assign fixed streams to random variables in use
2414 WifiHelper::AssignStreams(apDevice, streamNumber);
2415 WifiHelper::AssignStreams(staDevice, streamNumber);
2416
2417 MobilityHelper mobility;
2419 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2420 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
2421 mobility.SetPositionAllocator(positionAlloc);
2422
2423 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2424 mobility.Install(wifiApNode);
2425 mobility.Install(wifiStaNode);
2426
2427 auto rxErrorModel = CreateObject<ListErrorModel>();
2428 Ptr<WifiMac> wifiMac;
2429 switch (rcvErrorType)
2430 {
2431 case AP:
2432 wifiMac = DynamicCast<WifiNetDevice>(apDevice.Get(0))->GetMac();
2433 break;
2434 case STA:
2435 wifiMac = DynamicCast<WifiNetDevice>(staDevice.Get(0))->GetMac();
2436 break;
2437 default:
2438 NS_ABORT_MSG("Station type " << +rcvErrorType << " cannot be used here");
2439 }
2440 wifiMac->GetWifiPhy(0)->SetPostReceptionErrorModel(rxErrorModel);
2441
2443 "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/MonitorSnifferRx",
2445 Config::Connect("/NodeList/*/DeviceList/*/Phy/State/RxError",
2447 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/BE_Txop/"
2448 "BlockAckManager/AgreementState",
2450 Config::Connect("/NodeList/" + std::to_string(rcvErrorType == STA ? 0 /* AP */ : 1 /* STA */) +
2451 "/DeviceList/*/$ns3::WifiNetDevice/Phys/0/PhyTxPsduBegin",
2452 MakeCallback(&Bug2470TestCase::TxCallback, this).Bind(rxErrorModel));
2453
2456 this,
2457 1,
2458 apDevice.Get(0),
2459 staDevice.Get(0)->GetAddress());
2462 this,
2463 4,
2464 apDevice.Get(0),
2465 staDevice.Get(0)->GetAddress());
2468 this,
2469 1,
2470 apDevice.Get(0),
2471 staDevice.Get(0)->GetAddress());
2474 this,
2475 4,
2476 apDevice.Get(0),
2477 staDevice.Get(0)->GetAddress());
2478
2482}
2483
2484void
2486{
2487 {
2488 RunSubtest(STA);
2489 NS_TEST_ASSERT_MSG_EQ(m_failedActionCount, 7, "ADDBA request packets are not failed");
2490 // There are two sets of 5 packets to be transmitted. The first 5 packets should be sent by
2491 // normal MPDU because of failed ADDBA handshake. For the second set, the first packet
2492 // should be sent by normal MPDU, and the rest with A-MPDU. In total we expect to receive 6
2493 // normal MPDU packets and 4 A-MPDU packet.
2495 6,
2496 "Receiving incorrect number of normal MPDU packet on subtest 1");
2498 4,
2499 "Receiving incorrect number of A-MPDU packets on subtest 1");
2500
2502 1,
2503 "Incorrect number of times the ADDBA state machine was in "
2504 "established state on subtest 1");
2507 2,
2508 "Incorrect number of times the ADDBA state machine was in pending state on subtest 1");
2511 0,
2512 "Incorrect number of times the ADDBA state machine was in rejected state on subtest 1");
2515 1,
2516 "Incorrect number of times the ADDBA state machine was in no_reply state on subtest 1");
2519 1,
2520 "Incorrect number of times the ADDBA state machine was in reset state on subtest 1");
2521 }
2522
2531
2532 {
2533 RunSubtest(AP);
2534 NS_TEST_ASSERT_MSG_EQ(m_failedActionCount, 7, "ADDBA response packets are not failed");
2535 // Similar to subtest 1, we also expect to receive 6 normal MPDU packets and 4 A-MPDU
2536 // packets.
2538 6,
2539 "Receiving incorrect number of normal MPDU packet on subtest 2");
2541 4,
2542 "Receiving incorrect number of A-MPDU packet on subtest 2");
2543
2545 1,
2546 "Incorrect number of times the ADDBA state machine was in "
2547 "established state on subtest 2");
2550 2,
2551 "Incorrect number of times the ADDBA state machine was in pending state on subtest 2");
2554 0,
2555 "Incorrect number of times the ADDBA state machine was in rejected state on subtest 2");
2558 1,
2559 "Incorrect number of times the ADDBA state machine was in no_reply state on subtest 2");
2562 1,
2563 "Incorrect number of times the ADDBA state machine was in reset state on subtest 2");
2564 }
2565
2566 // TODO: In the second test set, it does not go to reset state since ADDBA response is received
2567 // after timeout (NO_REPLY) but before it does not enter RESET state. More tests should be
2568 // written to verify all possible scenarios.
2569}
2570
2571//-----------------------------------------------------------------------------
2572/**
2573 * Make sure that Ideal rate manager recovers when the station is moving away from the access point.
2574 *
2575 * The scenario considers an access point and a moving station.
2576 * Initially, the station is located at 1 meter from the access point.
2577 * After 1s, the station moves away from the access for 0.5s to
2578 * reach a point away of 50 meters from the access point.
2579 * The tests checks the Ideal rate manager is reset once it has
2580 * failed to transmit a data packet, so that the next data packets
2581 * can be successfully transmitted using a lower modulation.
2582 *
2583 * See \issueid{40}
2584 */
2585
2587{
2588 public:
2590 ~Issue40TestCase() override;
2591 void DoRun() override;
2592
2593 private:
2594 /**
2595 * Run one function
2596 * @param useAmpdu flag to indicate whether the test should be run with A-MPDU
2597 */
2598 void RunOne(bool useAmpdu);
2599
2600 /**
2601 * Callback when packet is successfully received
2602 * @param context node context
2603 * @param p the received packet
2604 */
2605 void RxSuccessCallback(std::string context, Ptr<const Packet> p);
2606 /**
2607 * Triggers the arrival of 1000 Byte-long packets in the source device
2608 * @param numPackets number of packets in burst
2609 * @param sourceDevice pointer to the source NetDevice
2610 * @param destination address of the destination device
2611 */
2612 void SendPackets(uint8_t numPackets, Ptr<NetDevice> sourceDevice, Address& destination);
2613 /**
2614 * Transmit final data failed function
2615 * @param context the context
2616 * @param address the MAC address
2617 */
2618 void TxFinalDataFailedCallback(std::string context, Mac48Address address);
2619
2620 uint16_t m_rxCount; ///< Count number of successfully received data packets
2621 uint16_t m_txCount; ///< Count number of transmitted data packets
2622 uint16_t
2623 m_txMacFinalDataFailedCount; ///< Count number of unsuccessfully transmitted data packets
2624};
2625
2627 : TestCase("Test case for issue #40"),
2628 m_rxCount(0),
2629 m_txCount(0),
2631{
2632}
2633
2637
2638void
2640{
2641 m_rxCount++;
2642}
2643
2644void
2645Issue40TestCase::SendPackets(uint8_t numPackets, Ptr<NetDevice> sourceDevice, Address& destination)
2646{
2647 for (uint8_t i = 0; i < numPackets; i++)
2648 {
2649 Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
2650 sourceDevice->Send(pkt, destination, 0);
2651 m_txCount++;
2652 }
2653}
2654
2655void
2660
2661void
2663{
2664 m_rxCount = 0;
2665 m_txCount = 0;
2667
2670 int64_t streamNumber = 100;
2671
2672 NodeContainer wifiApNode;
2673 NodeContainer wifiStaNode;
2674 wifiApNode.Create(1);
2675 wifiStaNode.Create(1);
2676
2679 phy.SetChannel(channel.Create());
2680
2681 WifiHelper wifi;
2682 // use HT standard so that BlockAck agreement is not established in the useAmpdu false case
2683 wifi.SetStandard(useAmpdu ? WIFI_STANDARD_80211ac : WIFI_STANDARD_80211n);
2684 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
2685
2686 WifiMacHelper mac;
2687 NetDeviceContainer apDevice;
2688 mac.SetType("ns3::ApWifiMac");
2689 apDevice = wifi.Install(phy, mac, wifiApNode);
2690
2691 NetDeviceContainer staDevice;
2692 mac.SetType("ns3::StaWifiMac");
2693 staDevice = wifi.Install(phy, mac, wifiStaNode);
2694
2695 // Assign fixed streams to random variables in use
2696 WifiHelper::AssignStreams(apDevice, streamNumber);
2697 WifiHelper::AssignStreams(staDevice, streamNumber);
2698
2699 MobilityHelper mobility;
2701 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2702 positionAlloc->Add(Vector(10.0, 0.0, 0.0));
2703 mobility.SetPositionAllocator(positionAlloc);
2704
2705 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2706 mobility.Install(wifiApNode);
2707
2708 mobility.SetMobilityModel("ns3::WaypointMobilityModel");
2709 mobility.Install(wifiStaNode);
2710
2711 Config::Connect("/NodeList/*/DeviceList/*/RemoteStationManager/MacTxFinalDataFailed",
2713 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/MacRx",
2715
2716 Ptr<WaypointMobilityModel> staWaypointMobility =
2718 staWaypointMobility->AddWaypoint(Waypoint(Seconds(1), Vector(10.0, 0.0, 0.0)));
2719 staWaypointMobility->AddWaypoint(Waypoint(Seconds(1.5), Vector(50.0, 0.0, 0.0)));
2720
2721 if (useAmpdu)
2722 {
2723 // Disable use of BAR that are sent with the lowest modulation so that we can also reproduce
2724 // the problem with A-MPDU, i.e. the lack of feedback about SNR change
2725 Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice>(apDevice.Get(0));
2726 PointerValue ptr;
2727 ap_device->GetMac()->GetAttribute("BE_Txop", ptr);
2728 ptr.Get<QosTxop>()->SetAttribute("UseExplicitBarAfterMissedBlockAck", BooleanValue(false));
2729 }
2730
2731 // Transmit a first data packet before the station moves: it should be sent with a high
2732 // modulation and successfully received
2735 this,
2736 useAmpdu ? 2 : 1,
2737 apDevice.Get(0),
2738 staDevice.Get(0)->GetAddress());
2739
2740 // Transmit a second data packet once the station is away from the access point: it should be
2741 // sent with the same high modulation and be unsuccessfully received
2744 this,
2745 useAmpdu ? 2 : 1,
2746 apDevice.Get(0),
2747 staDevice.Get(0)->GetAddress());
2748
2749 // Keep on transmitting data packets while the station is away from the access point: it should
2750 // be sent with a lower modulation and be successfully received
2753 this,
2754 useAmpdu ? 2 : 1,
2755 apDevice.Get(0),
2756 staDevice.Get(0)->GetAddress());
2759 this,
2760 useAmpdu ? 2 : 1,
2761 apDevice.Get(0),
2762 staDevice.Get(0)->GetAddress());
2765 this,
2766 useAmpdu ? 2 : 1,
2767 apDevice.Get(0),
2768 staDevice.Get(0)->GetAddress());
2771 this,
2772 useAmpdu ? 2 : 1,
2773 apDevice.Get(0),
2774 staDevice.Get(0)->GetAddress());
2777 this,
2778 useAmpdu ? 2 : 1,
2779 apDevice.Get(0),
2780 staDevice.Get(0)->GetAddress());
2781
2784
2786 (useAmpdu ? 14 : 7),
2787 "Incorrect number of transmitted packets");
2789 (useAmpdu ? 12 : 6),
2790 "Incorrect number of successfully received packets");
2792 (useAmpdu ? 2 : 1),
2793 "Incorrect number of dropped TX packets");
2794
2796}
2797
2798void
2800{
2801 // Test without A-MPDU
2802 RunOne(false);
2803
2804 // Test with A-MPDU
2805 RunOne(true);
2806}
2807
2808//-----------------------------------------------------------------------------
2809/**
2810 * Make sure that Ideal rate manager is able to handle non best-effort traffic.
2811 *
2812 * The scenario considers an access point and a fixed station.
2813 * The station first sends a best-effort packet to the access point,
2814 * for which Ideal rate manager should select a VHT rate. Then,
2815 * the station sends a non best-effort (voice) packet to the access point,
2816 * and since SNR is unchanged, the same VHT rate should be used.
2817 *
2818 * See \issueid{169}
2819 */
2820
2822{
2823 public:
2825 ~Issue169TestCase() override;
2826 void DoRun() override;
2827
2828 private:
2829 /**
2830 * Triggers the transmission of a 1000 Byte-long data packet from the source device
2831 * @param numPackets number of packets in burst
2832 * @param sourceDevice pointer to the source NetDevice
2833 * @param destination address of the destination device
2834 * @param priority the priority of the packets to send
2835 */
2836 void SendPackets(uint8_t numPackets,
2837 Ptr<NetDevice> sourceDevice,
2838 Address& destination,
2839 uint8_t priority);
2840
2841 /**
2842 * Callback that indicates a PSDU is being transmitted
2843 * @param context the context
2844 * @param psdus the PSDU map to transmit
2845 * @param txVector the TX vector
2846 * @param txPowerW the TX power (W)
2847 */
2848 void TxCallback(std::string context,
2849 WifiConstPsduMap psdus,
2850 WifiTxVector txVector,
2851 double txPowerW);
2852};
2853
2855 : TestCase("Test case for issue #169")
2856{
2857}
2858
2862
2863void
2865 Ptr<NetDevice> sourceDevice,
2866 Address& destination,
2867 uint8_t priority)
2868{
2869 SocketPriorityTag priorityTag;
2870 priorityTag.SetPriority(priority);
2871 for (uint8_t i = 0; i < numPackets; i++)
2872 {
2873 Ptr<Packet> packet = Create<Packet>(1000); // 1000 dummy bytes of data
2874 packet->AddPacketTag(priorityTag);
2875 sourceDevice->Send(packet, destination, 0);
2876 }
2877}
2878
2879void
2881 WifiConstPsduMap psdus,
2882 WifiTxVector txVector,
2883 double txPowerW)
2884{
2885 if (psdus.begin()->second->GetSize() >= 1000)
2886 {
2889 "Ideal rate manager selected incorrect modulation class");
2890 }
2891}
2892
2893void
2895{
2898 int64_t streamNumber = 100;
2899
2900 NodeContainer wifiApNode;
2901 NodeContainer wifiStaNode;
2902 wifiApNode.Create(1);
2903 wifiStaNode.Create(1);
2904
2907 phy.SetChannel(channel.Create());
2908
2909 WifiHelper wifi;
2910 wifi.SetStandard(WIFI_STANDARD_80211ac);
2911 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
2912
2913 WifiMacHelper mac;
2914 NetDeviceContainer apDevice;
2915 mac.SetType("ns3::ApWifiMac");
2916 apDevice = wifi.Install(phy, mac, wifiApNode);
2917
2918 NetDeviceContainer staDevice;
2919 mac.SetType("ns3::StaWifiMac");
2920 staDevice = wifi.Install(phy, mac, wifiStaNode);
2921
2922 // Assign fixed streams to random variables in use
2923 WifiHelper::AssignStreams(apDevice, streamNumber);
2924 WifiHelper::AssignStreams(staDevice, streamNumber);
2925
2926 MobilityHelper mobility;
2928 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2929 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
2930 mobility.SetPositionAllocator(positionAlloc);
2931
2932 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2933 mobility.Install(wifiApNode);
2934 mobility.Install(wifiStaNode);
2935
2936 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
2938
2939 // Send best-effort packet (i.e. priority 0)
2942 this,
2943 1,
2944 apDevice.Get(0),
2945 staDevice.Get(0)->GetAddress(),
2946 0);
2947
2948 // Send non best-effort (voice) packet (i.e. priority 6)
2951 this,
2952 1,
2953 apDevice.Get(0),
2954 staDevice.Get(0)->GetAddress(),
2955 6);
2956
2959
2961}
2962
2963//-----------------------------------------------------------------------------
2964/**
2965 * Make sure that Ideal rate manager properly selects MCS based on the configured channel width.
2966 *
2967 * The scenario considers an access point and a fixed station.
2968 * The access point first sends a 80 MHz PPDU to the station,
2969 * for which Ideal rate manager should select VH-MCS 0 based
2970 * on the distance (no interference generated in this test). Then,
2971 * the access point sends a 20 MHz PPDU to the station,
2972 * which corresponds to a SNR 6 dB higher than previously, hence
2973 * VHT-MCS 2 should be selected. Finally, the access point sends a
2974 * 40 MHz PPDU to the station, which means corresponds to a SNR 3 dB
2975 * lower than previously, hence VHT-MCS 1 should be selected.
2976 */
2977
2979{
2980 public:
2983 void DoRun() override;
2984
2985 private:
2986 /**
2987 * Change the configured channel width for all nodes
2988 * @param channelWidth the channel width
2989 */
2990 void ChangeChannelWidth(MHz_u channelWidth);
2991
2992 /**
2993 * Triggers the transmission of a 1000 Byte-long data packet from the source device
2994 * @param sourceDevice pointer to the source NetDevice
2995 * @param destination address of the destination device
2996 */
2997 void SendPacket(Ptr<NetDevice> sourceDevice, Address& destination);
2998
2999 /**
3000 * Callback that indicates a PSDU is being transmitted
3001 * @param context the context
3002 * @param psduMap the PSDU map to transmit
3003 * @param txVector the TX vector
3004 * @param txPowerW the TX power (W)
3005 */
3006 void TxCallback(std::string context,
3007 WifiConstPsduMap psduMap,
3008 WifiTxVector txVector,
3009 double txPowerW);
3010
3011 /**
3012 * Check if the selected WifiMode is correct
3013 * @param expectedMode the expected WifiMode
3014 */
3015 void CheckLastSelectedMode(WifiMode expectedMode);
3016
3017 WifiMode m_txMode; ///< Store the last selected mode to send data packet
3018};
3019
3021 : TestCase("Test case for use of channel bonding with Ideal rate manager")
3022{
3023}
3024
3028
3029void
3031{
3032 Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelSettings",
3033 StringValue("{0, " + std::to_string(static_cast<uint16_t>(channelWidth)) +
3034 ", BAND_5GHZ, 0}"));
3035}
3036
3037void
3039{
3040 Ptr<Packet> packet = Create<Packet>(1000);
3041 sourceDevice->Send(packet, destination, 0);
3042}
3043
3044void
3046 WifiConstPsduMap psduMap,
3047 WifiTxVector txVector,
3048 double txPowerW)
3049{
3050 if (psduMap.begin()->second->GetSize() >= 1000)
3051 {
3052 m_txMode = txVector.GetMode();
3053 }
3054}
3055
3056void
3058{
3060 expectedMode,
3061 "Last selected WifiMode "
3062 << m_txMode << " does not match expected WifiMode " << expectedMode);
3063}
3064
3065void
3067{
3070 int64_t streamNumber = 100;
3071
3072 NodeContainer wifiApNode;
3073 NodeContainer wifiStaNode;
3074 wifiApNode.Create(1);
3075 wifiStaNode.Create(1);
3076
3079 phy.SetChannel(channel.Create());
3080
3081 WifiHelper wifi;
3082 wifi.SetStandard(WIFI_STANDARD_80211ac);
3083 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
3084
3085 WifiMacHelper mac;
3086 NetDeviceContainer apDevice;
3087 mac.SetType("ns3::ApWifiMac");
3088 apDevice = wifi.Install(phy, mac, wifiApNode);
3089
3090 NetDeviceContainer staDevice;
3091 mac.SetType("ns3::StaWifiMac");
3092 staDevice = wifi.Install(phy, mac, wifiStaNode);
3093
3094 // Assign fixed streams to random variables in use
3095 WifiHelper::AssignStreams(apDevice, streamNumber);
3096 WifiHelper::AssignStreams(staDevice, streamNumber);
3097
3098 MobilityHelper mobility;
3100 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
3101 positionAlloc->Add(Vector(50.0, 0.0, 0.0));
3102 mobility.SetPositionAllocator(positionAlloc);
3103
3104 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
3105 mobility.Install(wifiApNode);
3106 mobility.Install(wifiStaNode);
3107
3108 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
3110
3111 // Set channel width to 80 MHz & send packet
3114 this,
3115 MHz_u{80});
3118 this,
3119 apDevice.Get(0),
3120 staDevice.Get(0)->GetAddress());
3121 // Selected rate should be VHT-MCS 1
3124 this,
3126
3127 // Set channel width to 20 MHz & send packet
3130 this,
3131 MHz_u{20});
3134 this,
3135 apDevice.Get(0),
3136 staDevice.Get(0)->GetAddress());
3137 // Selected rate should be VHT-MCS 3 since SNR should be 6 dB higher than previously
3140 this,
3142
3143 // Set channel width to 40 MHz & send packet
3146 this,
3147 MHz_u{40});
3150 this,
3151 apDevice.Get(0),
3152 staDevice.Get(0)->GetAddress());
3153 // Selected rate should be VHT-MCS 2 since SNR should be 3 dB lower than previously
3156 this,
3158
3161
3163}
3164
3165//-----------------------------------------------------------------------------
3166/**
3167 * Test to validate that Ideal rate manager properly selects TXVECTOR in scenarios where MIMO is
3168 * used. The test consider both balanced and unbalanced MIMO settings, and verify ideal picks the
3169 * correct number of spatial streams and the correct MCS, taking into account potential diversity in
3170 * AWGN channels when the number of antenna at the receiver is higher than the number of spatial
3171 * streams used for the transmission.
3172 */
3173
3175{
3176 public:
3178 ~IdealRateManagerMimoTest() override;
3179 void DoRun() override;
3180
3181 private:
3182 /**
3183 * Change the configured MIMO settings for AP node
3184 * @param antennas the number of active antennas
3185 * @param maxStreams the maximum number of allowed spatial streams
3186 */
3187 void SetApMimoSettings(uint8_t antennas, uint8_t maxStreams);
3188 /**
3189 * Change the configured MIMO settings for STA node
3190 * @param antennas the number of active antennas
3191 * @param maxStreams the maximum number of allowed spatial streams
3192 */
3193 void SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams);
3194 /**
3195 * Triggers the transmission of a 1000 Byte-long data packet from the source device
3196 * @param sourceDevice pointer to the source NetDevice
3197 * @param destination address of the destination device
3198 */
3199 void SendPacket(Ptr<NetDevice> sourceDevice, Address& destination);
3200
3201 /**
3202 * Callback that indicates a PSDU is being transmitted
3203 * @param context the context
3204 * @param psdus the PSDU map to transmit
3205 * @param txVector the TX vector
3206 * @param txPowerW the TX power (W)
3207 */
3208 void TxCallback(std::string context,
3209 WifiConstPsduMap psdus,
3210 WifiTxVector txVector,
3211 double txPowerW);
3212
3213 /**
3214 * Check if the selected WifiMode is correct
3215 * @param expectedMode the expected WifiMode
3216 */
3217 void CheckLastSelectedMode(WifiMode expectedMode);
3218 /**
3219 * Check if the selected Nss is correct
3220 * @param expectedNss the expected Nss
3221 */
3222 void CheckLastSelectedNss(uint8_t expectedNss);
3223
3224 WifiTxVector m_txVector; ///< Store the last TXVECTOR used to transmit Data
3225};
3226
3228 : TestCase("Test case for use of imbalanced MIMO settings with Ideal rate manager")
3229{
3230}
3231
3235
3236void
3237IdealRateManagerMimoTest::SetApMimoSettings(uint8_t antennas, uint8_t maxStreams)
3238{
3239 Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/Antennas",
3240 UintegerValue(antennas));
3241 Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedTxSpatialStreams",
3242 UintegerValue(maxStreams));
3243 Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedRxSpatialStreams",
3244 UintegerValue(maxStreams));
3245}
3246
3247void
3248IdealRateManagerMimoTest::SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams)
3249{
3250 Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/Antennas",
3251 UintegerValue(antennas));
3252 Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedTxSpatialStreams",
3253 UintegerValue(maxStreams));
3254 Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedRxSpatialStreams",
3255 UintegerValue(maxStreams));
3256}
3257
3258void
3260{
3261 Ptr<Packet> packet = Create<Packet>(1000);
3262 sourceDevice->Send(packet, destination, 0);
3263}
3264
3265void
3267 WifiConstPsduMap psdus,
3268 WifiTxVector txVector,
3269 double txPowerW)
3270{
3271 if (psdus.begin()->second->GetSize() >= 1000)
3272 {
3273 m_txVector = txVector;
3274 }
3275}
3276
3277void
3279{
3281 expectedNss,
3282 "Last selected Nss " << m_txVector.GetNss()
3283 << " does not match expected Nss " << expectedNss);
3284}
3285
3286void
3288{
3290 expectedMode,
3291 "Last selected WifiMode " << m_txVector.GetMode()
3292 << " does not match expected WifiMode "
3293 << expectedMode);
3294}
3295
3296void
3298{
3301 int64_t streamNumber = 100;
3302
3303 NodeContainer wifiApNode;
3304 NodeContainer wifiStaNode;
3305 wifiApNode.Create(1);
3306 wifiStaNode.Create(1);
3307
3310 phy.SetChannel(channel.Create());
3311
3312 WifiHelper wifi;
3313 wifi.SetStandard(WIFI_STANDARD_80211ac);
3314 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
3315
3316 WifiMacHelper mac;
3317 NetDeviceContainer apDevice;
3318 mac.SetType("ns3::ApWifiMac");
3319 apDevice = wifi.Install(phy, mac, wifiApNode);
3320
3321 NetDeviceContainer staDevice;
3322 mac.SetType("ns3::StaWifiMac");
3323 staDevice = wifi.Install(phy, mac, wifiStaNode);
3324
3325 // Assign fixed streams to random variables in use
3326 WifiHelper::AssignStreams(apDevice, streamNumber);
3327 WifiHelper::AssignStreams(staDevice, streamNumber);
3328
3329 MobilityHelper mobility;
3331 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
3332 positionAlloc->Add(Vector(40.0, 0.0, 0.0));
3333 mobility.SetPositionAllocator(positionAlloc);
3334
3335 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
3336 mobility.Install(wifiApNode);
3337 mobility.Install(wifiStaNode);
3338
3339 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
3341
3342 // TX: 1 antenna
3344 // RX: 1 antenna
3346 // Send packets (2 times to get one feedback)
3349 this,
3350 apDevice.Get(0),
3351 staDevice.Get(0)->GetAddress());
3354 this,
3355 apDevice.Get(0),
3356 staDevice.Get(0)->GetAddress());
3357 // Selected NSS should be 1 since both TX and RX support a single antenna
3359 // Selected rate should be VHT-MCS 2 because of settings and distance between TX and RX
3362 this,
3364
3365 // TX: 1 antenna
3367 // RX: 2 antennas, but only supports 1 spatial stream
3369 // Send packets (2 times to get one feedback)
3372 this,
3373 apDevice.Get(0),
3374 staDevice.Get(0)->GetAddress());
3377 this,
3378 apDevice.Get(0),
3379 staDevice.Get(0)->GetAddress());
3380 // Selected NSS should be 1 since both TX and RX support a single antenna
3382 // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3383 // improvement of about 3dB
3386 this,
3388
3389 // TX: 1 antenna
3391 // RX: 2 antennas, and supports 2 spatial streams
3393 // Send packets (2 times to get one feedback)
3396 this,
3397 apDevice.Get(0),
3398 staDevice.Get(0)->GetAddress());
3401 this,
3402 apDevice.Get(0),
3403 staDevice.Get(0)->GetAddress());
3404 // Selected NSS should be 1 since TX supports a single antenna
3406 // Selected rate should be as previously
3409 this,
3411
3412 // TX: 2 antennas, but only supports 1 spatial stream
3414 // RX: 1 antenna
3416 // Send packets (2 times to get one feedback)
3419 this,
3420 apDevice.Get(0),
3421 staDevice.Get(0)->GetAddress());
3424 this,
3425 apDevice.Get(0),
3426 staDevice.Get(0)->GetAddress());
3427 // Selected NSS should be 1 since both TX and RX support a single antenna
3429 // Selected rate should be VHT-MCS 2 because we do no longer have diversity in this scenario
3430 // (more antennas at TX does not result in SNR improvement in AWGN channel)
3433 this,
3435
3436 // TX: 2 antennas, but only supports 1 spatial stream
3438 // RX: 2 antennas, but only supports 1 spatial stream
3440 // Send packets (2 times to get one feedback)
3443 this,
3444 apDevice.Get(0),
3445 staDevice.Get(0)->GetAddress());
3448 this,
3449 apDevice.Get(0),
3450 staDevice.Get(0)->GetAddress());
3451 // Selected NSS should be 1 since both TX and RX support a single antenna
3453 // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3454 // improvement of about 3dB (more antennas at TX does not result in SNR improvement in AWGN
3455 // channel)
3458 this,
3460
3461 // TX: 2 antennas, but only supports 1 spatial stream
3463 // RX: 2 antennas, and supports 2 spatial streams
3465 // Send packets (2 times to get one feedback)
3468 this,
3469 apDevice.Get(0),
3470 staDevice.Get(0)->GetAddress());
3473 this,
3474 apDevice.Get(0),
3475 staDevice.Get(0)->GetAddress());
3476 // Selected NSS should be 1 since TX supports a single antenna
3478 // Selected rate should be as previously
3481 this,
3483
3484 // TX: 2 antennas, and supports 2 spatial streams
3486 // RX: 1 antenna
3488 // Send packets (2 times to get one feedback)
3491 this,
3492 apDevice.Get(0),
3493 staDevice.Get(0)->GetAddress());
3496 this,
3497 apDevice.Get(0),
3498 staDevice.Get(0)->GetAddress());
3499 // Selected NSS should be 1 since RX supports a single antenna
3501 // Selected rate should be VHT-MCS 2 because we do no longer have diversity in this scenario
3502 // (more antennas at TX does not result in SNR improvement in AWGN channel)
3505 this,
3507
3508 // TX: 2 antennas, and supports 2 spatial streams
3510 // RX: 2 antennas, but only supports 1 spatial stream
3512 // Send packets (2 times to get one feedback)
3515 this,
3516 apDevice.Get(0),
3517 staDevice.Get(0)->GetAddress());
3520 this,
3521 apDevice.Get(0),
3522 staDevice.Get(0)->GetAddress());
3523 // Selected NSS should be 1 since RX supports a single antenna
3525 // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3526 // improvement of about 3dB (more antennas at TX does not result in SNR improvement in AWGN
3527 // channel)
3530 this,
3532
3533 // TX: 2 antennas, and supports 2 spatial streams
3535 // RX: 2 antennas, and supports 2 spatial streams
3537 // Send packets (2 times to get one feedback)
3540 this,
3541 apDevice.Get(0),
3542 staDevice.Get(0)->GetAddress());
3545 this,
3546 apDevice.Get(0),
3547 staDevice.Get(0)->GetAddress());
3548 // Selected NSS should be 2 since both TX and RX support 2 antennas
3550 // Selected rate should be the same as without diversity, as it uses 2 spatial streams so there
3551 // is no more benefits from diversity in AWGN channels
3554 this,
3556
3557 // Verify we can go back to initial situation
3562 this,
3563 apDevice.Get(0),
3564 staDevice.Get(0)->GetAddress());
3568 this,
3570
3571 Simulator::Stop(Seconds(10.2));
3574}
3575
3576//-----------------------------------------------------------------------------
3577/**
3578 * @ingroup wifi-test
3579 * @ingroup tests
3580 *
3581 * @brief Data rate verification test for MCSs of different RU sizes
3582 */
3584{
3585 public:
3587
3588 private:
3589 /**
3590 * Compare the data rate computed for the provided combination with standard defined one.
3591 * @param ruType the RU type
3592 * @param mcs the modulation and coding scheme (as a string, e.g. HeMcs0)
3593 * @param nss the number of spatial streams
3594 * @param guardInterval the guard interval to use
3595 * @param expectedDataRate the expected data rate in 100 kbps units (minimum granularity in
3596 * standard tables)
3597 * @returns true if data rates are the same, false otherwise
3598 */
3599 bool CheckDataRate(RuType ruType,
3600 std::string mcs,
3601 uint8_t nss,
3602 Time guardInterval,
3603 uint16_t expectedDataRate);
3604 void DoRun() override;
3605};
3606
3608 : TestCase("Check data rates for different RU types.")
3609{
3610}
3611
3612bool
3614 std::string mcs,
3615 uint8_t nss,
3616 Time guardInterval,
3617 uint16_t expectedDataRate)
3618{
3619 uint8_t staId = 1;
3620 auto txVector = WifiTxVector(HePhy::GetHeMcs(0),
3623 guardInterval,
3624 1,
3625 1,
3626 0,
3627 MHz_u{160},
3628 false,
3629 false);
3630 WifiMode mode(mcs);
3631 txVector.SetMode(mode, staId);
3632 txVector.SetNss(nss, staId);
3633 HeRu::RuSpec ru(ruType, 1, true);
3634 txVector.SetRu(ru, staId);
3635 uint64_t dataRate = round(mode.GetDataRate(txVector, staId) / 100000.0);
3636 NS_ABORT_MSG_IF(dataRate > 65535, "Rate is way too high");
3637 if (static_cast<uint16_t>(dataRate) != expectedDataRate)
3638 {
3639 std::cerr << "RU=" << ruType << " mode=" << mode << " Nss=" << +nss
3640 << " guardInterval=" << guardInterval << " expected=" << expectedDataRate
3641 << " x100kbps"
3642 << " computed=" << static_cast<uint16_t>(dataRate) << " x100kbps" << std::endl;
3643 return false;
3644 }
3645 return true;
3646}
3647
3648void
3650{
3651 bool retval = true;
3652
3653 // 26-tone RU, browse over all MCSs, GIs and Nss's (up to 4, current max)
3654 retval = retval && CheckDataRate(RuType::RU_26_TONE, "HeMcs0", 1, NanoSeconds(800), 9) &&
3655 CheckDataRate(RuType::RU_26_TONE, "HeMcs1", 1, NanoSeconds(1600), 17) &&
3656 CheckDataRate(RuType::RU_26_TONE, "HeMcs2", 1, NanoSeconds(3200), 23) &&
3657 CheckDataRate(RuType::RU_26_TONE, "HeMcs3", 1, NanoSeconds(3200), 30) &&
3658 CheckDataRate(RuType::RU_26_TONE, "HeMcs4", 2, NanoSeconds(1600), 100) &&
3659 CheckDataRate(RuType::RU_26_TONE, "HeMcs5", 3, NanoSeconds(1600), 200) &&
3660 CheckDataRate(RuType::RU_26_TONE, "HeMcs6", 4, NanoSeconds(1600), 300) &&
3661 CheckDataRate(RuType::RU_26_TONE, "HeMcs7", 4, NanoSeconds(3200), 300) &&
3662 CheckDataRate(RuType::RU_26_TONE, "HeMcs8", 4, NanoSeconds(1600), 400) &&
3663 CheckDataRate(RuType::RU_26_TONE, "HeMcs9", 4, NanoSeconds(3200), 400) &&
3664 CheckDataRate(RuType::RU_26_TONE, "HeMcs10", 4, NanoSeconds(1600), 500) &&
3665 CheckDataRate(RuType::RU_26_TONE, "HeMcs11", 4, NanoSeconds(3200), 500);
3666
3668 retval,
3669 true,
3670 "26-tone RU data rate verification for different MCSs, GIs, and Nss's failed");
3671
3672 // Check other RU sizes
3673 retval = retval && CheckDataRate(RuType::RU_52_TONE, "HeMcs2", 1, NanoSeconds(1600), 50) &&
3674 CheckDataRate(RuType::RU_106_TONE, "HeMcs9", 1, NanoSeconds(800), 500) &&
3675 CheckDataRate(RuType::RU_242_TONE, "HeMcs5", 1, NanoSeconds(1600), 650) &&
3676 CheckDataRate(RuType::RU_484_TONE, "HeMcs3", 1, NanoSeconds(1600), 650) &&
3677 CheckDataRate(RuType::RU_996_TONE, "HeMcs5", 1, NanoSeconds(3200), 2450) &&
3678 CheckDataRate(RuType::RU_2x996_TONE, "HeMcs3", 1, NanoSeconds(3200), 2450);
3679
3680 NS_TEST_EXPECT_MSG_EQ(retval,
3681 true,
3682 "Data rate verification for RUs above 52-tone RU (included) failed");
3683}
3684
3685/// List of Information Elements included in the test management frame
3687 std::tuple<SupportedRates, std::optional<ExtendedSupportedRatesIE>, std::vector<Ssid>>;
3688
3689/**
3690 * @ingroup wifi-test
3691 * @ingroup tests
3692 *
3693 * @brief Test management header
3694 */
3695class MgtTestHeader : public WifiMgtHeader<MgtTestHeader, MgtTestElems>
3696{
3697 public:
3698 ~MgtTestHeader() override = default;
3699
3700 /**
3701 * Register this type.
3702 * @return The TypeId.
3703 */
3704 static TypeId GetTypeId();
3705
3706 /**
3707 * @return the TypeId for this object.
3708 */
3709 TypeId GetInstanceTypeId() const override;
3710
3711 using WifiMgtHeader<MgtTestHeader, MgtTestElems>::GetSerializedSize;
3712 using WifiMgtHeader<MgtTestHeader, MgtTestElems>::Serialize;
3713 using WifiMgtHeader<MgtTestHeader, MgtTestElems>::Deserialize;
3714};
3715
3716TypeId
3718{
3719 static TypeId tid = TypeId("ns3::MgtTestHeader")
3720 .SetParent<Header>()
3721 .SetGroupName("Wifi")
3722 .AddConstructor<MgtTestHeader>();
3723 return tid;
3724}
3725
3726TypeId
3728{
3729 return GetTypeId();
3730}
3731
3732/**
3733 * @ingroup wifi-test
3734 * @ingroup tests
3735 *
3736 * @brief Mgt header (de)serialization Test Suite
3737 */
3739{
3740 public:
3742 ~WifiMgtHeaderTest() override = default;
3743
3744 private:
3745 void DoRun() override;
3746};
3747
3749 : HeaderSerializationTestCase("Check (de)serialization of a test management header")
3750{
3751}
3752
3753void
3755{
3756 MgtTestHeader frame;
3757
3758 // Add the mandatory Information Element (SupportedRates)
3759 AllSupportedRates allRates;
3760 allRates.AddSupportedRate(1000000);
3761 allRates.AddSupportedRate(2000000);
3762 allRates.AddSupportedRate(3000000);
3763 allRates.AddSupportedRate(4000000);
3764 allRates.AddSupportedRate(5000000);
3765
3766 frame.Get<SupportedRates>() = allRates.rates;
3767 frame.Get<ExtendedSupportedRatesIE>() = allRates.extendedRates;
3768
3769 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3770 true,
3771 "Expected a SupportedRates IE to be included");
3772 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3773 false,
3774 "Expected no ExtendedSupportedRatesIE to be included");
3775 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 0, "Expected no Ssid IE to be included");
3776
3778
3779 // Add more rates, so that the optional Information Element (ExtendedSupportedRatesIE) is added
3780 allRates.AddSupportedRate(6000000);
3781 allRates.AddSupportedRate(7000000);
3782 allRates.AddSupportedRate(8000000);
3783 allRates.AddSupportedRate(9000000);
3784 allRates.AddSupportedRate(10000000);
3785
3786 frame.Get<SupportedRates>() = allRates.rates;
3787 frame.Get<ExtendedSupportedRatesIE>() = allRates.extendedRates;
3788
3789 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3790 true,
3791 "Expected a SupportedRates IE to be included");
3792 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3793 true,
3794 "Expected an ExtendedSupportedRatesIE to be included");
3795 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 0, "Expected no Ssid IE to be included");
3796
3798
3799 // Add a first Ssid IE
3800 Ssid one("Ssid One");
3801 frame.Get<Ssid>().push_back(one);
3802
3803 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3804 true,
3805 "Expected a SupportedRates IE to be included");
3806 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3807 true,
3808 "Expected an ExtendedSupportedRatesIE to be included");
3809 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 1, "Expected one Ssid IE to be included");
3810 NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().front().PeekString()),
3811 "Ssid One",
3812 "Incorrect SSID");
3813
3815
3816 // Add a second Ssid IE
3817 frame.Get<Ssid>().emplace_back("Ssid Two");
3818
3819 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3820 true,
3821 "Expected a SupportedRates IE to be included");
3822 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3823 true,
3824 "Expected an ExtendedSupportedRatesIE to be included");
3825 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 2, "Expected two Ssid IEs to be included");
3826 NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().front().PeekString()),
3827 "Ssid One",
3828 "Incorrect first SSID");
3829 NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().back().PeekString()),
3830 "Ssid Two",
3831 "Incorrect second SSID");
3832
3834}
3835
3836//-----------------------------------------------------------------------------
3837
3838/**
3839 * Make sure that all DSSS modulation types work (see issue #1095).
3840 *
3841 * This test sends four packets from a STA to an AP, each with a different
3842 * DSSS rate (1, 2, 5.5, and 11Mbps), and checks that all four are received.
3843 */
3845{
3846 public:
3848
3849 void DoRun() override;
3850
3851 private:
3852 uint32_t m_received; ///< number of received packets
3853
3854 /**
3855 * Trace sink to receive from the PacketSocket; the address parameter is unused
3856 * @param context the context
3857 * @param p the received packet
3858 */
3859 void Receive(std::string context, Ptr<const Packet> p, const Address&);
3860};
3861
3863 : TestCase("Test case for Bug 730"),
3864 m_received(0)
3865{
3866}
3867
3868void
3870{
3871 m_received++;
3872}
3873
3874void
3876{
3877 m_received = 0;
3878
3879 NodeContainer wifiStaNode;
3880 wifiStaNode.Create(1);
3881
3882 NodeContainer wifiApNode;
3883 wifiApNode.Create(1);
3884
3885 auto channel = YansWifiChannelHelper::Default();
3887 phy.SetChannel(channel.Create());
3888
3889 WifiHelper wifi;
3890 wifi.SetStandard(WIFI_STANDARD_80211b);
3891 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
3892 "DataMode",
3893 StringValue("DsssRate1Mbps"),
3894 "ControlMode",
3895 StringValue("DsssRate1Mbps"));
3896
3897 WifiMacHelper mac;
3898 auto ssid = Ssid("ns-3-ssid");
3899 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid), "ActiveProbing", BooleanValue(false));
3900
3901 NetDeviceContainer staDevices;
3902 staDevices = wifi.Install(phy, mac, wifiStaNode);
3903
3904 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid), "BeaconGeneration", BooleanValue(true));
3905
3906 NetDeviceContainer apDevices;
3907 apDevices = wifi.Install(phy, mac, wifiApNode);
3908 auto apRemoteStationManager = apDevices.Get(0)
3909 ->GetObject<WifiNetDevice>()
3910 ->GetRemoteStationManager()
3912 apRemoteStationManager->SetAttribute("DataMode", StringValue("DsssRate1Mbps"));
3913
3914 MobilityHelper mobility;
3915 auto positionAlloc = CreateObject<ListPositionAllocator>();
3916
3917 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
3918 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
3919 mobility.SetPositionAllocator(positionAlloc);
3920
3921 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
3922 mobility.Install(wifiApNode);
3923 mobility.Install(wifiStaNode);
3924
3925 auto apDevice = DynamicCast<WifiNetDevice>(apDevices.Get(0));
3926 auto staDevice = DynamicCast<WifiNetDevice>(staDevices.Get(0));
3927
3928 PacketSocketAddress socket;
3929 socket.SetSingleDevice(staDevice->GetIfIndex());
3930 socket.SetPhysicalAddress(apDevice->GetAddress());
3931 socket.SetProtocol(1);
3932
3933 // give packet socket powers to nodes.
3934 PacketSocketHelper packetSocket;
3935 packetSocket.Install(wifiStaNode);
3936 packetSocket.Install(wifiApNode);
3937
3938 auto client = CreateObject<PacketSocketClient>();
3939 client->SetAttribute("PacketSize", UintegerValue(1460));
3940 client->SetAttribute("MaxPackets", UintegerValue(4));
3941 client->SetRemote(socket);
3942 wifiStaNode.Get(0)->AddApplication(client);
3943 client->SetStartTime(Seconds(1));
3944 client->SetStopTime(Seconds(4.5));
3945
3946 auto server = CreateObject<PacketSocketServer>();
3947 server->SetLocal(socket);
3948 wifiApNode.Get(0)->AddApplication(server);
3949 server->SetStartTime(Seconds(0));
3950 server->SetStopTime(Seconds(4.5));
3951
3952 Config::Connect("/NodeList/1/ApplicationList/0/$ns3::PacketSocketServer/Rx",
3954
3955 // The PacketSocketClient starts at time 1s, and packets are sent at times 1s, 2s, 3s, 4s.
3956 // Change the MCS in between these send times (e.g., at 1.5s, 2.5s, 3.5s)
3958 Seconds(1.5),
3960 "/NodeList/0/DeviceList/0/RemoteStationManager/$ns3::ConstantRateWifiManager/DataMode",
3961 StringValue("DsssRate2Mbps"));
3963 Seconds(2.5),
3965 "/NodeList/0/DeviceList/0/RemoteStationManager/$ns3::ConstantRateWifiManager/DataMode",
3966 StringValue("DsssRate5_5Mbps"));
3968 Seconds(3.5),
3970 "/NodeList/0/DeviceList/0/RemoteStationManager/$ns3::ConstantRateWifiManager/DataMode",
3971 StringValue("DsssRate11Mbps"));
3972
3975
3977
3978 NS_TEST_ASSERT_MSG_EQ(m_received, 4, "Did not receive four DSSS packets");
3979}
3980
3981/**
3982 * @ingroup wifi-test
3983 * @ingroup tests
3984 *
3985 * @brief Wifi Test Suite
3986 */
3988{
3989 public:
3990 WifiTestSuite();
3991};
3992
3994 : TestSuite("wifi-devices", Type::UNIT)
3995{
4015}
4016
4017static WifiTestSuite g_wifiTestSuite; ///< the test suite
return result
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.
Time m_2ndPktSetStart
time the second set of packets is generated
uint16_t m_addbaRejectedCount
Count number of times ADDBA state machine is in rejected state.
void AddbaStateChangedCallback(std::string context, Time t, Mac48Address recipient, uint8_t tid, OriginatorBlockAckAgreement::State state)
Callback when ADDBA state changed.
uint16_t m_failedActionCount
Count failed ADDBA request/response.
void TxCallback(Ptr< ListErrorModel > rxErrorModel, std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback when a frame is transmitted.
uint16_t m_addbaEstablishedCount
Count number of times ADDBA state machine is in established state.
void RxCallback(std::string context, Ptr< const Packet > p, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise, uint16_t staId)
Callback when packet is received.
~Bug2470TestCase() override
uint16_t m_receivedNormalMpduCount
Count received normal MPDU packets on STA.
uint16_t m_addbaNoReplyCount
Count number of times ADDBA state machine is in no_reply state.
uint16_t m_addbaPendingCount
Count number of times ADDBA state machine is in pending state.
void SendPacketBurst(uint32_t numPackets, Ptr< NetDevice > sourceDevice, Address &destination) const
Triggers the arrival of a burst of 1000 Byte-long packets in the source device.
uint16_t m_receivedAmpduCount
Count received A-MPDU packets on STA.
Make sure that the channel width and the channel number can be changed at runtime.
uint16_t m_countOperationalChannelWidth20
count number of beacon frames announcing a 20 MHz operating channel width
void ChangeSupportedChannelWidth()
Function called to change the supported channel width at runtime.
uint16_t m_countOperationalChannelWidth40
count number of beacon frames announcing a 40 MHz operating channel width
void RxCallback(std::string context, Ptr< const Packet > p, RxPowerWattPerChannelBand rxPowersW)
Callback triggered when a packet is received by the PHYs.
uint16_t m_assocReqCount
count number of association requests
Ptr< YansWifiPhy > m_apPhy
AP PHY.
void DoRun() override
Implementation to actually run this TestCase.
Ptr< YansWifiPhy > m_staPhy
STA PHY.
uint16_t m_assocRespCount
count number of association responses
~Bug2831TestCase() override
Make sure that the correct channel width and center frequency have been set for OFDM basic rate trans...
void SendPacketBurst(uint8_t numPackets, Ptr< NetDevice > sourceDevice, Address &destination) const
Triggers the arrival of a burst of 1000 Byte-long packets in the source device.
void StoreDistinctTuple(std::string context, Ptr< SpectrumSignalParameters > txParams)
Stores the distinct {starting frequency, channelWidth, Number of subbands in SpectrumModel,...
std::vector< FreqWidthSubbandModulationTuple > m_distinctTuples
vector of distinct {starting frequency, channelWidth, Number of subbands in SpectrumModel,...
void DoRun() override
Implementation to actually run this TestCase.
MHz_u m_channelWidth
channel width
std::tuple< Hz_u, MHz_u, uint32_t, WifiModulationClass > FreqWidthSubbandModulationTuple
A tuple of {starting frequency, channelWidth, Number of subbands in SpectrumModel,...
~Bug2843TestCase() override
Make sure that when changing the fragmentation threshold during the simulation, the TCP transmission ...
Definition wifi-test.cc:647
~Bug730TestCase() override
Definition wifi-test.cc:672
void Receive(std::string context, Ptr< const Packet > p, const Address &adr)
Receive function.
Definition wifi-test.cc:677
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:686
uint32_t m_received
received
Definition wifi-test.cc:655
Make sure that when multiple broadcast packets are queued on the same device in a short succession,...
Definition wifi-test.cc:475
void NotifyPhyTxBegin(Ptr< const Packet > p, double txPowerW)
Notify Phy transmit begin.
Definition wifi-test.cc:510
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:531
ObjectFactory m_propDelay
propagation delay
Definition wifi-test.cc:490
unsigned int m_numSentPackets
number of sent packets
Definition wifi-test.cc:494
Time m_secondTransmissionTime
second transmission time
Definition wifi-test.cc:493
Time m_firstTransmissionTime
first transmission time
Definition wifi-test.cc:492
void SendOnePacket(Ptr< WifiNetDevice > dev)
Send one packet function.
Definition wifi-test.cc:524
Make sure that all DSSS modulation types work (see issue #1095).
void Receive(std::string context, Ptr< const Packet > p, const Address &)
Trace sink to receive from the PacketSocket; the address parameter is unused.
void DoRun() override
Implementation to actually run this TestCase.
uint32_t m_received
number of received packets
Data rate verification test for MCSs of different RU sizes.
bool CheckDataRate(RuType ruType, std::string mcs, uint8_t nss, Time guardInterval, uint16_t expectedDataRate)
Compare the data rate computed for the provided combination with standard defined one.
void DoRun() override
Implementation to actually run this TestCase.
Make sure that Ideal rate manager properly selects MCS based on the configured channel width.
WifiMode m_txMode
Store the last selected mode to send data packet.
void ChangeChannelWidth(MHz_u channelWidth)
Change the configured channel width for all nodes.
void DoRun() override
Implementation to actually run this TestCase.
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
Triggers the transmission of a 1000 Byte-long data packet from the source device.
void CheckLastSelectedMode(WifiMode expectedMode)
Check if the selected WifiMode is correct.
void TxCallback(std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback that indicates a PSDU is being transmitted.
Test to validate that Ideal rate manager properly selects TXVECTOR in scenarios where MIMO is used.
~IdealRateManagerMimoTest() override
void CheckLastSelectedNss(uint8_t expectedNss)
Check if the selected Nss is correct.
void DoRun() override
Implementation to actually run this TestCase.
void TxCallback(std::string context, WifiConstPsduMap psdus, WifiTxVector txVector, double txPowerW)
Callback that indicates a PSDU is being transmitted.
void SetApMimoSettings(uint8_t antennas, uint8_t maxStreams)
Change the configured MIMO settings for AP node.
WifiTxVector m_txVector
Store the last TXVECTOR used to transmit Data.
void SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams)
Change the configured MIMO settings for STA node.
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
Triggers the transmission of a 1000 Byte-long data packet from the source device.
void CheckLastSelectedMode(WifiMode expectedMode)
Check if the selected WifiMode is correct.
void SwitchCh(Ptr< WifiNetDevice > dev)
Switch channel function.
Definition wifi-test.cc:323
void SendOnePacket(Ptr< WifiNetDevice > dev)
Send one packet function.
Definition wifi-test.cc:316
void DoRun() override
Implementation to actually run this TestCase.
Definition wifi-test.cc:375
ObjectFactory m_manager
manager
Definition wifi-test.cc:305
ObjectFactory m_propDelay
propagation delay
Definition wifi-test.cc:307
Ptr< Node > CreateOne(Vector pos, Ptr< YansWifiChannel > channel)
Create one function.
Definition wifi-test.cc:330
Make sure that Ideal rate manager is able to handle non best-effort traffic.
void SendPackets(uint8_t numPackets, Ptr< NetDevice > sourceDevice, Address &destination, uint8_t priority)
Triggers the transmission of a 1000 Byte-long data packet from the source device.
~Issue169TestCase() override
void TxCallback(std::string context, WifiConstPsduMap psdus, WifiTxVector txVector, double txPowerW)
Callback that indicates a PSDU is being transmitted.
void DoRun() override
Implementation to actually run this TestCase.
Make sure that Ideal rate manager recovers when the station is moving away from the access point.
uint16_t m_txCount
Count number of transmitted data packets.
uint16_t m_txMacFinalDataFailedCount
Count number of unsuccessfully 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:114
AttributeValue implementation for Boolean.
Definition boolean.h:26
use constant rates for data and RTS transmissions
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
The Extended Supported Rates Information Element.
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition he-phy.cc:1573
RU Specification.
Definition he-ru.h:37
Protocol header serialization and deserialization.
Definition header.h:36
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...
HeaderSerializationTestCase(std::string name)
Constructor.
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
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 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:518
State
Represents the state for this agreement.
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
AttributeValue implementation for Pointer.
Definition pointer.h:37
Ptr< T > Get() const
Definition pointer.h:224
calculate a propagation delay.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
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:580
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:125
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:191
static void Run()
Run the simulation.
Definition simulator.cc:161
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:169
indicates whether the socket has a priority set.
Definition socket.h:1308
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.
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:296
@ QUICK
Fast test.
Definition test.h:1057
TestCase(const TestCase &)=delete
Caller graph was not generated because of its size.
Type
Type of test.
Definition test.h:1271
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:494
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
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:50
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:999
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:38
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:172
Hold together all Wifi-related objects.
void Set(std::string name, const AttributeValue &v)
void SetErrorRateModel(std::string type, Args &&... args)
Helper function used to set the error rate model.
WifiChannelConfig::SegmentWithoutUnits ChannelTuple
kept for backward compatibility, can be deprecated when using strong types
Definition wifi-phy.h:954
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.
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
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:690
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:970
void Set(std::string path, const AttributeValue &value)
Definition config.cc:872
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:627
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:454
#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:133
#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:819
#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:240
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1307
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1324
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1273
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.
@ WIFI_MOD_CLASS_OFDM
OFDM (Clause 17).
@ WIFI_MOD_CLASS_VHT
VHT (Clause 22).
@ NORMAL_MPDU
The MPDU is not part of an A-MPDU.
Definition wifi-types.h:55
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< void, Ptr< const WifiPsdu > > RxErrorCallback
Callback if PSDU unsuccessfully received.
static constexpr uint8_t WIFI_MIN_TX_PWR_LEVEL
minimum TX power level value
double Hz_u
Hz weak type.
Definition wifi-units.h:30
RuType
The different Resource Unit (RU) types.
Definition wifi-types.h:240
double MHz_u
MHz weak type.
Definition wifi-units.h:31
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:605
std::map< WifiSpectrumBandInfo, Watt_u > RxPowerWattPerChannelBand
A map of the received power for each band.
@ WIFI_MAC_MGT_ACTION
Ptr< T1 > StaticCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:612
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:77
MpduType type
type of MPDU
Definition wifi-types.h:78
SignalNoiseDbm structure.
Definition wifi-types.h:70
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.