A Discrete-Event Network Simulator
API
wifi-test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005,2006 INRIA
3  * 2010 NICTA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  * Quincy Tse <quincy.tse@nicta.com.au>
20  * Sébastien Deronne <sebastien.deronne@gmail.com>
21  */
22 
23 #include "ns3/adhoc-wifi-mac.h"
24 #include "ns3/ap-wifi-mac.h"
25 #include "ns3/config.h"
26 #include "ns3/constant-position-mobility-model.h"
27 #include "ns3/error-model.h"
28 #include "ns3/fcfs-wifi-queue-scheduler.h"
29 #include "ns3/frame-exchange-manager.h"
30 #include "ns3/header-serialization-test.h"
31 #include "ns3/ht-configuration.h"
32 #include "ns3/interference-helper.h"
33 #include "ns3/mgt-headers.h"
34 #include "ns3/mobility-helper.h"
35 #include "ns3/multi-model-spectrum-channel.h"
36 #include "ns3/packet-socket-client.h"
37 #include "ns3/packet-socket-helper.h"
38 #include "ns3/packet-socket-server.h"
39 #include "ns3/pointer.h"
40 #include "ns3/propagation-loss-model.h"
41 #include "ns3/rng-seed-manager.h"
42 #include "ns3/socket.h"
43 #include "ns3/spectrum-wifi-helper.h"
44 #include "ns3/string.h"
45 #include "ns3/test.h"
46 #include "ns3/vht-phy.h"
47 #include "ns3/waypoint-mobility-model.h"
48 #include "ns3/wifi-default-ack-manager.h"
49 #include "ns3/wifi-default-assoc-manager.h"
50 #include "ns3/wifi-default-protection-manager.h"
51 #include "ns3/wifi-mgt-header.h"
52 #include "ns3/wifi-net-device.h"
53 #include "ns3/wifi-ppdu.h"
54 #include "ns3/wifi-psdu.h"
55 #include "ns3/wifi-spectrum-signal-parameters.h"
56 #include "ns3/yans-error-rate-model.h"
57 #include "ns3/yans-wifi-helper.h"
58 #include "ns3/yans-wifi-phy.h"
59 
60 #include <optional>
61 
62 using namespace ns3;
63 
64 // Helper function to assign streams to random variables, to control
65 // randomness in the tests
66 static void
68 {
69  int64_t currentStream = stream;
70  PointerValue ptr;
71  if (!mac->GetQosSupported())
72  {
73  mac->GetAttribute("Txop", ptr);
74  Ptr<Txop> txop = ptr.Get<Txop>();
75  currentStream += txop->AssignStreams(currentStream);
76  }
77  else
78  {
79  mac->GetAttribute("VO_Txop", ptr);
80  Ptr<QosTxop> vo_txop = ptr.Get<QosTxop>();
81  currentStream += vo_txop->AssignStreams(currentStream);
82 
83  mac->GetAttribute("VI_Txop", ptr);
84  Ptr<QosTxop> vi_txop = ptr.Get<QosTxop>();
85  currentStream += vi_txop->AssignStreams(currentStream);
86 
87  mac->GetAttribute("BE_Txop", ptr);
88  Ptr<QosTxop> be_txop = ptr.Get<QosTxop>();
89  currentStream += be_txop->AssignStreams(currentStream);
90 
91  mac->GetAttribute("BK_Txop", ptr);
92  Ptr<QosTxop> bk_txop = ptr.Get<QosTxop>();
93  bk_txop->AssignStreams(currentStream);
94  }
95 }
96 
103 class WifiTest : public TestCase
104 {
105  public:
106  WifiTest();
107 
108  void DoRun() override;
109 
110  private:
112  void RunOne();
118  void CreateOne(Vector pos, Ptr<YansWifiChannel> channel);
124 
128 };
129 
131  : TestCase("Wifi")
132 {
133 }
134 
135 void
137 {
138  Ptr<Packet> p = Create<Packet>();
139  dev->Send(p, dev->GetBroadcast(), 1);
140 }
141 
142 void
144 {
145  Ptr<Node> node = CreateObject<Node>();
146  Ptr<WifiNetDevice> dev = CreateObject<WifiNetDevice>();
147  node->AddDevice(dev);
148 
149  auto mobility = CreateObject<ConstantPositionMobilityModel>();
150  auto phy = CreateObject<YansWifiPhy>();
151  Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper>();
152  phy->SetInterferenceHelper(interferenceHelper);
153  auto error = CreateObject<YansErrorRateModel>();
154  phy->SetErrorRateModel(error);
155  phy->SetChannel(channel);
156  phy->SetDevice(dev);
157  phy->ConfigureStandard(WIFI_STANDARD_80211a);
158  dev->SetPhy(phy);
159  auto manager = m_manager.Create<WifiRemoteStationManager>();
160  dev->SetRemoteStationManager(manager);
161 
163  mac->SetDevice(dev);
164  mac->SetAddress(Mac48Address::Allocate());
165  dev->SetMac(mac);
166  mac->ConfigureStandard(WIFI_STANDARD_80211a);
167  if (mac->GetTypeOfStation() == STA)
168  {
169  StaticCast<StaWifiMac>(mac)->SetAssocManager(CreateObject<WifiDefaultAssocManager>());
170  }
171  mac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
172  Ptr<FrameExchangeManager> fem = mac->GetFrameExchangeManager();
173  Ptr<WifiProtectionManager> protectionManager = CreateObject<WifiDefaultProtectionManager>();
174  protectionManager->SetWifiMac(mac);
175  fem->SetProtectionManager(protectionManager);
176  Ptr<WifiAckManager> ackManager = CreateObject<WifiDefaultAckManager>();
177  ackManager->SetWifiMac(mac);
178  fem->SetAckManager(ackManager);
179 
180  mobility->SetPosition(pos);
181  node->AggregateObject(mobility);
182 
183  Simulator::Schedule(Seconds(1.0), &WifiTest::SendOnePacket, this, dev);
184 }
185 
186 void
188 {
189  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel>();
191  Ptr<PropagationLossModel> propLoss = CreateObject<RandomPropagationLossModel>();
192  channel->SetPropagationDelayModel(propDelay);
193  channel->SetPropagationLossModel(propLoss);
194 
195  CreateOne(Vector(0.0, 0.0, 0.0), channel);
196  CreateOne(Vector(5.0, 0.0, 0.0), channel);
197  CreateOne(Vector(5.0, 0.0, 0.0), channel);
198 
199  Simulator::Stop(Seconds(10.0));
200 
201  Simulator::Run();
202  Simulator::Destroy();
203 }
204 
205 void
207 {
208  m_mac.SetTypeId("ns3::AdhocWifiMac");
209  m_propDelay.SetTypeId("ns3::ConstantSpeedPropagationDelayModel");
210 
211  m_manager.SetTypeId("ns3::ArfWifiManager");
212  RunOne();
213  m_manager.SetTypeId("ns3::AarfWifiManager");
214  RunOne();
215  m_manager.SetTypeId("ns3::ConstantRateWifiManager");
216  RunOne();
217  m_manager.SetTypeId("ns3::OnoeWifiManager");
218  RunOne();
219  m_manager.SetTypeId("ns3::AmrrWifiManager");
220  RunOne();
221  m_manager.SetTypeId("ns3::IdealWifiManager");
222  RunOne();
223 
224  m_mac.SetTypeId("ns3::AdhocWifiMac");
225  RunOne();
226  m_mac.SetTypeId("ns3::ApWifiMac");
227  RunOne();
228  m_mac.SetTypeId("ns3::StaWifiMac");
229  RunOne();
230 
231  m_propDelay.SetTypeId("ns3::RandomPropagationDelayModel");
232  m_mac.SetTypeId("ns3::AdhocWifiMac");
233  RunOne();
234 }
235 
243 {
244  public:
246  : TestCase("QosUtilsIsOldPacket")
247  {
248  }
249 
250  void DoRun() override
251  {
252  // startingSeq=0, seqNum=2047
254  false,
255  "2047 is new in comparison to 0");
256  // startingSeq=0, seqNum=2048
257  NS_TEST_EXPECT_MSG_EQ(QosUtilsIsOldPacket(0, 2048), true, "2048 is old in comparison to 0");
258  // startingSeq=2048, seqNum=0
259  NS_TEST_EXPECT_MSG_EQ(QosUtilsIsOldPacket(2048, 0), true, "0 is old in comparison to 2048");
260  // startingSeq=4095, seqNum=0
262  false,
263  "0 is new in comparison to 4095");
264  // startingSeq=0, seqNum=4095
265  NS_TEST_EXPECT_MSG_EQ(QosUtilsIsOldPacket(0, 4095), true, "4095 is old in comparison to 0");
266  // startingSeq=4095 seqNum=2047
268  true,
269  "2047 is old in comparison to 4095");
270  // startingSeq=2048 seqNum=4095
272  false,
273  "4095 is new in comparison to 2048");
274  // startingSeq=2049 seqNum=0
276  false,
277  "0 is new in comparison to 2049");
278  }
279 };
280 
285 {
286  public:
288 
289  void DoRun() override;
290 
291  private:
308  void SwitchCh(Ptr<WifiNetDevice> dev);
309 
313 };
314 
316  : TestCase("InterferenceHelperSequence")
317 {
318 }
319 
320 void
322 {
323  Ptr<Packet> p = Create<Packet>(1000);
324  dev->Send(p, dev->GetBroadcast(), 1);
325 }
326 
327 void
329 {
330  Ptr<WifiPhy> p = dev->GetPhy();
332 }
333 
334 Ptr<Node>
336 {
337  Ptr<Node> node = CreateObject<Node>();
338  Ptr<WifiNetDevice> dev = CreateObject<WifiNetDevice>();
339  node->AddDevice(dev);
340 
341  auto mobility = CreateObject<ConstantPositionMobilityModel>();
342  auto phy = CreateObject<YansWifiPhy>();
343  Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper>();
344  phy->SetInterferenceHelper(interferenceHelper);
345  auto error = CreateObject<YansErrorRateModel>();
346  phy->SetErrorRateModel(error);
347  phy->SetChannel(channel);
348  phy->SetDevice(dev);
349  phy->SetMobility(mobility);
350  phy->ConfigureStandard(WIFI_STANDARD_80211a);
351  dev->SetPhy(phy);
352  auto manager = m_manager.Create<WifiRemoteStationManager>();
353  dev->SetRemoteStationManager(manager);
354 
356  mac->SetDevice(dev);
357  mac->SetAddress(Mac48Address::Allocate());
358  dev->SetMac(mac);
359  mac->ConfigureStandard(WIFI_STANDARD_80211a);
360  mac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
361  Ptr<FrameExchangeManager> fem = mac->GetFrameExchangeManager();
362  Ptr<WifiProtectionManager> protectionManager = CreateObject<WifiDefaultProtectionManager>();
363  protectionManager->SetWifiMac(mac);
364  fem->SetProtectionManager(protectionManager);
365  Ptr<WifiAckManager> ackManager = CreateObject<WifiDefaultAckManager>();
366  ackManager->SetWifiMac(mac);
367  fem->SetAckManager(ackManager);
368 
369  mobility->SetPosition(pos);
370  node->AggregateObject(mobility);
371 
372  return node;
373 }
374 
375 void
377 {
378  m_mac.SetTypeId("ns3::AdhocWifiMac");
379  m_propDelay.SetTypeId("ns3::ConstantSpeedPropagationDelayModel");
380  m_manager.SetTypeId("ns3::ConstantRateWifiManager");
381 
382  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel>();
384  Ptr<MatrixPropagationLossModel> propLoss = CreateObject<MatrixPropagationLossModel>();
385  channel->SetPropagationDelayModel(propDelay);
386  channel->SetPropagationLossModel(propLoss);
387 
388  Ptr<Node> rxOnly = CreateOne(Vector(0.0, 0.0, 0.0), channel);
389  Ptr<Node> senderA = CreateOne(Vector(5.0, 0.0, 0.0), channel);
390  Ptr<Node> senderB = CreateOne(Vector(-5.0, 0.0, 0.0), channel);
391 
392  propLoss->SetLoss(senderB->GetObject<MobilityModel>(),
393  rxOnly->GetObject<MobilityModel>(),
394  0,
395  true);
396  propLoss->SetDefaultLoss(999);
397 
398  Simulator::Schedule(Seconds(1.0),
400  this,
401  DynamicCast<WifiNetDevice>(senderB->GetDevice(0)));
402 
403  Simulator::Schedule(Seconds(1.0000001),
405  this,
406  DynamicCast<WifiNetDevice>(rxOnly->GetDevice(0)));
407 
408  Simulator::Schedule(Seconds(5.0),
410  this,
411  DynamicCast<WifiNetDevice>(senderA->GetDevice(0)));
412 
413  Simulator::Schedule(Seconds(7.0),
415  this,
416  DynamicCast<WifiNetDevice>(senderB->GetDevice(0)));
417 
418  Simulator::Stop(Seconds(100.0));
419  Simulator::Run();
420 
421  Simulator::Destroy();
422 }
423 
424 //-----------------------------------------------------------------------------
476 {
477  public:
479 
480  void DoRun() override;
481 
482  private:
488 
492 
495  unsigned int m_numSentPackets;
496 
502  void NotifyPhyTxBegin(Ptr<const Packet> p, double txPowerW);
503 };
504 
506  : TestCase("Test case for DCF immediate access with broadcast frames")
507 {
508 }
509 
510 void
512 {
513  if (m_numSentPackets == 0)
514  {
517  }
518  else if (m_numSentPackets == 1)
519  {
521  }
522 }
523 
524 void
526 {
527  Ptr<Packet> p = Create<Packet>(1000);
528  dev->Send(p, dev->GetBroadcast(), 1);
529 }
530 
531 void
533 {
534  m_mac.SetTypeId("ns3::AdhocWifiMac");
535  m_propDelay.SetTypeId("ns3::ConstantSpeedPropagationDelayModel");
536  m_manager.SetTypeId("ns3::ConstantRateWifiManager");
537 
538  // Assign a seed and run number, and later fix the assignment of streams to
539  // WiFi random variables, so that the first backoff used is one slot
540  RngSeedManager::SetSeed(1);
541  RngSeedManager::SetRun(40); // a value of 17 will result in zero slots
542 
543  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel>();
545  Ptr<PropagationLossModel> propLoss = CreateObject<RandomPropagationLossModel>();
546  channel->SetPropagationDelayModel(propDelay);
547  channel->SetPropagationLossModel(propLoss);
548 
549  Ptr<Node> txNode = CreateObject<Node>();
550  Ptr<WifiNetDevice> txDev = CreateObject<WifiNetDevice>();
551 
552  Ptr<ConstantPositionMobilityModel> txMobility = CreateObject<ConstantPositionMobilityModel>();
553  Ptr<YansWifiPhy> txPhy = CreateObject<YansWifiPhy>();
554  Ptr<InterferenceHelper> txInterferenceHelper = CreateObject<InterferenceHelper>();
555  txPhy->SetInterferenceHelper(txInterferenceHelper);
556  Ptr<ErrorRateModel> txError = CreateObject<YansErrorRateModel>();
557  txPhy->SetErrorRateModel(txError);
558  txPhy->SetChannel(channel);
559  txPhy->SetDevice(txDev);
560  txPhy->SetMobility(txMobility);
562 
564  "PhyTxBegin",
566 
567  txMobility->SetPosition(Vector(0.0, 0.0, 0.0));
568  txNode->AggregateObject(txMobility);
569  txDev->SetPhy(txPhy);
571  txNode->AddDevice(txDev);
572 
573  auto txMac = m_mac.Create<WifiMac>();
574  txMac->SetDevice(txDev);
575  txMac->SetAddress(Mac48Address::Allocate());
576  txDev->SetMac(txMac);
577  txMac->ConfigureStandard(WIFI_STANDARD_80211a);
578  txMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
579  auto fem = txMac->GetFrameExchangeManager();
580  auto protectionManager = CreateObject<WifiDefaultProtectionManager>();
581  protectionManager->SetWifiMac(txMac);
582  fem->SetProtectionManager(protectionManager);
583  auto ackManager = CreateObject<WifiDefaultAckManager>();
584  ackManager->SetWifiMac(txMac);
585  fem->SetAckManager(ackManager);
586 
587  // Fix the stream assignment to the Dcf Txop objects (backoffs)
588  // The below stream assignment will result in the Txop object
589  // using a backoff value of zero for this test when the
590  // Txop::EndTxNoAck() calls to StartBackoffNow()
591  AssignWifiRandomStreams(txMac, 23);
592 
595  m_numSentPackets = 0;
596 
597  Simulator::Schedule(Seconds(1.0),
599  this,
600  txDev);
601  Simulator::Schedule(Seconds(1.0) + MicroSeconds(1),
603  this,
604  txDev);
605 
606  Simulator::Stop(Seconds(2.0));
607  Simulator::Run();
608  Simulator::Destroy();
609 
610  // First packet is transmitted a DIFS after the packet is queued. A DIFS
611  // is 2 slots (2 * 9 = 18 us) plus a SIFS (16 us), i.e., 34 us
612  Time expectedFirstTransmissionTime = Seconds(1.0) + MicroSeconds(34);
613 
614  // First packet has 1408 us of transmit time. Slot time is 9 us.
615  // Backoff is 1 slots. SIFS is 16 us. DIFS is 2 slots = 18 us.
616  // Should send next packet at 1408 us + (1 * 9 us) + 16 us + (2 * 9) us
617  // 1451 us after the first one.
618  uint32_t expectedWait1 = 1408 + (1 * 9) + 16 + (2 * 9);
619  Time expectedSecondTransmissionTime =
620  expectedFirstTransmissionTime + MicroSeconds(expectedWait1);
622  expectedFirstTransmissionTime,
623  "The first transmission time not correct!");
624 
626  expectedSecondTransmissionTime,
627  "The second transmission time not correct!");
628 }
629 
630 //-----------------------------------------------------------------------------
643 class Bug730TestCase : public TestCase
644 {
645  public:
646  Bug730TestCase();
647  ~Bug730TestCase() override;
648 
649  void DoRun() override;
650 
651  private:
652  uint32_t m_received;
653 
660  void Receive(std::string context, Ptr<const Packet> p, const Address& adr);
661 };
662 
664  : TestCase("Test case for Bug 730"),
665  m_received(0)
666 {
667 }
668 
670 {
671 }
672 
673 void
674 Bug730TestCase::Receive(std::string context, Ptr<const Packet> p, const Address& adr)
675 {
676  if ((p->GetSize() == 1460) && (Simulator::Now() > Seconds(20)))
677  {
678  m_received++;
679  }
680 }
681 
682 void
684 {
685  m_received = 0;
686 
687  NodeContainer wifiStaNode;
688  wifiStaNode.Create(1);
689 
691  wifiApNode.Create(1);
692 
693  YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
695  phy.SetChannel(channel.Create());
696 
698  wifi.SetStandard(WIFI_STANDARD_80211b);
699  wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
700  "DataMode",
701  StringValue("DsssRate1Mbps"),
702  "ControlMode",
703  StringValue("DsssRate1Mbps"));
704 
706  Ssid ssid = Ssid("ns-3-ssid");
707  mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid), "ActiveProbing", BooleanValue(false));
708 
710  staDevices = wifi.Install(phy, mac, wifiStaNode);
711 
712  mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid), "BeaconGeneration", BooleanValue(true));
713 
715  apDevices = wifi.Install(phy, mac, wifiApNode);
716 
718  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
719 
720  positionAlloc->Add(Vector(0.0, 0.0, 0.0));
721  positionAlloc->Add(Vector(1.0, 0.0, 0.0));
722  mobility.SetPositionAllocator(positionAlloc);
723 
724  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
725  mobility.Install(wifiApNode);
726  mobility.Install(wifiStaNode);
727 
728  Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice>(apDevices.Get(0));
729  Ptr<WifiNetDevice> sta_device = DynamicCast<WifiNetDevice>(staDevices.Get(0));
730 
731  PacketSocketAddress socket;
732  socket.SetSingleDevice(sta_device->GetIfIndex());
733  socket.SetPhysicalAddress(ap_device->GetAddress());
734  socket.SetProtocol(1);
735 
736  // give packet socket powers to nodes.
737  PacketSocketHelper packetSocket;
738  packetSocket.Install(wifiStaNode);
739  packetSocket.Install(wifiApNode);
740 
741  Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient>();
742  client->SetAttribute("PacketSize", UintegerValue(1460));
743  client->SetRemote(socket);
744  wifiStaNode.Get(0)->AddApplication(client);
745  client->SetStartTime(Seconds(1));
746  client->SetStopTime(Seconds(51.0));
747 
748  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer>();
749  server->SetLocal(socket);
750  wifiApNode.Get(0)->AddApplication(server);
751  server->SetStartTime(Seconds(0.0));
752  server->SetStopTime(Seconds(52.0));
753 
754  Config::Connect("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx",
756 
757  Simulator::Schedule(Seconds(10.0),
758  Config::Set,
759  "/NodeList/0/DeviceList/0/RemoteStationManager/FragmentationThreshold",
760  StringValue("800"));
761 
762  Simulator::Stop(Seconds(55));
763  Simulator::Run();
764 
765  Simulator::Destroy();
766 
767  bool result = (m_received > 0);
769  result,
770  true,
771  "packet reception unexpectedly stopped after adapting fragmentation threshold!");
772 }
773 
774 //-----------------------------------------------------------------------------
783 {
784  public:
786  ~QosFragmentationTestCase() override;
787 
788  void DoRun() override;
789 
790  private:
791  uint32_t m_received;
792  uint32_t m_fragments;
793 
800  void Receive(std::string context, Ptr<const Packet> p, const Address& adr);
801 
808  void Transmit(std::string context, Ptr<const Packet> p, double power);
809 };
810 
812  : TestCase("Test case for fragmentation with QoS stations"),
813  m_received(0),
814  m_fragments(0)
815 {
816 }
817 
819 {
820 }
821 
822 void
824 {
825  if (p->GetSize() == 1400)
826  {
827  m_received++;
828  }
829 }
830 
831 void
832 QosFragmentationTestCase::Transmit(std::string context, Ptr<const Packet> p, double power)
833 {
834  WifiMacHeader hdr;
835  p->PeekHeader(hdr);
836  if (hdr.IsQosData())
837  {
838  NS_TEST_EXPECT_MSG_LT_OR_EQ(p->GetSize(), 400, "Unexpected fragment size");
839  m_fragments++;
840  }
841 }
842 
843 void
845 {
846  NodeContainer wifiStaNode;
847  wifiStaNode.Create(1);
848 
850  wifiApNode.Create(1);
851 
852  YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
854  phy.SetChannel(channel.Create());
855 
857  wifi.SetStandard(WIFI_STANDARD_80211n);
858  wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", "DataMode", StringValue("HtMcs7"));
859 
861  Ssid ssid = Ssid("ns-3-ssid");
862  mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid), "ActiveProbing", BooleanValue(false));
863 
865  staDevices = wifi.Install(phy, mac, wifiStaNode);
866 
867  mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid), "BeaconGeneration", BooleanValue(true));
868 
870  apDevices = wifi.Install(phy, mac, wifiApNode);
871 
873  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
874 
875  positionAlloc->Add(Vector(0.0, 0.0, 0.0));
876  positionAlloc->Add(Vector(1.0, 0.0, 0.0));
877  mobility.SetPositionAllocator(positionAlloc);
878 
879  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
880  mobility.Install(wifiApNode);
881  mobility.Install(wifiStaNode);
882 
883  Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice>(apDevices.Get(0));
884  Ptr<WifiNetDevice> sta_device = DynamicCast<WifiNetDevice>(staDevices.Get(0));
885 
886  // set the TXOP limit on BE AC
887  PointerValue ptr;
888  sta_device->GetMac()->GetAttribute("BE_Txop", ptr);
889  ptr.Get<QosTxop>()->SetTxopLimit(MicroSeconds(3008));
890 
891  PacketSocketAddress socket;
892  socket.SetSingleDevice(sta_device->GetIfIndex());
893  socket.SetPhysicalAddress(ap_device->GetAddress());
894  socket.SetProtocol(1);
895 
896  // give packet socket powers to nodes.
897  PacketSocketHelper packetSocket;
898  packetSocket.Install(wifiStaNode);
899  packetSocket.Install(wifiApNode);
900 
901  Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient>();
902  client->SetAttribute("PacketSize", UintegerValue(1400));
903  client->SetAttribute("MaxPackets", UintegerValue(1));
904  client->SetRemote(socket);
905  wifiStaNode.Get(0)->AddApplication(client);
906  client->SetStartTime(Seconds(1));
907  client->SetStopTime(Seconds(3.0));
908 
909  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer>();
910  server->SetLocal(socket);
911  wifiApNode.Get(0)->AddApplication(server);
912  server->SetStartTime(Seconds(0.0));
913  server->SetStopTime(Seconds(4.0));
914 
915  Config::Connect("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx",
917 
918  Config::Set("/NodeList/0/DeviceList/0/RemoteStationManager/FragmentationThreshold",
919  StringValue("400"));
920  Config::Connect("/NodeList/0/DeviceList/0/Phy/PhyTxBegin",
922 
923  Simulator::Stop(Seconds(5));
924  Simulator::Run();
925 
926  Simulator::Destroy();
927 
928  NS_TEST_ASSERT_MSG_EQ(m_received, 1, "Unexpected number of received packets");
929  NS_TEST_ASSERT_MSG_EQ(m_fragments, 4, "Unexpected number of transmitted fragments");
930 }
931 
939 {
940  public:
942 
943  void DoRun() override;
944 
945  private:
952 };
953 
955  : TestCase("Test case for setting WifiPhy channel and frequency")
956 {
957 }
958 
961 {
962  Ptr<WifiNetDevice> wnd = nc.Get(0)->GetObject<WifiNetDevice>();
963  Ptr<WifiPhy> wp = wnd->GetPhy();
964  return wp->GetObject<YansWifiPhy>();
965 }
966 
967 void
969 {
970  NodeContainer wifiStaNode;
971  wifiStaNode.Create(1);
973  wifiApNode.Create(1);
974 
975  YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
977  phy.SetChannel(channel.Create());
978 
979  // Configure and declare other generic components of this example
980  Ssid ssid;
981  ssid = Ssid("wifi-phy-configuration");
982  WifiMacHelper macSta;
983  macSta.SetType("ns3::StaWifiMac",
984  "Ssid",
985  SsidValue(ssid),
986  "ActiveProbing",
987  BooleanValue(false));
988  NetDeviceContainer staDevice;
989  Ptr<YansWifiPhy> phySta;
990 
991  // Cases taken from src/wifi/examples/wifi-phy-configuration.cc example
992  {
993  // case 0:
994  // Default configuration, without WifiHelper::SetStandard or WifiHelper
995  phySta = CreateObject<YansWifiPhy>();
996  // The default results in an invalid configuration
998  false,
999  "default configuration");
1000  }
1001  {
1002  // case 1:
1003  WifiHelper wifi;
1004  wifi.SetStandard(WIFI_STANDARD_80211a);
1005  wifi.SetRemoteStationManager("ns3::ArfWifiManager");
1006  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1007  phySta = GetYansWifiPhyPtr(staDevice);
1008  // We expect channel 36, width 20, frequency 5180
1009  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "default configuration");
1010  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "default configuration");
1011  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "default configuration");
1012  }
1013  {
1014  // case 2:
1015  WifiHelper wifi;
1016  wifi.SetStandard(WIFI_STANDARD_80211b);
1017  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1018  phySta = GetYansWifiPhyPtr(staDevice);
1019  // We expect channel 1, width 22, frequency 2412
1020  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 1, "802.11b configuration");
1021  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 22, "802.11b configuration");
1022  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 2412, "802.11b configuration");
1023  }
1024  {
1025  // case 3:
1026  WifiHelper wifi;
1027  wifi.SetStandard(WIFI_STANDARD_80211g);
1028  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1029  phySta = GetYansWifiPhyPtr(staDevice);
1030  // We expect channel 1, width 20, frequency 2412
1031  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 1, "802.11g configuration");
1032  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11g configuration");
1033  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 2412, "802.11g configuration");
1034  }
1035  {
1036  // case 4:
1037  WifiHelper wifi;
1038  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1039  wifi.SetStandard(WIFI_STANDARD_80211n);
1040  phy.Set("ChannelSettings", StringValue("{0, 0, BAND_5GHZ, 0}"));
1041  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1042  phySta = GetYansWifiPhyPtr(staDevice);
1043  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11n-5GHz configuration");
1044  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11n-5GHz configuration");
1045  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11n-5GHz configuration");
1046  phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1047  }
1048  {
1049  // case 5:
1050  WifiHelper wifi;
1051  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1052  wifi.SetStandard(WIFI_STANDARD_80211n);
1053  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1054  phySta = GetYansWifiPhyPtr(staDevice);
1055  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 1, "802.11n-2.4GHz configuration");
1056  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11n-2.4GHz configuration");
1057  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 2412, "802.11n-2.4GHz configuration");
1058  }
1059  {
1060  // case 6:
1061  WifiHelper wifi;
1062  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1063  wifi.SetStandard(WIFI_STANDARD_80211ac);
1064  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1065  phySta = GetYansWifiPhyPtr(staDevice);
1066  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 42, "802.11ac configuration");
1067  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 80, "802.11ac configuration");
1068  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5210, "802.11ac configuration");
1069  }
1070  {
1071  // case 7:
1072  // By default, WifiHelper will use WIFI_PHY_STANDARD_80211ax
1073  WifiHelper wifi;
1074  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1075  phy.Set("ChannelSettings", StringValue("{0, 0, BAND_2_4GHZ, 0}"));
1076  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1077  phySta = GetYansWifiPhyPtr(staDevice);
1078  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 1, "802.11ax-2.4GHz configuration");
1079  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11ax-2.4GHz configuration");
1080  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 2412, "802.11ax-2.4GHz configuration");
1081  phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1082  }
1083  {
1084  // case 8:
1085  WifiHelper wifi;
1086  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1087  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1088  phySta = GetYansWifiPhyPtr(staDevice);
1089  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 42, "802.11ax-5GHz configuration");
1090  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 80, "802.11ax-5GHz configuration");
1091  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5210, "802.11ax-5GHz configuration");
1092  }
1093  {
1094  // case 9:
1095  WifiHelper wifi;
1096  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1097  phy.Set("ChannelSettings", StringValue("{0, 0, BAND_6GHZ, 0}"));
1098  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1099  phySta = GetYansWifiPhyPtr(staDevice);
1100  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 7, "802.11ax-6GHz configuration");
1101  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 80, "802.11ax-6GHz configuration");
1102  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5985, "802.11ax-6GHz configuration");
1103  phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1104  }
1105  {
1106  // case 10:
1107  WifiHelper wifi;
1108  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1109  wifi.SetStandard(WIFI_STANDARD_80211p);
1110  phy.Set("ChannelSettings", StringValue("{0, 10, BAND_5GHZ, 0}"));
1111  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1112  phySta = GetYansWifiPhyPtr(staDevice);
1113  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 172, "802.11p 10Mhz configuration");
1114  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 10, "802.11p 10Mhz configuration");
1115  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5860, "802.11p 10Mhz configuration");
1116  phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1117  }
1118  {
1119  // case 11:
1120  WifiHelper wifi;
1121  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1122  wifi.SetStandard(WIFI_STANDARD_80211p);
1123  phy.Set("ChannelSettings", StringValue("{0, 5, BAND_5GHZ, 0}"));
1124  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1125  phySta = GetYansWifiPhyPtr(staDevice);
1126  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 171, "802.11p 5Mhz configuration");
1127  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 5, "802.11p 5Mhz configuration");
1128  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5860, "802.11p 5Mhz configuration");
1129  phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1130  }
1131  {
1132  // case 12:
1133  WifiHelper wifi;
1134  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1135  wifi.SetStandard(WIFI_STANDARD_80211n);
1136  phy.Set("ChannelSettings", StringValue("{44, 20, BAND_5GHZ, 0}"));
1137  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1138  phySta = GetYansWifiPhyPtr(staDevice);
1139  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 44, "802.11 5GHz configuration");
1140  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1141  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5220, "802.11 5GHz configuration");
1142  phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1143  }
1144  {
1145  // case 13:
1146  WifiHelper wifi;
1147  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1148  phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1149  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1150  phySta = GetYansWifiPhyPtr(staDevice);
1151  // Post-install reconfiguration to channel number 40
1152  std::ostringstream path;
1153  path << "/NodeList/*/DeviceList/" << staDevice.Get(0)->GetIfIndex()
1154  << "/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelSettings";
1155  Config::Set(path.str(), StringValue("{40, 0, BAND_5GHZ, 0}"));
1156  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 40, "802.11 5GHz configuration");
1157  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1158  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5200, "802.11 5GHz configuration");
1159  phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1160  }
1161  {
1162  // case 14:
1163  WifiHelper wifi;
1164  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1165  phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1166  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1167  phySta = GetYansWifiPhyPtr(staDevice);
1168  // Post-install reconfiguration to a 40 MHz channel
1169  std::ostringstream path;
1170  path << "/NodeList/*/DeviceList/" << staDevice.Get(0)->GetIfIndex()
1171  << "/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelSettings";
1172  Config::Set(path.str(), StringValue("{46, 0, BAND_5GHZ, 0}"));
1173  // Although channel 44 is configured originally for 20 MHz, we
1174  // allow it to be used for 40 MHz here
1175  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 46, "802.11 5GHz configuration");
1176  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 40, "802.11 5GHz configuration");
1177  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5230, "802.11 5GHz configuration");
1178  phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1179  }
1180  {
1181  // case 15:
1182  WifiHelper wifi;
1183  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1184  wifi.SetStandard(WIFI_STANDARD_80211n);
1185  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1186  phySta = GetYansWifiPhyPtr(staDevice);
1187  phySta->SetAttribute("ChannelSettings", StringValue("{3, 20, BAND_2_4GHZ, 0}"));
1188  // Post-install reconfiguration to a 40 MHz channel
1189  std::ostringstream path;
1190  path << "/NodeList/*/DeviceList/" << staDevice.Get(0)->GetIfIndex()
1191  << "/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelSettings";
1192  Config::Set(path.str(), StringValue("{4, 40, BAND_2_4GHZ, 0}"));
1193  // Although channel 44 is configured originally for 20 MHz, we
1194  // allow it to be used for 40 MHz here
1195  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 4, "802.11 5GHz configuration");
1196  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 40, "802.11 5GHz configuration");
1197  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 2427, "802.11 5GHz configuration");
1198  phy.Set("ChannelSettings", StringValue("{0, 0, BAND_UNSPECIFIED, 0}")); // restore default
1199  }
1200  {
1201  // case 16:
1202  WifiHelper wifi;
1203  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1204  // Test that setting Frequency to a non-standard value will throw an exception
1205  wifi.SetStandard(WIFI_STANDARD_80211n);
1206  phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1207  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1208  phySta = GetYansWifiPhyPtr(staDevice);
1209  bool exceptionThrown = false;
1210  try
1211  {
1212  phySta->SetAttribute("ChannelSettings", StringValue("{45, 0, BAND_5GHZ, 0}"));
1213  }
1214  catch (const std::runtime_error&)
1215  {
1216  exceptionThrown = true;
1217  }
1218  // We expect that an exception is thrown
1219  NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1220  }
1221  {
1222  // case 17:
1223  WifiHelper wifi;
1224  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1225  wifi.SetStandard(WIFI_STANDARD_80211n);
1226  phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1227  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1228  phySta = GetYansWifiPhyPtr(staDevice);
1229  // Test that setting channel to a standard value will set the
1230  // frequency correctly
1231  phySta->SetAttribute("ChannelSettings", StringValue("{100, 0, BAND_5GHZ, 0}"));
1232  // We expect frequency to be 5500 due to channel number being 100
1233  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 100, "802.11 5GHz configuration");
1234  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1235  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5500, "802.11 5GHz configuration");
1236  }
1237  {
1238  // case 18:
1239  // Set a wrong channel after initialization
1240  WifiHelper wifi;
1241  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1242  wifi.SetStandard(WIFI_STANDARD_80211n);
1243  phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1244  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1245  phySta = GetYansWifiPhyPtr(staDevice);
1246  bool exceptionThrown = false;
1247  try
1248  {
1250  }
1251  catch (const std::runtime_error&)
1252  {
1253  exceptionThrown = true;
1254  }
1255  // We expect that an exception is thrown
1256  NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1257  }
1258  {
1259  // case 19:
1260  WifiHelper wifi;
1261  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1262  // Test how channel number behaves when frequency is non-standard
1263  wifi.SetStandard(WIFI_STANDARD_80211n);
1264  phy.Set("ChannelSettings", StringValue("{44, 0, BAND_5GHZ, 0}"));
1265  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1266  phySta = GetYansWifiPhyPtr(staDevice);
1267  bool exceptionThrown = false;
1268  try
1269  {
1270  phySta->SetAttribute("ChannelSettings", StringValue("{45, 0, BAND_5GHZ, 0}"));
1271  }
1272  catch (const std::runtime_error&)
1273  {
1274  exceptionThrown = true;
1275  }
1276  // We expect that an exception is thrown due to unknown channel number 45
1277  NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1278  phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1279  // We expect channel number to be 36 due to known center frequency 5180
1280  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1281  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1282  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11 5GHz configuration");
1283  exceptionThrown = false;
1284  try
1285  {
1286  phySta->SetAttribute("ChannelSettings", StringValue("{43, 0, BAND_5GHZ, 0}"));
1287  }
1288  catch (const std::runtime_error&)
1289  {
1290  exceptionThrown = true;
1291  }
1292  // We expect that an exception is thrown due to unknown channel number 43
1293  NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1294  phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1295  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1296  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1297  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11 5GHz configuration");
1298  }
1299  {
1300  // case 20:
1301  WifiHelper wifi;
1302  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1303  phy.Set("ChannelSettings", StringValue("{40, 0, BAND_5GHZ, 0}"));
1304  wifi.SetStandard(WIFI_STANDARD_80211n);
1305  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1306  phySta = GetYansWifiPhyPtr(staDevice);
1307  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 40, "802.11 5GHz configuration");
1308  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1309  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5200, "802.11 5GHz configuration");
1310  // Set both channel and frequency to consistent values after initialization
1311  wifi.SetStandard(WIFI_STANDARD_80211n);
1312  staDevice = wifi.Install(phy, macSta, wifiStaNode.Get(0));
1313  phySta = GetYansWifiPhyPtr(staDevice);
1314  phySta->SetAttribute("ChannelSettings", StringValue("{40, 0, BAND_5GHZ, 0}"));
1315  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 40, "802.11 5GHz configuration");
1316  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1317  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5200, "802.11 5GHz configuration");
1318 
1319  phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1320  // We expect channel number to be 36
1321  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1322  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1323  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11 5GHz configuration");
1324  phySta->SetAttribute("ChannelSettings", StringValue("{40, 0, BAND_5GHZ, 0}"));
1325  // We expect channel number to be 40
1326  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 40, "802.11 5GHz configuration");
1327  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1328  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5200, "802.11 5GHz configuration");
1329  bool exceptionThrown = false;
1330  try
1331  {
1332  phySta->SetAttribute("ChannelSettings", StringValue("{45, 0, BAND_5GHZ, 0}"));
1333  }
1334  catch (const std::runtime_error&)
1335  {
1336  exceptionThrown = true;
1337  }
1338  phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1339  // We expect channel number to be 36 and an exception to be thrown
1340  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1341  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1342  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11 5GHz configuration");
1343  NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1344  phySta->SetAttribute("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
1345  exceptionThrown = false;
1346  try
1347  {
1348  phySta->SetAttribute("ChannelSettings", StringValue("{43, 0, BAND_5GHZ, 0}"));
1349  }
1350  catch (const std::runtime_error&)
1351  {
1352  exceptionThrown = true;
1353  }
1354  // We expect channel number to be 36 and an exception to be thrown
1355  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelNumber(), 36, "802.11 5GHz configuration");
1356  NS_TEST_ASSERT_MSG_EQ(phySta->GetChannelWidth(), 20, "802.11 5GHz configuration");
1357  NS_TEST_ASSERT_MSG_EQ(phySta->GetFrequency(), 5180, "802.11 5GHz configuration");
1358  NS_TEST_ASSERT_MSG_EQ(exceptionThrown, true, "802.11 5GHz configuration");
1359  }
1360 
1361  Simulator::Destroy();
1362 }
1363 
1364 //-----------------------------------------------------------------------------
1373 {
1374  public:
1375  Bug2222TestCase();
1376  ~Bug2222TestCase() override;
1377 
1378  void DoRun() override;
1379 
1380  private:
1382 
1388  void TxDataFailedTrace(std::string context, Mac48Address adr);
1389 };
1390 
1392  : TestCase("Test case for Bug 2222"),
1393  m_countInternalCollisions(0)
1394 {
1395 }
1396 
1398 {
1399 }
1400 
1401 void
1403 {
1404  // Indicate the long retry counter has been increased in the wifi remote station manager
1406 }
1407 
1408 void
1410 {
1412 
1413  // Generate same backoff for AC_VI and AC_VO
1414  // The below combination will work
1415  RngSeedManager::SetSeed(1);
1416  RngSeedManager::SetRun(1);
1417  int64_t streamNumber = 100;
1418 
1419  NodeContainer wifiNodes;
1420  wifiNodes.Create(2);
1421 
1422  YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
1424  phy.SetChannel(channel.Create());
1425 
1426  WifiHelper wifi;
1427  wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
1428  "DataMode",
1429  StringValue("OfdmRate54Mbps"),
1430  "ControlMode",
1431  StringValue("OfdmRate24Mbps"));
1433  Ssid ssid = Ssid("ns-3-ssid");
1434  mac.SetType("ns3::AdhocWifiMac", "QosSupported", BooleanValue(true));
1435 
1436  NetDeviceContainer wifiDevices;
1437  wifiDevices = wifi.Install(phy, mac, wifiNodes);
1438 
1439  // Assign fixed streams to random variables in use
1440  wifi.AssignStreams(wifiDevices, streamNumber);
1441 
1443  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
1444 
1445  positionAlloc->Add(Vector(0.0, 0.0, 0.0));
1446  positionAlloc->Add(Vector(10.0, 0.0, 0.0));
1447  mobility.SetPositionAllocator(positionAlloc);
1448 
1449  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1450  mobility.Install(wifiNodes);
1451 
1452  Ptr<WifiNetDevice> device1 = DynamicCast<WifiNetDevice>(wifiDevices.Get(0));
1453  Ptr<WifiNetDevice> device2 = DynamicCast<WifiNetDevice>(wifiDevices.Get(1));
1454 
1455  PacketSocketAddress socket;
1456  socket.SetSingleDevice(device1->GetIfIndex());
1457  socket.SetPhysicalAddress(device2->GetAddress());
1458  socket.SetProtocol(1);
1459 
1460  PacketSocketHelper packetSocket;
1461  packetSocket.Install(wifiNodes);
1462 
1463  Ptr<PacketSocketClient> clientLowPriority = CreateObject<PacketSocketClient>();
1464  clientLowPriority->SetAttribute("PacketSize", UintegerValue(1460));
1465  clientLowPriority->SetAttribute("MaxPackets", UintegerValue(1));
1466  clientLowPriority->SetAttribute("Priority", UintegerValue(4)); // AC_VI
1467  clientLowPriority->SetRemote(socket);
1468  wifiNodes.Get(0)->AddApplication(clientLowPriority);
1469  clientLowPriority->SetStartTime(Seconds(0.0));
1470  clientLowPriority->SetStopTime(Seconds(1.0));
1471 
1472  Ptr<PacketSocketClient> clientHighPriority = CreateObject<PacketSocketClient>();
1473  clientHighPriority->SetAttribute("PacketSize", UintegerValue(1460));
1474  clientHighPriority->SetAttribute("MaxPackets", UintegerValue(1));
1475  clientHighPriority->SetAttribute("Priority", UintegerValue(6)); // AC_VO
1476  clientHighPriority->SetRemote(socket);
1477  wifiNodes.Get(0)->AddApplication(clientHighPriority);
1478  clientHighPriority->SetStartTime(Seconds(0.0));
1479  clientHighPriority->SetStopTime(Seconds(1.0));
1480 
1481  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer>();
1482  server->SetLocal(socket);
1483  wifiNodes.Get(1)->AddApplication(server);
1484  server->SetStartTime(Seconds(0.0));
1485  server->SetStopTime(Seconds(1.0));
1486 
1487  Config::Connect("/NodeList/*/DeviceList/*/RemoteStationManager/MacTxDataFailed",
1489 
1490  Simulator::Stop(Seconds(1.0));
1491  Simulator::Run();
1492  Simulator::Destroy();
1493 
1495  1,
1496  "unexpected number of internal collisions!");
1497 }
1498 
1499 //-----------------------------------------------------------------------------
1513 {
1514  public:
1515  Bug2843TestCase();
1516  ~Bug2843TestCase() override;
1517  void DoRun() override;
1518 
1519  private:
1524  typedef std::tuple<double, uint16_t, uint32_t, WifiModulationClass>
1526  std::vector<FreqWidthSubbandModulationTuple>
1529 
1536  void StoreDistinctTuple(std::string context, Ptr<SpectrumSignalParameters> txParams);
1543  void SendPacketBurst(uint8_t numPackets,
1544  Ptr<NetDevice> sourceDevice,
1545  Address& destination) const;
1546 
1547  uint16_t m_channelWidth;
1548 };
1549 
1551  : TestCase("Test case for Bug 2843"),
1552  m_channelWidth(20)
1553 {
1554 }
1555 
1557 {
1558 }
1559 
1560 void
1562 {
1563  // Extract starting frequency and number of subbands
1565  std::size_t numBands = c->GetNumBands();
1566  double startingFreq = c->Begin()->fl;
1567 
1568  // Get channel bandwidth and modulation class
1570  DynamicCast<WifiSpectrumSignalParameters>(txParams);
1571 
1572  Ptr<WifiPpdu> ppdu = wifiTxParams->ppdu->Copy();
1573  WifiTxVector txVector = ppdu->GetTxVector();
1574  m_channelWidth = txVector.GetChannelWidth();
1575  WifiModulationClass modulationClass = txVector.GetMode().GetModulationClass();
1576 
1577  // Build a tuple and check if seen before (if so store it)
1578  FreqWidthSubbandModulationTuple tupleForCurrentTx =
1579  std::make_tuple(startingFreq, m_channelWidth, numBands, modulationClass);
1580  bool found = false;
1581  for (auto it = m_distinctTuples.begin(); it != m_distinctTuples.end(); it++)
1582  {
1583  if (*it == tupleForCurrentTx)
1584  {
1585  found = true;
1586  }
1587  }
1588  if (!found)
1589  {
1590  m_distinctTuples.push_back(tupleForCurrentTx);
1591  }
1592 }
1593 
1594 void
1596  Ptr<NetDevice> sourceDevice,
1597  Address& destination) const
1598 {
1599  for (uint8_t i = 0; i < numPackets; i++)
1600  {
1601  Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
1602  sourceDevice->Send(pkt, destination, 0);
1603  }
1604 }
1605 
1606 void
1608 {
1609  uint16_t channelWidth = 40; // at least 40 MHz expected here
1610 
1611  NodeContainer wifiStaNode;
1612  wifiStaNode.Create(1);
1613 
1615  wifiApNode.Create(1);
1616 
1617  SpectrumWifiPhyHelper spectrumPhy;
1618  Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
1619  Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel>();
1620  lossModel->SetFrequency(5.190e9);
1621  spectrumChannel->AddPropagationLossModel(lossModel);
1622 
1624  CreateObject<ConstantSpeedPropagationDelayModel>();
1625  spectrumChannel->SetPropagationDelayModel(delayModel);
1626 
1627  spectrumPhy.SetChannel(spectrumChannel);
1628  spectrumPhy.SetErrorRateModel("ns3::NistErrorRateModel");
1629  spectrumPhy.Set("ChannelSettings", StringValue("{38, 40, BAND_5GHZ, 0}"));
1630  spectrumPhy.Set("TxPowerStart", DoubleValue(10));
1631  spectrumPhy.Set("TxPowerEnd", DoubleValue(10));
1632 
1633  WifiHelper wifi;
1634  wifi.SetStandard(WIFI_STANDARD_80211ac);
1635  wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
1636  "DataMode",
1637  StringValue("VhtMcs8"),
1638  "ControlMode",
1639  StringValue("VhtMcs8"),
1640  "RtsCtsThreshold",
1641  StringValue("500")); // so as to force RTS/CTS for data frames
1642 
1644  mac.SetType("ns3::StaWifiMac");
1645  NetDeviceContainer staDevice;
1646  staDevice = wifi.Install(spectrumPhy, mac, wifiStaNode);
1647 
1648  mac.SetType("ns3::ApWifiMac");
1649  NetDeviceContainer apDevice;
1650  apDevice = wifi.Install(spectrumPhy, mac, wifiApNode);
1651 
1653  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
1654  positionAlloc->Add(Vector(0.0, 0.0, 0.0));
1655  positionAlloc->Add(Vector(1.0, 0.0, 0.0)); // put close enough in order to use MCS
1656  mobility.SetPositionAllocator(positionAlloc);
1657 
1658  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1659  mobility.Install(wifiApNode);
1660  mobility.Install(wifiStaNode);
1661 
1662  // Send two 5 packet-bursts
1663  Simulator::Schedule(Seconds(0.5),
1665  this,
1666  5,
1667  apDevice.Get(0),
1668  staDevice.Get(0)->GetAddress());
1669  Simulator::Schedule(Seconds(0.6),
1671  this,
1672  5,
1673  apDevice.Get(0),
1674  staDevice.Get(0)->GetAddress());
1675 
1676  Config::Connect("/ChannelList/*/$ns3::MultiModelSpectrumChannel/TxSigParams",
1678 
1679  Simulator::Stop(Seconds(0.8));
1680  Simulator::Run();
1681 
1682  Simulator::Destroy();
1683 
1684  // {starting frequency, channelWidth, Number of subbands in SpectrumModel, modulation type}
1685  // tuples
1686  std::size_t numberTuples = m_distinctTuples.size();
1687  NS_TEST_ASSERT_MSG_EQ(numberTuples, 2, "Only two distinct tuples expected");
1688  NS_TEST_ASSERT_MSG_EQ(std::get<0>(m_distinctTuples[0]) - 20e6,
1689  std::get<0>(m_distinctTuples[1]),
1690  "The starting frequency of the first tuple should be shifted 20 MHz to "
1691  "the right wrt second tuple");
1692  // Note that the first tuple should the one initiated by the beacon, i.e. non-HT OFDM (20 MHz)
1693  NS_TEST_ASSERT_MSG_EQ(std::get<1>(m_distinctTuples[0]),
1694  20,
1695  "First tuple's channel width should be 20 MHz");
1696  NS_TEST_ASSERT_MSG_EQ(std::get<2>(m_distinctTuples[0]),
1697  193,
1698  "First tuple should have 193 subbands (64+DC, 20MHz+DC, inband and 64*2 "
1699  "out-of-band, 20MHz on each side)");
1700  NS_TEST_ASSERT_MSG_EQ(std::get<3>(m_distinctTuples[0]),
1702  "First tuple should be OFDM");
1703  // Second tuple
1704  NS_TEST_ASSERT_MSG_EQ(std::get<1>(m_distinctTuples[1]),
1705  channelWidth,
1706  "Second tuple's channel width should be 40 MHz");
1707  NS_TEST_ASSERT_MSG_EQ(std::get<2>(m_distinctTuples[1]),
1708  385,
1709  "Second tuple should have 385 subbands (128+DC, 40MHz+DC, inband and "
1710  "128*2 out-of-band, 40MHz on each side)");
1711  NS_TEST_ASSERT_MSG_EQ(std::get<3>(m_distinctTuples[1]),
1713  "Second tuple should be VHT_OFDM");
1714 }
1715 
1716 //-----------------------------------------------------------------------------
1729 {
1730  public:
1731  Bug2831TestCase();
1732  ~Bug2831TestCase() override;
1733  void DoRun() override;
1734 
1735  private:
1746  void RxCallback(std::string context, Ptr<const Packet> p, RxPowerWattPerChannelBand rxPowersW);
1747 
1750 
1751  uint16_t m_assocReqCount;
1752  uint16_t m_assocRespCount;
1757 };
1758 
1760  : TestCase("Test case for Bug 2831"),
1761  m_assocReqCount(0),
1762  m_assocRespCount(0),
1763  m_countOperationalChannelWidth20(0),
1764  m_countOperationalChannelWidth40(0)
1765 {
1766 }
1767 
1769 {
1770 }
1771 
1772 void
1774 {
1777 }
1778 
1779 void
1780 Bug2831TestCase::RxCallback(std::string context,
1782  RxPowerWattPerChannelBand rxPowersW)
1783 {
1784  Ptr<Packet> packet = p->Copy();
1785  WifiMacHeader hdr;
1786  packet->RemoveHeader(hdr);
1787  if (hdr.IsAssocReq())
1788  {
1789  m_assocReqCount++;
1790  }
1791  else if (hdr.IsAssocResp())
1792  {
1793  m_assocRespCount++;
1794  }
1795  else if (hdr.IsBeacon())
1796  {
1797  MgtBeaconHeader beacon;
1798  packet->RemoveHeader(beacon);
1799  const auto& htOperation = beacon.Get<HtOperation>();
1800  if (htOperation.has_value() && htOperation->GetStaChannelWidth() > 0)
1801  {
1803  }
1804  else
1805  {
1807  }
1808  }
1809 }
1810 
1811 void
1813 {
1814  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel>();
1815  ObjectFactory propDelay;
1816  propDelay.SetTypeId("ns3::ConstantSpeedPropagationDelayModel");
1817  Ptr<PropagationDelayModel> propagationDelay = propDelay.Create<PropagationDelayModel>();
1818  Ptr<PropagationLossModel> propagationLoss = CreateObject<FriisPropagationLossModel>();
1819  channel->SetPropagationDelayModel(propagationDelay);
1820  channel->SetPropagationLossModel(propagationLoss);
1821 
1822  Ptr<Node> apNode = CreateObject<Node>();
1823  Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice>();
1824  apNode->AddDevice(apDev);
1826  Ptr<HtConfiguration> apHtConfiguration = CreateObject<HtConfiguration>();
1827  apDev->SetHtConfiguration(apHtConfiguration);
1828  ObjectFactory manager;
1829  manager.SetTypeId("ns3::ConstantRateWifiManager");
1831 
1832  auto apMobility = CreateObject<ConstantPositionMobilityModel>();
1833  apMobility->SetPosition(Vector(0.0, 0.0, 0.0));
1834  apNode->AggregateObject(apMobility);
1835 
1836  auto error = CreateObject<YansErrorRateModel>();
1837  m_apPhy = CreateObject<YansWifiPhy>();
1838  apDev->SetPhy(m_apPhy);
1839  Ptr<InterferenceHelper> apInterferenceHelper = CreateObject<InterferenceHelper>();
1840  m_apPhy->SetInterferenceHelper(apInterferenceHelper);
1841  m_apPhy->SetErrorRateModel(error);
1843  m_apPhy->SetMobility(apMobility);
1844  m_apPhy->SetDevice(apDev);
1847 
1849  mac.SetTypeId("ns3::ApWifiMac");
1850  mac.Set("EnableBeaconJitter", BooleanValue(false));
1851  mac.Set("QosSupported", BooleanValue(true));
1852  Ptr<WifiMac> apMac = mac.Create<WifiMac>();
1853  apMac->SetDevice(apDev);
1854  apMac->SetAddress(Mac48Address::Allocate());
1855  apDev->SetMac(apMac);
1857  apMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
1859  Ptr<WifiProtectionManager> protectionManager = CreateObject<WifiDefaultProtectionManager>();
1860  protectionManager->SetWifiMac(apMac);
1861  fem->SetProtectionManager(protectionManager);
1862  Ptr<WifiAckManager> ackManager = CreateObject<WifiDefaultAckManager>();
1863  ackManager->SetWifiMac(apMac);
1864  fem->SetAckManager(ackManager);
1865 
1866  Ptr<Node> staNode = CreateObject<Node>();
1867  Ptr<WifiNetDevice> staDev = CreateObject<WifiNetDevice>();
1868  staNode->AddDevice(staDev);
1870  Ptr<HtConfiguration> staHtConfiguration = CreateObject<HtConfiguration>();
1871  staDev->SetHtConfiguration(staHtConfiguration);
1873 
1874  Ptr<ConstantPositionMobilityModel> staMobility = CreateObject<ConstantPositionMobilityModel>();
1875  staMobility->SetPosition(Vector(1.0, 0.0, 0.0));
1876  staNode->AggregateObject(staMobility);
1877 
1878  m_staPhy = CreateObject<YansWifiPhy>();
1879  staDev->SetPhy(m_staPhy);
1880  Ptr<InterferenceHelper> staInterferenceHelper = CreateObject<InterferenceHelper>();
1881  m_staPhy->SetInterferenceHelper(staInterferenceHelper);
1882  m_staPhy->SetErrorRateModel(error);
1884  m_staPhy->SetMobility(staMobility);
1885  m_staPhy->SetDevice(apDev);
1888 
1889  mac.SetTypeId("ns3::StaWifiMac");
1890  auto staMac = mac.Create<WifiMac>();
1891  staDev->SetMac(staMac);
1892  staMac->SetDevice(staDev);
1893  staMac->SetAddress(Mac48Address::Allocate());
1894  staMac->ConfigureStandard(WIFI_STANDARD_80211ax);
1895  StaticCast<StaWifiMac>(staMac)->SetAssocManager(CreateObject<WifiDefaultAssocManager>());
1896  staMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
1897  fem = staMac->GetFrameExchangeManager();
1898  protectionManager = CreateObject<WifiDefaultProtectionManager>();
1899  protectionManager->SetWifiMac(staMac);
1900  fem->SetProtectionManager(protectionManager);
1901  ackManager = CreateObject<WifiDefaultAckManager>();
1902  ackManager->SetWifiMac(staMac);
1903  fem->SetAckManager(ackManager);
1904 
1905  Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxBegin",
1907 
1908  Simulator::Schedule(Seconds(1.0), &Bug2831TestCase::ChangeSupportedChannelWidth, this);
1909 
1910  Simulator::Stop(Seconds(3.0));
1911  Simulator::Run();
1912  Simulator::Destroy();
1913 
1914  NS_TEST_ASSERT_MSG_EQ(m_assocReqCount, 2, "Second Association request not received");
1915  NS_TEST_ASSERT_MSG_EQ(m_assocRespCount, 2, "Second Association response not received");
1917  10,
1918  "Incorrect operational channel width before channel change");
1920  20,
1921  "Incorrect operational channel width after channel change");
1922 }
1923 
1924 //-----------------------------------------------------------------------------
1941 {
1942  public:
1944  ~StaWifiMacScanningTestCase() override;
1945  void DoRun() override;
1946 
1947  private:
1953  void AssocCallback(std::string context, Mac48Address bssid);
1958  void TurnBeaconGenerationOn(Ptr<Node> apNode);
1963  void TurnApOff(Ptr<Node> apNode);
1970  NodeContainer Setup(bool nearestApBeaconGeneration, bool staActiveProbe);
1971 
1973 };
1974 
1976  : TestCase("Test case for StaWifiMac scanning capability")
1977 {
1978 }
1979 
1981 {
1982 }
1983 
1984 void
1986 {
1987  m_associatedApBssid = bssid;
1988 }
1989 
1990 void
1992 {
1993  Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice>(apNode->GetDevice(0));
1994  Ptr<ApWifiMac> mac = DynamicCast<ApWifiMac>(netDevice->GetMac());
1995  mac->SetAttribute("BeaconGeneration", BooleanValue(true));
1996 }
1997 
1998 void
2000 {
2001  Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice>(apNode->GetDevice(0));
2002  Ptr<WifiPhy> phy = netDevice->GetPhy();
2003  phy->SetOffMode();
2004 }
2005 
2007 StaWifiMacScanningTestCase::Setup(bool nearestApBeaconGeneration, bool staActiveProbe)
2008 {
2009  RngSeedManager::SetSeed(1);
2010  RngSeedManager::SetRun(1);
2011  int64_t streamNumber = 1;
2012 
2013  NodeContainer apNodes;
2014  apNodes.Create(2);
2015 
2016  Ptr<Node> apNodeNearest = CreateObject<Node>();
2017  Ptr<Node> staNode = CreateObject<Node>();
2018 
2020  YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
2021  phy.SetChannel(channel.Create());
2022 
2023  WifiHelper wifi;
2024  wifi.SetStandard(WIFI_STANDARD_80211n);
2025  wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager");
2026 
2028  NetDeviceContainer apDevice;
2029  NetDeviceContainer apDeviceNearest;
2030  mac.SetType("ns3::ApWifiMac", "BeaconGeneration", BooleanValue(true));
2031  apDevice = wifi.Install(phy, mac, apNodes);
2032  mac.SetType("ns3::ApWifiMac", "BeaconGeneration", BooleanValue(nearestApBeaconGeneration));
2033  apDeviceNearest = wifi.Install(phy, mac, apNodeNearest);
2034 
2035  NetDeviceContainer staDevice;
2036  mac.SetType("ns3::StaWifiMac", "ActiveProbing", BooleanValue(staActiveProbe));
2037  staDevice = wifi.Install(phy, mac, staNode);
2038 
2039  // Assign fixed streams to random variables in use
2040  wifi.AssignStreams(apDevice, streamNumber);
2041  wifi.AssignStreams(apDeviceNearest, streamNumber + 1);
2042  wifi.AssignStreams(staDevice, streamNumber + 2);
2043 
2045  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
2046  positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Furthest AP
2047  positionAlloc->Add(Vector(10.0, 0.0, 0.0)); // Second nearest AP
2048  positionAlloc->Add(Vector(5.0, 5.0, 0.0)); // Nearest AP
2049  positionAlloc->Add(Vector(6.0, 5.0, 0.0)); // STA
2050  mobility.SetPositionAllocator(positionAlloc);
2051 
2052  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2053  mobility.Install(apNodes);
2054  mobility.Install(apNodeNearest);
2055  mobility.Install(staNode);
2056 
2057  Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/Assoc",
2059 
2060  NodeContainer allNodes = NodeContainer(apNodes, apNodeNearest, staNode);
2061  return allNodes;
2062 }
2063 
2064 void
2066 {
2067  {
2068  NodeContainer nodes = Setup(false, false);
2069  Ptr<Node> nearestAp = nodes.Get(2);
2070  Mac48Address nearestApAddr =
2071  DynamicCast<WifiNetDevice>(nearestAp->GetDevice(0))->GetMac()->GetAddress();
2072 
2073  Simulator::Schedule(Seconds(0.05),
2075  this,
2076  nearestAp);
2077 
2078  Simulator::Stop(Seconds(0.2));
2079  Simulator::Run();
2080  Simulator::Destroy();
2081 
2083  nearestApAddr,
2084  "STA is associated to the wrong AP");
2085  }
2087  {
2088  NodeContainer nodes = Setup(true, true);
2089  Ptr<Node> nearestAp = nodes.Get(2);
2090  Mac48Address nearestApAddr =
2091  DynamicCast<WifiNetDevice>(nearestAp->GetDevice(0))->GetMac()->GetAddress();
2092 
2093  Simulator::Stop(Seconds(0.2));
2094  Simulator::Run();
2095  Simulator::Destroy();
2096 
2098  nearestApAddr,
2099  "STA is associated to the wrong AP");
2100  }
2102  {
2103  NodeContainer nodes = Setup(true, false);
2104  Ptr<Node> nearestAp = nodes.Get(2);
2105  Mac48Address secondNearestApAddr =
2106  DynamicCast<WifiNetDevice>(nodes.Get(1)->GetDevice(0))->GetMac()->GetAddress();
2107 
2108  Simulator::Schedule(Seconds(0.1), &StaWifiMacScanningTestCase::TurnApOff, this, nearestAp);
2109 
2110  Simulator::Stop(Seconds(1.5));
2111  Simulator::Run();
2112  Simulator::Destroy();
2113 
2115  secondNearestApAddr,
2116  "STA is associated to the wrong AP");
2117  }
2118 }
2119 
2120 //-----------------------------------------------------------------------------
2144 {
2145  public:
2146  Bug2470TestCase();
2147  ~Bug2470TestCase() override;
2148  void DoRun() override;
2149 
2150  private:
2159  void AddbaStateChangedCallback(std::string context,
2160  Time t,
2161  Mac48Address recipient,
2162  uint8_t tid,
2172  void TxCallback(Ptr<ListErrorModel> rxErrorModel,
2173  std::string context,
2174  WifiConstPsduMap psduMap,
2175  WifiTxVector txVector,
2176  double txPowerW);
2177 
2188  void RxCallback(std::string context,
2190  uint16_t channelFreqMhz,
2191  WifiTxVector txVector,
2192  MpduInfo aMpdu,
2193  SignalNoiseDbm signalNoise,
2194  uint16_t staId);
2201  void RxErrorCallback(std::string context, Ptr<const Packet> p, double snr);
2208  void SendPacketBurst(uint32_t numPackets,
2209  Ptr<NetDevice> sourceDevice,
2210  Address& destination) const;
2215  void RunSubtest(TypeOfStation rcvErrorType);
2216 
2223  uint16_t
2225  uint16_t
2228 };
2229 
2231  : TestCase("Test case for Bug 2470"),
2232  m_receivedNormalMpduCount(0),
2233  m_receivedAmpduCount(0),
2234  m_failedActionCount(0),
2235  m_addbaEstablishedCount(0),
2236  m_addbaPendingCount(0),
2237  m_addbaRejectedCount(0),
2238  m_addbaNoReplyCount(0),
2239  m_addbaResetCount(0)
2240 {
2241 }
2242 
2244 {
2245 }
2246 
2247 void
2249  Time t,
2250  Mac48Address recipient,
2251  uint8_t tid,
2253 {
2254  switch (state)
2255  {
2256  case OriginatorBlockAckAgreement::ESTABLISHED:
2258  break;
2259  case OriginatorBlockAckAgreement::PENDING:
2261  break;
2262  case OriginatorBlockAckAgreement::REJECTED:
2264  break;
2265  case OriginatorBlockAckAgreement::NO_REPLY:
2267  break;
2268  case OriginatorBlockAckAgreement::RESET:
2270  break;
2271  }
2272 }
2273 
2274 void
2276  std::string context,
2277  WifiConstPsduMap psduMap,
2278  WifiTxVector txVector,
2279  double txPowerW)
2280 {
2281  auto psdu = psduMap.begin()->second;
2282 
2283  // The sender is transmitting an ADDBA_REQUEST or ADDBA_RESPONSE frame. If this is
2284  // the first attempt at establishing a BA agreement (i.e., before the second set of packets
2285  // is generated), make the reception of the frame fail at the receiver.
2286  if (psdu->GetHeader(0).GetType() == WIFI_MAC_MGT_ACTION && Simulator::Now() < Seconds(0.8))
2287  {
2288  auto uid = psdu->GetPayload(0)->GetUid();
2289  rxErrorModel->SetList({uid});
2290  }
2291 }
2292 
2293 void
2294 Bug2470TestCase::RxCallback(std::string context,
2296  uint16_t channelFreqMhz,
2297  WifiTxVector txVector,
2298  MpduInfo aMpdu,
2299  SignalNoiseDbm signalNoise,
2300  uint16_t staId)
2301 {
2302  Ptr<Packet> packet = p->Copy();
2303  if (aMpdu.type != MpduType::NORMAL_MPDU)
2304  {
2306  }
2307  else
2308  {
2309  WifiMacHeader hdr;
2310  packet->RemoveHeader(hdr);
2311  if (hdr.IsData())
2312  {
2314  }
2315  }
2316 }
2317 
2318 void
2319 Bug2470TestCase::RxErrorCallback(std::string context, Ptr<const Packet> p, double snr)
2320 {
2321  Ptr<Packet> packet = p->Copy();
2322  WifiMacHeader hdr;
2323  packet->RemoveHeader(hdr);
2324  if (hdr.IsAction())
2325  {
2327  }
2328 }
2329 
2330 void
2332  Ptr<NetDevice> sourceDevice,
2333  Address& destination) const
2334 {
2335  for (uint32_t i = 0; i < numPackets; i++)
2336  {
2337  Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
2338  sourceDevice->Send(pkt, destination, 0);
2339  }
2340 }
2341 
2342 void
2344 {
2345  RngSeedManager::SetSeed(1);
2346  RngSeedManager::SetRun(1);
2347  int64_t streamNumber = 200;
2348 
2350  NodeContainer wifiStaNode;
2351  wifiApNode.Create(1);
2352  wifiStaNode.Create(1);
2353 
2355  YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
2356  phy.SetChannel(channel.Create());
2357 
2358  WifiHelper wifi;
2359  wifi.SetStandard(WIFI_STANDARD_80211n);
2360  wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
2361  "DataMode",
2362  StringValue("HtMcs7"),
2363  "ControlMode",
2364  StringValue("HtMcs7"));
2365 
2367  NetDeviceContainer apDevice;
2368  phy.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}"));
2369  mac.SetType("ns3::ApWifiMac", "EnableBeaconJitter", BooleanValue(false));
2370  apDevice = wifi.Install(phy, mac, wifiApNode);
2371 
2372  NetDeviceContainer staDevice;
2373  mac.SetType("ns3::StaWifiMac");
2374  staDevice = wifi.Install(phy, mac, wifiStaNode);
2375 
2376  // Assign fixed streams to random variables in use
2377  wifi.AssignStreams(apDevice, streamNumber);
2378  wifi.AssignStreams(staDevice, streamNumber);
2379 
2381  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
2382  positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2383  positionAlloc->Add(Vector(1.0, 0.0, 0.0));
2384  mobility.SetPositionAllocator(positionAlloc);
2385 
2386  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2387  mobility.Install(wifiApNode);
2388  mobility.Install(wifiStaNode);
2389 
2390  auto rxErrorModel = CreateObject<ListErrorModel>();
2391  Ptr<WifiMac> wifiMac;
2392  switch (rcvErrorType)
2393  {
2394  case AP:
2395  wifiMac = DynamicCast<WifiNetDevice>(apDevice.Get(0))->GetMac();
2396  break;
2397  case STA:
2398  wifiMac = DynamicCast<WifiNetDevice>(staDevice.Get(0))->GetMac();
2399  break;
2400  default:
2401  NS_ABORT_MSG("Station type " << +rcvErrorType << " cannot be used here");
2402  }
2403  wifiMac->GetWifiPhy(0)->SetPostReceptionErrorModel(rxErrorModel);
2404 
2406  "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/MonitorSnifferRx",
2408  Config::Connect("/NodeList/*/DeviceList/*/Phy/State/RxError",
2410  Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/BE_Txop/"
2411  "BlockAckManager/AgreementState",
2413  Config::Connect("/NodeList/" + std::to_string(rcvErrorType == STA ? 0 /* AP */ : 1 /* STA */) +
2414  "/DeviceList/*/$ns3::WifiNetDevice/Phys/0/PhyTxPsduBegin",
2415  MakeCallback(&Bug2470TestCase::TxCallback, this).Bind(rxErrorModel));
2416 
2417  Simulator::Schedule(Seconds(0.5),
2419  this,
2420  1,
2421  apDevice.Get(0),
2422  staDevice.Get(0)->GetAddress());
2423  Simulator::Schedule(Seconds(0.5) + MicroSeconds(5),
2425  this,
2426  4,
2427  apDevice.Get(0),
2428  staDevice.Get(0)->GetAddress());
2429  Simulator::Schedule(Seconds(0.8),
2431  this,
2432  1,
2433  apDevice.Get(0),
2434  staDevice.Get(0)->GetAddress());
2435  Simulator::Schedule(Seconds(0.8) + MicroSeconds(5),
2437  this,
2438  4,
2439  apDevice.Get(0),
2440  staDevice.Get(0)->GetAddress());
2441 
2442  Simulator::Stop(Seconds(1.0));
2443  Simulator::Run();
2444  Simulator::Destroy();
2445 }
2446 
2447 void
2449 {
2450  {
2451  RunSubtest(STA);
2452  NS_TEST_ASSERT_MSG_EQ(m_failedActionCount, 7, "ADDBA request packets are not failed");
2453  // There are two sets of 5 packets to be transmitted. The first 5 packets should be sent by
2454  // normal MPDU because of failed ADDBA handshake. For the second set, the first packet
2455  // should be sent by normal MPDU, and the rest with A-MPDU. In total we expect to receive 6
2456  // normal MPDU packets and 4 A-MPDU packet.
2458  6,
2459  "Receiving incorrect number of normal MPDU packet on subtest 1");
2461  4,
2462  "Receiving incorrect number of A-MPDU packets on subtest 1");
2463 
2465  1,
2466  "Incorrect number of times the ADDBA state machine was in "
2467  "established state on subtest 1");
2470  2,
2471  "Incorrect number of times the ADDBA state machine was in pending state on subtest 1");
2474  0,
2475  "Incorrect number of times the ADDBA state machine was in rejected state on subtest 1");
2478  1,
2479  "Incorrect number of times the ADDBA state machine was in no_reply state on subtest 1");
2482  1,
2483  "Incorrect number of times the ADDBA state machine was in reset state on subtest 1");
2484  }
2485 
2488  m_failedActionCount = 0;
2490  m_addbaPendingCount = 0;
2492  m_addbaNoReplyCount = 0;
2493  m_addbaResetCount = 0;
2494 
2495  {
2496  RunSubtest(AP);
2497  NS_TEST_ASSERT_MSG_EQ(m_failedActionCount, 7, "ADDBA response packets are not failed");
2498  // Similar to subtest 1, we also expect to receive 6 normal MPDU packets and 4 A-MPDU
2499  // packets.
2501  6,
2502  "Receiving incorrect number of normal MPDU packet on subtest 2");
2504  4,
2505  "Receiving incorrect number of A-MPDU packet on subtest 2");
2506 
2508  1,
2509  "Incorrect number of times the ADDBA state machine was in "
2510  "established state on subtest 2");
2513  2,
2514  "Incorrect number of times the ADDBA state machine was in pending state on subtest 2");
2517  0,
2518  "Incorrect number of times the ADDBA state machine was in rejected state on subtest 2");
2521  1,
2522  "Incorrect number of times the ADDBA state machine was in no_reply state on subtest 2");
2525  1,
2526  "Incorrect number of times the ADDBA state machine was in reset state on subtest 2");
2527  }
2528 
2529  // TODO: In the second test set, it does not go to reset state since ADDBA response is received
2530  // after timeout (NO_REPLY) but before it does not enter RESET state. More tests should be
2531  // written to verify all possible scenarios.
2532 }
2533 
2534 //-----------------------------------------------------------------------------
2550 {
2551  public:
2552  Issue40TestCase();
2553  ~Issue40TestCase() override;
2554  void DoRun() override;
2555 
2556  private:
2561  void RunOne(bool useAmpdu);
2562 
2568  void RxSuccessCallback(std::string context, Ptr<const Packet> p);
2575  void SendPackets(uint8_t numPackets, Ptr<NetDevice> sourceDevice, Address& destination);
2581  void TxFinalDataFailedCallback(std::string context, Mac48Address address);
2582 
2583  uint16_t m_rxCount;
2584  uint16_t m_txCount;
2585  uint16_t
2587 };
2588 
2590  : TestCase("Test case for issue #40"),
2591  m_rxCount(0),
2592  m_txCount(0),
2593  m_txMacFinalDataFailedCount(0)
2594 {
2595 }
2596 
2598 {
2599 }
2600 
2601 void
2603 {
2604  m_rxCount++;
2605 }
2606 
2607 void
2608 Issue40TestCase::SendPackets(uint8_t numPackets, Ptr<NetDevice> sourceDevice, Address& destination)
2609 {
2610  for (uint8_t i = 0; i < numPackets; i++)
2611  {
2612  Ptr<Packet> pkt = Create<Packet>(1000); // 1000 dummy bytes of data
2613  sourceDevice->Send(pkt, destination, 0);
2614  m_txCount++;
2615  }
2616 }
2617 
2618 void
2620 {
2622 }
2623 
2624 void
2626 {
2627  m_rxCount = 0;
2628  m_txCount = 0;
2630 
2631  RngSeedManager::SetSeed(1);
2632  RngSeedManager::SetRun(1);
2633  int64_t streamNumber = 100;
2634 
2636  NodeContainer wifiStaNode;
2637  wifiApNode.Create(1);
2638  wifiStaNode.Create(1);
2639 
2641  YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
2642  phy.SetChannel(channel.Create());
2643 
2644  WifiHelper wifi;
2645  wifi.SetStandard(WIFI_STANDARD_80211ac);
2646  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
2647 
2649  NetDeviceContainer apDevice;
2650  mac.SetType("ns3::ApWifiMac");
2651  apDevice = wifi.Install(phy, mac, wifiApNode);
2652 
2653  NetDeviceContainer staDevice;
2654  mac.SetType("ns3::StaWifiMac");
2655  staDevice = wifi.Install(phy, mac, wifiStaNode);
2656 
2657  // Assign fixed streams to random variables in use
2658  wifi.AssignStreams(apDevice, streamNumber);
2659  wifi.AssignStreams(staDevice, streamNumber);
2660 
2662  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
2663  positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2664  positionAlloc->Add(Vector(10.0, 0.0, 0.0));
2665  mobility.SetPositionAllocator(positionAlloc);
2666 
2667  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2668  mobility.Install(wifiApNode);
2669 
2670  mobility.SetMobilityModel("ns3::WaypointMobilityModel");
2671  mobility.Install(wifiStaNode);
2672 
2673  Config::Connect("/NodeList/*/DeviceList/*/RemoteStationManager/MacTxFinalDataFailed",
2675  Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/MacRx",
2677 
2678  Ptr<WaypointMobilityModel> staWaypointMobility =
2679  DynamicCast<WaypointMobilityModel>(wifiStaNode.Get(0)->GetObject<MobilityModel>());
2680  staWaypointMobility->AddWaypoint(Waypoint(Seconds(1.0), Vector(10.0, 0.0, 0.0)));
2681  staWaypointMobility->AddWaypoint(Waypoint(Seconds(1.5), Vector(50.0, 0.0, 0.0)));
2682 
2683  if (useAmpdu)
2684  {
2685  // Disable use of BAR that are sent with the lowest modulation so that we can also reproduce
2686  // the problem with A-MPDU, i.e. the lack of feedback about SNR change
2687  Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice>(apDevice.Get(0));
2688  PointerValue ptr;
2689  ap_device->GetMac()->GetAttribute("BE_Txop", ptr);
2690  ptr.Get<QosTxop>()->SetAttribute("UseExplicitBarAfterMissedBlockAck", BooleanValue(false));
2691  }
2692 
2693  // Transmit a first data packet before the station moves: it should be sent with a high
2694  // modulation and successfully received
2695  Simulator::Schedule(Seconds(0.5),
2697  this,
2698  useAmpdu ? 2 : 1,
2699  apDevice.Get(0),
2700  staDevice.Get(0)->GetAddress());
2701 
2702  // Transmit a second data packet once the station is away from the access point: it should be
2703  // sent with the same high modulation and be unsuccessfuly received
2704  Simulator::Schedule(Seconds(2.0),
2706  this,
2707  useAmpdu ? 2 : 1,
2708  apDevice.Get(0),
2709  staDevice.Get(0)->GetAddress());
2710 
2711  // Keep on transmitting data packets while the station is away from the access point: it should
2712  // be sent with a lower modulation and be successfully received
2713  Simulator::Schedule(Seconds(2.1),
2715  this,
2716  useAmpdu ? 2 : 1,
2717  apDevice.Get(0),
2718  staDevice.Get(0)->GetAddress());
2719  Simulator::Schedule(Seconds(2.2),
2721  this,
2722  useAmpdu ? 2 : 1,
2723  apDevice.Get(0),
2724  staDevice.Get(0)->GetAddress());
2725  Simulator::Schedule(Seconds(2.3),
2727  this,
2728  useAmpdu ? 2 : 1,
2729  apDevice.Get(0),
2730  staDevice.Get(0)->GetAddress());
2731  Simulator::Schedule(Seconds(2.4),
2733  this,
2734  useAmpdu ? 2 : 1,
2735  apDevice.Get(0),
2736  staDevice.Get(0)->GetAddress());
2737  Simulator::Schedule(Seconds(2.5),
2739  this,
2740  useAmpdu ? 2 : 1,
2741  apDevice.Get(0),
2742  staDevice.Get(0)->GetAddress());
2743 
2744  Simulator::Stop(Seconds(3.0));
2745  Simulator::Run();
2746 
2748  (useAmpdu ? 14 : 7),
2749  "Incorrect number of transmitted packets");
2751  (useAmpdu ? 12 : 6),
2752  "Incorrect number of successfully received packets");
2753  NS_TEST_ASSERT_MSG_EQ(m_txMacFinalDataFailedCount, 1, "Incorrect number of dropped TX packets");
2754 
2755  Simulator::Destroy();
2756 }
2757 
2758 void
2760 {
2761  // Test without A-MPDU
2762  RunOne(false);
2763 
2764  // Test with A-MPDU
2765  RunOne(true);
2766 }
2767 
2768 //-----------------------------------------------------------------------------
2782 {
2783  public:
2784  Issue169TestCase();
2785  ~Issue169TestCase() override;
2786  void DoRun() override;
2787 
2788  private:
2796  void SendPackets(uint8_t numPackets,
2797  Ptr<NetDevice> sourceDevice,
2798  Address& destination,
2799  uint8_t priority);
2800 
2808  void TxCallback(std::string context,
2809  WifiConstPsduMap psdus,
2810  WifiTxVector txVector,
2811  double txPowerW);
2812 };
2813 
2815  : TestCase("Test case for issue #169")
2816 {
2817 }
2818 
2820 {
2821 }
2822 
2823 void
2825  Ptr<NetDevice> sourceDevice,
2826  Address& destination,
2827  uint8_t priority)
2828 {
2829  SocketPriorityTag priorityTag;
2830  priorityTag.SetPriority(priority);
2831  for (uint8_t i = 0; i < numPackets; i++)
2832  {
2833  Ptr<Packet> packet = Create<Packet>(1000); // 1000 dummy bytes of data
2834  packet->AddPacketTag(priorityTag);
2835  sourceDevice->Send(packet, destination, 0);
2836  }
2837 }
2838 
2839 void
2840 Issue169TestCase::TxCallback(std::string context,
2841  WifiConstPsduMap psdus,
2842  WifiTxVector txVector,
2843  double txPowerW)
2844 {
2845  if (psdus.begin()->second->GetSize() >= 1000)
2846  {
2849  "Ideal rate manager selected incorrect modulation class");
2850  }
2851 }
2852 
2853 void
2855 {
2856  RngSeedManager::SetSeed(1);
2857  RngSeedManager::SetRun(1);
2858  int64_t streamNumber = 100;
2859 
2861  NodeContainer wifiStaNode;
2862  wifiApNode.Create(1);
2863  wifiStaNode.Create(1);
2864 
2866  YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
2867  phy.SetChannel(channel.Create());
2868 
2869  WifiHelper wifi;
2870  wifi.SetStandard(WIFI_STANDARD_80211ac);
2871  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
2872 
2874  NetDeviceContainer apDevice;
2875  mac.SetType("ns3::ApWifiMac");
2876  apDevice = wifi.Install(phy, mac, wifiApNode);
2877 
2878  NetDeviceContainer staDevice;
2879  mac.SetType("ns3::StaWifiMac");
2880  staDevice = wifi.Install(phy, mac, wifiStaNode);
2881 
2882  // Assign fixed streams to random variables in use
2883  wifi.AssignStreams(apDevice, streamNumber);
2884  wifi.AssignStreams(staDevice, streamNumber);
2885 
2887  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
2888  positionAlloc->Add(Vector(0.0, 0.0, 0.0));
2889  positionAlloc->Add(Vector(1.0, 0.0, 0.0));
2890  mobility.SetPositionAllocator(positionAlloc);
2891 
2892  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2893  mobility.Install(wifiApNode);
2894  mobility.Install(wifiStaNode);
2895 
2896  Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
2898 
2899  // Send best-effort packet (i.e. priority 0)
2900  Simulator::Schedule(Seconds(0.5),
2902  this,
2903  1,
2904  apDevice.Get(0),
2905  staDevice.Get(0)->GetAddress(),
2906  0);
2907 
2908  // Send non best-effort (voice) packet (i.e. priority 6)
2909  Simulator::Schedule(Seconds(1.0),
2911  this,
2912  1,
2913  apDevice.Get(0),
2914  staDevice.Get(0)->GetAddress(),
2915  6);
2916 
2917  Simulator::Stop(Seconds(2.0));
2918  Simulator::Run();
2919 
2920  Simulator::Destroy();
2921 }
2922 
2923 //-----------------------------------------------------------------------------
2939 {
2940  public:
2943  void DoRun() override;
2944 
2945  private:
2950  void ChangeChannelWidth(uint16_t channelWidth);
2951 
2957  void SendPacket(Ptr<NetDevice> sourceDevice, Address& destination);
2958 
2966  void TxCallback(std::string context,
2967  WifiConstPsduMap psduMap,
2968  WifiTxVector txVector,
2969  double txPowerW);
2970 
2975  void CheckLastSelectedMode(WifiMode expectedMode);
2976 
2978 };
2979 
2981  : TestCase("Test case for use of channel bonding with Ideal rate manager")
2982 {
2983 }
2984 
2986 {
2987 }
2988 
2989 void
2991 {
2992  Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelSettings",
2993  StringValue("{0, " + std::to_string(channelWidth) + ", BAND_5GHZ, 0}"));
2994 }
2995 
2996 void
2998 {
2999  Ptr<Packet> packet = Create<Packet>(1000);
3000  sourceDevice->Send(packet, destination, 0);
3001 }
3002 
3003 void
3005  WifiConstPsduMap psduMap,
3006  WifiTxVector txVector,
3007  double txPowerW)
3008 {
3009  if (psduMap.begin()->second->GetSize() >= 1000)
3010  {
3011  m_txMode = txVector.GetMode();
3012  }
3013 }
3014 
3015 void
3017 {
3019  expectedMode,
3020  "Last selected WifiMode "
3021  << m_txMode << " does not match expected WifiMode " << expectedMode);
3022 }
3023 
3024 void
3026 {
3027  RngSeedManager::SetSeed(1);
3028  RngSeedManager::SetRun(1);
3029  int64_t streamNumber = 100;
3030 
3032  NodeContainer wifiStaNode;
3033  wifiApNode.Create(1);
3034  wifiStaNode.Create(1);
3035 
3037  YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
3038  phy.SetChannel(channel.Create());
3039 
3040  WifiHelper wifi;
3041  wifi.SetStandard(WIFI_STANDARD_80211ac);
3042  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
3043 
3045  NetDeviceContainer apDevice;
3046  mac.SetType("ns3::ApWifiMac");
3047  apDevice = wifi.Install(phy, mac, wifiApNode);
3048 
3049  NetDeviceContainer staDevice;
3050  mac.SetType("ns3::StaWifiMac");
3051  staDevice = wifi.Install(phy, mac, wifiStaNode);
3052 
3053  // Assign fixed streams to random variables in use
3054  wifi.AssignStreams(apDevice, streamNumber);
3055  wifi.AssignStreams(staDevice, streamNumber);
3056 
3058  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
3059  positionAlloc->Add(Vector(0.0, 0.0, 0.0));
3060  positionAlloc->Add(Vector(50.0, 0.0, 0.0));
3061  mobility.SetPositionAllocator(positionAlloc);
3062 
3063  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
3064  mobility.Install(wifiApNode);
3065  mobility.Install(wifiStaNode);
3066 
3067  Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
3069 
3070  // Set channel width to 80 MHz & send packet
3071  Simulator::Schedule(Seconds(0.5),
3073  this,
3074  80);
3075  Simulator::Schedule(Seconds(1.0),
3077  this,
3078  apDevice.Get(0),
3079  staDevice.Get(0)->GetAddress());
3080  // Selected rate should be VHT-MCS 1
3081  Simulator::Schedule(Seconds(1.1),
3083  this,
3084  VhtPhy::GetVhtMcs1());
3085 
3086  // Set channel width to 20 MHz & send packet
3087  Simulator::Schedule(Seconds(1.5),
3089  this,
3090  20);
3091  Simulator::Schedule(Seconds(2.0),
3093  this,
3094  apDevice.Get(0),
3095  staDevice.Get(0)->GetAddress());
3096  // Selected rate should be VHT-MCS 3 since SNR should be 6 dB higher than previously
3097  Simulator::Schedule(Seconds(2.1),
3099  this,
3100  VhtPhy::GetVhtMcs3());
3101 
3102  // Set channel width to 40 MHz & send packet
3103  Simulator::Schedule(Seconds(2.5),
3105  this,
3106  40);
3107  Simulator::Schedule(Seconds(3.0),
3109  this,
3110  apDevice.Get(0),
3111  staDevice.Get(0)->GetAddress());
3112  // Selected rate should be VHT-MCS 2 since SNR should be 3 dB lower than previously
3113  Simulator::Schedule(Seconds(3.1),
3115  this,
3116  VhtPhy::GetVhtMcs2());
3117 
3118  Simulator::Stop(Seconds(3.2));
3119  Simulator::Run();
3120 
3121  Simulator::Destroy();
3122 }
3123 
3124 //-----------------------------------------------------------------------------
3134 {
3135  public:
3137  ~IdealRateManagerMimoTest() override;
3138  void DoRun() override;
3139 
3140  private:
3146  void SetApMimoSettings(uint8_t antennas, uint8_t maxStreams);
3152  void SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams);
3158  void SendPacket(Ptr<NetDevice> sourceDevice, Address& destination);
3159 
3167  void TxCallback(std::string context,
3168  WifiConstPsduMap psdus,
3169  WifiTxVector txVector,
3170  double txPowerW);
3171 
3176  void CheckLastSelectedMode(WifiMode expectedMode);
3181  void CheckLastSelectedNss(uint8_t expectedNss);
3182 
3184 };
3185 
3187  : TestCase("Test case for use of imbalanced MIMO settings with Ideal rate manager")
3188 {
3189 }
3190 
3192 {
3193 }
3194 
3195 void
3196 IdealRateManagerMimoTest::SetApMimoSettings(uint8_t antennas, uint8_t maxStreams)
3197 {
3198  Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/Antennas",
3199  UintegerValue(antennas));
3200  Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedTxSpatialStreams",
3201  UintegerValue(maxStreams));
3202  Config::Set("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedRxSpatialStreams",
3203  UintegerValue(maxStreams));
3204 }
3205 
3206 void
3207 IdealRateManagerMimoTest::SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams)
3208 {
3209  Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/Antennas",
3210  UintegerValue(antennas));
3211  Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedTxSpatialStreams",
3212  UintegerValue(maxStreams));
3213  Config::Set("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/MaxSupportedRxSpatialStreams",
3214  UintegerValue(maxStreams));
3215 }
3216 
3217 void
3219 {
3220  Ptr<Packet> packet = Create<Packet>(1000);
3221  sourceDevice->Send(packet, destination, 0);
3222 }
3223 
3224 void
3226  WifiConstPsduMap psdus,
3227  WifiTxVector txVector,
3228  double txPowerW)
3229 {
3230  if (psdus.begin()->second->GetSize() >= 1000)
3231  {
3232  m_txVector = txVector;
3233  }
3234 }
3235 
3236 void
3238 {
3240  expectedNss,
3241  "Last selected Nss " << m_txVector.GetNss()
3242  << " does not match expected Nss " << expectedNss);
3243 }
3244 
3245 void
3247 {
3249  expectedMode,
3250  "Last selected WifiMode " << m_txVector.GetMode()
3251  << " does not match expected WifiMode "
3252  << expectedMode);
3253 }
3254 
3255 void
3257 {
3258  RngSeedManager::SetSeed(1);
3259  RngSeedManager::SetRun(1);
3260  int64_t streamNumber = 100;
3261 
3263  NodeContainer wifiStaNode;
3264  wifiApNode.Create(1);
3265  wifiStaNode.Create(1);
3266 
3268  YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
3269  phy.SetChannel(channel.Create());
3270 
3271  WifiHelper wifi;
3272  wifi.SetStandard(WIFI_STANDARD_80211ac);
3273  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
3274 
3276  NetDeviceContainer apDevice;
3277  mac.SetType("ns3::ApWifiMac");
3278  apDevice = wifi.Install(phy, mac, wifiApNode);
3279 
3280  NetDeviceContainer staDevice;
3281  mac.SetType("ns3::StaWifiMac");
3282  staDevice = wifi.Install(phy, mac, wifiStaNode);
3283 
3284  // Assign fixed streams to random variables in use
3285  wifi.AssignStreams(apDevice, streamNumber);
3286  wifi.AssignStreams(staDevice, streamNumber);
3287 
3289  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
3290  positionAlloc->Add(Vector(0.0, 0.0, 0.0));
3291  positionAlloc->Add(Vector(40.0, 0.0, 0.0));
3292  mobility.SetPositionAllocator(positionAlloc);
3293 
3294  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
3295  mobility.Install(wifiApNode);
3296  mobility.Install(wifiStaNode);
3297 
3298  Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxPsduBegin",
3300 
3301  // TX: 1 antenna
3302  Simulator::Schedule(Seconds(0.9), &IdealRateManagerMimoTest::SetApMimoSettings, this, 1, 1);
3303  // RX: 1 antenna
3304  Simulator::Schedule(Seconds(0.9), &IdealRateManagerMimoTest::SetStaMimoSettings, this, 1, 1);
3305  // Send packets (2 times to get one feedback)
3306  Simulator::Schedule(Seconds(1.0),
3308  this,
3309  apDevice.Get(0),
3310  staDevice.Get(0)->GetAddress());
3311  Simulator::Schedule(Seconds(1.1),
3313  this,
3314  apDevice.Get(0),
3315  staDevice.Get(0)->GetAddress());
3316  // Selected NSS should be 1 since both TX and RX support a single antenna
3317  Simulator::Schedule(Seconds(1.2), &IdealRateManagerMimoTest::CheckLastSelectedNss, this, 1);
3318  // Selected rate should be VHT-MCS 2 because of settings and distance between TX and RX
3319  Simulator::Schedule(Seconds(1.2),
3321  this,
3322  VhtPhy::GetVhtMcs2());
3323 
3324  // TX: 1 antenna
3325  Simulator::Schedule(Seconds(1.9), &IdealRateManagerMimoTest::SetApMimoSettings, this, 1, 1);
3326  // RX: 2 antennas, but only supports 1 spatial stream
3327  Simulator::Schedule(Seconds(1.9), &IdealRateManagerMimoTest::SetStaMimoSettings, this, 2, 1);
3328  // Send packets (2 times to get one feedback)
3329  Simulator::Schedule(Seconds(2.0),
3331  this,
3332  apDevice.Get(0),
3333  staDevice.Get(0)->GetAddress());
3334  Simulator::Schedule(Seconds(2.1),
3336  this,
3337  apDevice.Get(0),
3338  staDevice.Get(0)->GetAddress());
3339  // Selected NSS should be 1 since both TX and RX support a single antenna
3340  Simulator::Schedule(Seconds(2.2), &IdealRateManagerMimoTest::CheckLastSelectedNss, this, 1);
3341  // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3342  // improvement of about 3dB
3343  Simulator::Schedule(Seconds(2.2),
3345  this,
3346  VhtPhy::GetVhtMcs3());
3347 
3348  // TX: 1 antenna
3349  Simulator::Schedule(Seconds(2.9), &IdealRateManagerMimoTest::SetApMimoSettings, this, 1, 1);
3350  // RX: 2 antennas, and supports 2 spatial streams
3351  Simulator::Schedule(Seconds(2.9), &IdealRateManagerMimoTest::SetStaMimoSettings, this, 2, 2);
3352  // Send packets (2 times to get one feedback)
3353  Simulator::Schedule(Seconds(3.0),
3355  this,
3356  apDevice.Get(0),
3357  staDevice.Get(0)->GetAddress());
3358  Simulator::Schedule(Seconds(3.1),
3360  this,
3361  apDevice.Get(0),
3362  staDevice.Get(0)->GetAddress());
3363  // Selected NSS should be 1 since TX supports a single antenna
3364  Simulator::Schedule(Seconds(3.2), &IdealRateManagerMimoTest::CheckLastSelectedNss, this, 1);
3365  // Selected rate should be as previously
3366  Simulator::Schedule(Seconds(3.2),
3368  this,
3369  VhtPhy::GetVhtMcs3());
3370 
3371  // TX: 2 antennas, but only supports 1 spatial stream
3372  Simulator::Schedule(Seconds(3.9), &IdealRateManagerMimoTest::SetApMimoSettings, this, 2, 1);
3373  // RX: 1 antenna
3374  Simulator::Schedule(Seconds(3.9), &IdealRateManagerMimoTest::SetStaMimoSettings, this, 1, 1);
3375  // Send packets (2 times to get one feedback)
3376  Simulator::Schedule(Seconds(4.0),
3378  this,
3379  apDevice.Get(0),
3380  staDevice.Get(0)->GetAddress());
3381  Simulator::Schedule(Seconds(4.1),
3383  this,
3384  apDevice.Get(0),
3385  staDevice.Get(0)->GetAddress());
3386  // Selected NSS should be 1 since both TX and RX support a single antenna
3387  Simulator::Schedule(Seconds(4.2), &IdealRateManagerMimoTest::CheckLastSelectedNss, this, 1);
3388  // Selected rate should be VHT-MCS 2 because we do no longer have diversity in this scenario
3389  // (more antennas at TX does not result in SNR improvement in AWGN channel)
3390  Simulator::Schedule(Seconds(4.2),
3392  this,
3393  VhtPhy::GetVhtMcs2());
3394 
3395  // TX: 2 antennas, but only supports 1 spatial stream
3396  Simulator::Schedule(Seconds(4.9), &IdealRateManagerMimoTest::SetApMimoSettings, this, 2, 1);
3397  // RX: 2 antennas, but only supports 1 spatial stream
3398  Simulator::Schedule(Seconds(4.9), &IdealRateManagerMimoTest::SetStaMimoSettings, this, 2, 1);
3399  // Send packets (2 times to get one feedback)
3400  Simulator::Schedule(Seconds(5.0),
3402  this,
3403  apDevice.Get(0),
3404  staDevice.Get(0)->GetAddress());
3405  Simulator::Schedule(Seconds(5.1),
3407  this,
3408  apDevice.Get(0),
3409  staDevice.Get(0)->GetAddress());
3410  // Selected NSS should be 1 since both TX and RX support a single antenna
3411  Simulator::Schedule(Seconds(5.2), &IdealRateManagerMimoTest::CheckLastSelectedNss, this, 1);
3412  // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3413  // improvement of about 3dB (more antennas at TX does not result in SNR improvement in AWGN
3414  // channel)
3415  Simulator::Schedule(Seconds(5.2),
3417  this,
3418  VhtPhy::GetVhtMcs3());
3419 
3420  // TX: 2 antennas, but only supports 1 spatial stream
3421  Simulator::Schedule(Seconds(5.9), &IdealRateManagerMimoTest::SetApMimoSettings, this, 2, 1);
3422  // RX: 2 antennas, and supports 2 spatial streams
3423  Simulator::Schedule(Seconds(5.9), &IdealRateManagerMimoTest::SetStaMimoSettings, this, 2, 2);
3424  // Send packets (2 times to get one feedback)
3425  Simulator::Schedule(Seconds(6.0),
3427  this,
3428  apDevice.Get(0),
3429  staDevice.Get(0)->GetAddress());
3430  Simulator::Schedule(Seconds(6.1),
3432  this,
3433  apDevice.Get(0),
3434  staDevice.Get(0)->GetAddress());
3435  // Selected NSS should be 1 since TX supports a single antenna
3436  Simulator::Schedule(Seconds(6.2), &IdealRateManagerMimoTest::CheckLastSelectedNss, this, 1);
3437  // Selected rate should be as previously
3438  Simulator::Schedule(Seconds(6.2),
3440  this,
3441  VhtPhy::GetVhtMcs3());
3442 
3443  // TX: 2 antennas, and supports 2 spatial streams
3444  Simulator::Schedule(Seconds(6.9), &IdealRateManagerMimoTest::SetApMimoSettings, this, 2, 2);
3445  // RX: 1 antenna
3446  Simulator::Schedule(Seconds(6.9), &IdealRateManagerMimoTest::SetStaMimoSettings, this, 1, 1);
3447  // Send packets (2 times to get one feedback)
3448  Simulator::Schedule(Seconds(7.0),
3450  this,
3451  apDevice.Get(0),
3452  staDevice.Get(0)->GetAddress());
3453  Simulator::Schedule(Seconds(7.1),
3455  this,
3456  apDevice.Get(0),
3457  staDevice.Get(0)->GetAddress());
3458  // Selected NSS should be 1 since RX supports a single antenna
3459  Simulator::Schedule(Seconds(7.2), &IdealRateManagerMimoTest::CheckLastSelectedNss, this, 1);
3460  // Selected rate should be VHT-MCS 2 because we do no longer have diversity in this scenario
3461  // (more antennas at TX does not result in SNR improvement in AWGN channel)
3462  Simulator::Schedule(Seconds(7.2),
3464  this,
3465  VhtPhy::GetVhtMcs2());
3466 
3467  // TX: 2 antennas, and supports 2 spatial streams
3468  Simulator::Schedule(Seconds(7.9), &IdealRateManagerMimoTest::SetApMimoSettings, this, 2, 2);
3469  // RX: 2 antennas, but only supports 1 spatial stream
3470  Simulator::Schedule(Seconds(7.9), &IdealRateManagerMimoTest::SetStaMimoSettings, this, 2, 1);
3471  // Send packets (2 times to get one feedback)
3472  Simulator::Schedule(Seconds(8.0),
3474  this,
3475  apDevice.Get(0),
3476  staDevice.Get(0)->GetAddress());
3477  Simulator::Schedule(Seconds(8.1),
3479  this,
3480  apDevice.Get(0),
3481  staDevice.Get(0)->GetAddress());
3482  // Selected NSS should be 1 since RX supports a single antenna
3483  Simulator::Schedule(Seconds(8.2), &IdealRateManagerMimoTest::CheckLastSelectedNss, this, 1);
3484  // Selected rate should be increased to VHT-MCS 3 because of RX diversity resulting in SNR
3485  // improvement of about 3dB (more antennas at TX does not result in SNR improvement in AWGN
3486  // channel)
3487  Simulator::Schedule(Seconds(8.2),
3489  this,
3490  VhtPhy::GetVhtMcs3());
3491 
3492  // TX: 2 antennas, and supports 2 spatial streams
3493  Simulator::Schedule(Seconds(8.9), &IdealRateManagerMimoTest::SetApMimoSettings, this, 2, 2);
3494  // RX: 2 antennas, and supports 2 spatial streams
3495  Simulator::Schedule(Seconds(8.9), &IdealRateManagerMimoTest::SetStaMimoSettings, this, 2, 2);
3496  // Send packets (2 times to get one feedback)
3497  Simulator::Schedule(Seconds(9.0),
3499  this,
3500  apDevice.Get(0),
3501  staDevice.Get(0)->GetAddress());
3502  Simulator::Schedule(Seconds(9.1),
3504  this,
3505  apDevice.Get(0),
3506  staDevice.Get(0)->GetAddress());
3507  // Selected NSS should be 2 since both TX and RX support 2 antennas
3508  Simulator::Schedule(Seconds(9.2), &IdealRateManagerMimoTest::CheckLastSelectedNss, this, 2);
3509  // Selected rate should be the same as without diversity, as it uses 2 spatial streams so there
3510  // is no more benefits from diversity in AWGN channels
3511  Simulator::Schedule(Seconds(9.2),
3513  this,
3514  VhtPhy::GetVhtMcs2());
3515 
3516  // Verify we can go back to initial situation
3517  Simulator::Schedule(Seconds(9.9), &IdealRateManagerMimoTest::SetApMimoSettings, this, 1, 1);
3518  Simulator::Schedule(Seconds(9.9), &IdealRateManagerMimoTest::SetStaMimoSettings, this, 1, 1);
3519  Simulator::Schedule(Seconds(10.0),
3521  this,
3522  apDevice.Get(0),
3523  staDevice.Get(0)->GetAddress());
3524  Simulator::Schedule(Seconds(10.1), &IdealRateManagerMimoTest::CheckLastSelectedNss, this, 1);
3525  Simulator::Schedule(Seconds(10.1),
3527  this,
3528  VhtPhy::GetVhtMcs2());
3529 
3530  Simulator::Stop(Seconds(10.2));
3531  Simulator::Run();
3532  Simulator::Destroy();
3533 }
3534 
3535 //-----------------------------------------------------------------------------
3543 {
3544  public:
3546 
3547  private:
3558  bool CheckDataRate(HeRu::RuType ruType,
3559  std::string mcs,
3560  uint8_t nss,
3561  uint16_t guardInterval,
3562  uint16_t expectedDataRate);
3563  void DoRun() override;
3564 };
3565 
3567  : TestCase("Check data rates for different RU types.")
3568 {
3569 }
3570 
3571 bool
3573  std::string mcs,
3574  uint8_t nss,
3575  uint16_t guardInterval,
3576  uint16_t expectedDataRate)
3577 {
3578  uint16_t approxWidth = HeRu::GetBandwidth(ruType);
3579  WifiMode mode(mcs);
3580  uint64_t dataRate = round(mode.GetDataRate(approxWidth, guardInterval, nss) / 100000.0);
3581  NS_ABORT_MSG_IF(dataRate > 65535, "Rate is way too high");
3582  if (static_cast<uint16_t>(dataRate) != expectedDataRate)
3583  {
3584  std::cerr << "RU=" << ruType << " mode=" << mode << " Nss=" << +nss
3585  << " guardInterval=" << guardInterval << " expected=" << expectedDataRate
3586  << " x100kbps"
3587  << " computed=" << static_cast<uint16_t>(dataRate) << " x100kbps" << std::endl;
3588  return false;
3589  }
3590  return true;
3591 }
3592 
3593 void
3595 {
3596  bool retval = true;
3597 
3598  // 26-tone RU, browse over all MCSs, GIs and Nss's (up to 4, current max)
3599  retval = retval && CheckDataRate(HeRu::RU_26_TONE, "HeMcs0", 1, 800, 9) &&
3600  CheckDataRate(HeRu::RU_26_TONE, "HeMcs1", 1, 1600, 17) &&
3601  CheckDataRate(HeRu::RU_26_TONE, "HeMcs2", 1, 3200, 23) &&
3602  CheckDataRate(HeRu::RU_26_TONE, "HeMcs3", 1, 3200, 30) &&
3603  CheckDataRate(HeRu::RU_26_TONE, "HeMcs4", 2, 1600, 100) &&
3604  CheckDataRate(HeRu::RU_26_TONE, "HeMcs5", 3, 1600, 200) &&
3605  CheckDataRate(HeRu::RU_26_TONE, "HeMcs6", 4, 1600, 300) &&
3606  CheckDataRate(HeRu::RU_26_TONE, "HeMcs7", 4, 3200, 300) &&
3607  CheckDataRate(HeRu::RU_26_TONE, "HeMcs8", 4, 1600, 400) &&
3608  CheckDataRate(HeRu::RU_26_TONE, "HeMcs9", 4, 3200, 400) &&
3609  CheckDataRate(HeRu::RU_26_TONE, "HeMcs10", 4, 1600, 500) &&
3610  CheckDataRate(HeRu::RU_26_TONE, "HeMcs11", 4, 3200, 500);
3611 
3613  retval,
3614  true,
3615  "26-tone RU data rate verification for different MCSs, GIs, and Nss's failed");
3616 
3617  // Check other RU sizes
3618  retval = retval && CheckDataRate(HeRu::RU_52_TONE, "HeMcs2", 1, 1600, 50) &&
3619  CheckDataRate(HeRu::RU_106_TONE, "HeMcs9", 1, 800, 500) &&
3620  CheckDataRate(HeRu::RU_242_TONE, "HeMcs5", 1, 1600, 650) &&
3621  CheckDataRate(HeRu::RU_484_TONE, "HeMcs3", 1, 1600, 650) &&
3622  CheckDataRate(HeRu::RU_996_TONE, "HeMcs5", 1, 3200, 2450) &&
3623  CheckDataRate(HeRu::RU_2x996_TONE, "HeMcs3", 1, 3200, 2450);
3624 
3625  NS_TEST_EXPECT_MSG_EQ(retval,
3626  true,
3627  "Data rate verification for RUs above 52-tone RU (included) failed");
3628 }
3629 
3632  std::tuple<SupportedRates, std::optional<ExtendedSupportedRatesIE>, std::vector<Ssid>>;
3633 
3640 class MgtTestHeader : public WifiMgtHeader<MgtTestHeader, MgtTestElems>
3641 {
3642  public:
3643  ~MgtTestHeader() override = default;
3644 
3649  static TypeId GetTypeId();
3650 
3654  TypeId GetInstanceTypeId() const override;
3655 
3659 };
3660 
3661 TypeId
3663 {
3664  static TypeId tid = TypeId("ns3::MgtTestHeader")
3665  .SetParent<Header>()
3666  .SetGroupName("Wifi")
3667  .AddConstructor<MgtTestHeader>();
3668  return tid;
3669 }
3670 
3671 TypeId
3673 {
3674  return GetTypeId();
3675 }
3676 
3684 {
3685  public:
3687  ~WifiMgtHeaderTest() override = default;
3688 
3689  private:
3690  void DoRun() override;
3691 };
3692 
3694  : HeaderSerializationTestCase("Check (de)serialization of a test management header")
3695 {
3696 }
3697 
3698 void
3700 {
3701  MgtTestHeader frame;
3702 
3703  // Add the mandatory Information Element (SupportedRates)
3704  AllSupportedRates allRates;
3705  allRates.AddSupportedRate(1000000);
3706  allRates.AddSupportedRate(2000000);
3707  allRates.AddSupportedRate(3000000);
3708  allRates.AddSupportedRate(4000000);
3709  allRates.AddSupportedRate(5000000);
3710 
3711  frame.Get<SupportedRates>() = allRates.rates;
3712  frame.Get<ExtendedSupportedRatesIE>() = allRates.extendedRates;
3713 
3714  NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3715  true,
3716  "Expected a SupportedRates IE to be included");
3717  NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3718  false,
3719  "Expected no ExtendedSupportedRatesIE to be included");
3720  NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 0, "Expected no Ssid IE to be included");
3721 
3722  TestHeaderSerialization(frame);
3723 
3724  // Add more rates, so that the optional Information Element (ExtendedSupportedRatesIE) is added
3725  allRates.AddSupportedRate(6000000);
3726  allRates.AddSupportedRate(7000000);
3727  allRates.AddSupportedRate(8000000);
3728  allRates.AddSupportedRate(9000000);
3729  allRates.AddSupportedRate(10000000);
3730 
3731  frame.Get<SupportedRates>() = allRates.rates;
3732  frame.Get<ExtendedSupportedRatesIE>() = allRates.extendedRates;
3733 
3734  NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3735  true,
3736  "Expected a SupportedRates IE to be included");
3737  NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3738  true,
3739  "Expected an ExtendedSupportedRatesIE to be included");
3740  NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 0, "Expected no Ssid IE to be included");
3741 
3742  TestHeaderSerialization(frame);
3743 
3744  // Add a first Ssid IE
3745  Ssid one("Ssid One");
3746  frame.Get<Ssid>().push_back(one);
3747 
3748  NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3749  true,
3750  "Expected a SupportedRates IE to be included");
3751  NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3752  true,
3753  "Expected an ExtendedSupportedRatesIE to be included");
3754  NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 1, "Expected one Ssid IE to be included");
3755  NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().front().PeekString()),
3756  "Ssid One",
3757  "Incorrect SSID");
3758 
3759  TestHeaderSerialization(frame);
3760 
3761  // Add a second Ssid IE
3762  frame.Get<Ssid>().emplace_back("Ssid Two");
3763 
3764  NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
3765  true,
3766  "Expected a SupportedRates IE to be included");
3767  NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
3768  true,
3769  "Expected an ExtendedSupportedRatesIE to be included");
3770  NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().size(), 2, "Expected two Ssid IEs to be included");
3771  NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().front().PeekString()),
3772  "Ssid One",
3773  "Incorrect first SSID");
3774  NS_TEST_EXPECT_MSG_EQ(std::string(frame.Get<Ssid>().back().PeekString()),
3775  "Ssid Two",
3776  "Incorrect second SSID");
3777 
3778  TestHeaderSerialization(frame);
3779 }
3780 
3787 class WifiTestSuite : public TestSuite
3788 {
3789  public:
3790  WifiTestSuite();
3791 };
3792 
3794  : TestSuite("wifi-devices", UNIT)
3795 {
3796  AddTestCase(new WifiTest, TestCase::QUICK);
3797  AddTestCase(new QosUtilsIsOldPacketTest, TestCase::QUICK);
3798  AddTestCase(new InterferenceHelperSequenceTest, TestCase::QUICK); // Bug 991
3799  AddTestCase(new DcfImmediateAccessBroadcastTestCase, TestCase::QUICK);
3800  AddTestCase(new Bug730TestCase, TestCase::QUICK); // Bug 730
3801  AddTestCase(new QosFragmentationTestCase, TestCase::QUICK);
3802  AddTestCase(new SetChannelFrequencyTest, TestCase::QUICK);
3803  AddTestCase(new Bug2222TestCase, TestCase::QUICK); // Bug 2222
3804  AddTestCase(new Bug2843TestCase, TestCase::QUICK); // Bug 2843
3805  AddTestCase(new Bug2831TestCase, TestCase::QUICK); // Bug 2831
3806  AddTestCase(new StaWifiMacScanningTestCase, TestCase::QUICK); // Bug 2399
3807  AddTestCase(new Bug2470TestCase, TestCase::QUICK); // Bug 2470
3808  AddTestCase(new Issue40TestCase, TestCase::QUICK); // Issue #40
3809  AddTestCase(new Issue169TestCase, TestCase::QUICK); // Issue #169
3810  AddTestCase(new IdealRateManagerChannelWidthTest, TestCase::QUICK);
3811  AddTestCase(new IdealRateManagerMimoTest, TestCase::QUICK);
3812  AddTestCase(new HeRuMcsDataRateTestCase, TestCase::QUICK);
3813  AddTestCase(new WifiMgtHeaderTest, TestCase::QUICK);
3814 }
3815 
Make sure that when virtual collision occurs the wifi remote station manager is triggered and the ret...
Definition: wifi-test.cc:1373
~Bug2222TestCase() override
Definition: wifi-test.cc:1397
uint32_t m_countInternalCollisions
count internal collisions
Definition: wifi-test.cc:1381
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:1409
void TxDataFailedTrace(std::string context, Mac48Address adr)
Transmit data failed function.
Definition: wifi-test.cc:1402
Make sure that the ADDBA handshake process is protected.
Definition: wifi-test.cc:2144
void RxErrorCallback(std::string context, Ptr< const Packet > p, double snr)
Callback when packet is dropped.
Definition: wifi-test.cc:2319
void RunSubtest(TypeOfStation rcvErrorType)
Run subtest for this test suite.
Definition: wifi-test.cc:2343
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:2448
uint16_t m_addbaResetCount
Count number of times ADDBA state machine is in reset state.
Definition: wifi-test.cc:2227
uint16_t m_addbaRejectedCount
Count number of times ADDBA state machine is in rejected state.
Definition: wifi-test.cc:2224
void AddbaStateChangedCallback(std::string context, Time t, Mac48Address recipient, uint8_t tid, OriginatorBlockAckAgreement::State state)
Callback when ADDBA state changed.
Definition: wifi-test.cc:2248
uint16_t m_failedActionCount
Count failed ADDBA request/response.
Definition: wifi-test.cc:2219
void TxCallback(Ptr< ListErrorModel > rxErrorModel, std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback when a frame is transmitted.
Definition: wifi-test.cc:2275
uint16_t m_addbaEstablishedCount
Count number of times ADDBA state machine is in established state.
Definition: wifi-test.cc:2220
void RxCallback(std::string context, Ptr< const Packet > p, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise, uint16_t staId)
Callback when packet is received.
Definition: wifi-test.cc:2294
~Bug2470TestCase() override
Definition: wifi-test.cc:2243
uint16_t m_receivedNormalMpduCount
Count received normal MPDU packets on STA.
Definition: wifi-test.cc:2217
uint16_t m_addbaNoReplyCount
Count number of times ADDBA state machine is in no_reply state.
Definition: wifi-test.cc:2226
uint16_t m_addbaPendingCount
Count number of times ADDBA state machine is in pending state.
Definition: wifi-test.cc:2222
void SendPacketBurst(uint32_t numPackets, Ptr< NetDevice > sourceDevice, Address &destination) const
Triggers the arrival of a burst of 1000 Byte-long packets in the source device.
Definition: wifi-test.cc:2331
uint16_t m_receivedAmpduCount
Count received A-MPDU packets on STA.
Definition: wifi-test.cc:2218
Make sure that the channel width and the channel number can be changed at runtime.
Definition: wifi-test.cc:1729
uint16_t m_countOperationalChannelWidth20
count number of beacon frames announcing a 20 MHz operating channel width
Definition: wifi-test.cc:1753
void ChangeSupportedChannelWidth()
Function called to change the supported channel width at runtime.
Definition: wifi-test.cc:1773
uint16_t m_countOperationalChannelWidth40
count number of beacon frames announcing a 40 MHz operating channel width
Definition: wifi-test.cc:1755
void RxCallback(std::string context, Ptr< const Packet > p, RxPowerWattPerChannelBand rxPowersW)
Callback triggered when a packet is received by the PHYs.
Definition: wifi-test.cc:1780
uint16_t m_assocReqCount
count number of association requests
Definition: wifi-test.cc:1751
Ptr< YansWifiPhy > m_apPhy
AP PHY.
Definition: wifi-test.cc:1748
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:1812
Ptr< YansWifiPhy > m_staPhy
STA PHY.
Definition: wifi-test.cc:1749
uint16_t m_assocRespCount
count number of association responses
Definition: wifi-test.cc:1752
~Bug2831TestCase() override
Definition: wifi-test.cc:1768
Make sure that the correct channel width and center frequency have been set for OFDM basic rate trans...
Definition: wifi-test.cc:1513
void SendPacketBurst(uint8_t numPackets, Ptr< NetDevice > sourceDevice, Address &destination) const
Triggers the arrival of a burst of 1000 Byte-long packets in the source device.
Definition: wifi-test.cc:1595
void StoreDistinctTuple(std::string context, Ptr< SpectrumSignalParameters > txParams)
Stores the distinct {starting frequency, channelWidth, Number of subbands in SpectrumModel,...
Definition: wifi-test.cc:1561
std::vector< FreqWidthSubbandModulationTuple > m_distinctTuples
vector of distinct {starting frequency, channelWidth, Number of subbands in SpectrumModel,...
Definition: wifi-test.cc:1527
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:1607
uint16_t m_channelWidth
channel width (in MHz)
Definition: wifi-test.cc:1547
~Bug2843TestCase() override
Definition: wifi-test.cc:1556
std::tuple< double, uint16_t, uint32_t, WifiModulationClass > FreqWidthSubbandModulationTuple
A tuple of {starting frequency, channelWidth, Number of subbands in SpectrumModel,...
Definition: wifi-test.cc:1525
Make sure that when changing the fragmentation threshold during the simulation, the TCP transmission ...
Definition: wifi-test.cc:644
~Bug730TestCase() override
Definition: wifi-test.cc:669
void Receive(std::string context, Ptr< const Packet > p, const Address &adr)
Receive function.
Definition: wifi-test.cc:674
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:683
uint32_t m_received
received
Definition: wifi-test.cc:652
Make sure that when multiple broadcast packets are queued on the same device in a short succession,...
Definition: wifi-test.cc:476
void NotifyPhyTxBegin(Ptr< const Packet > p, double txPowerW)
Notify Phy transmit begin.
Definition: wifi-test.cc:511
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:532
ObjectFactory m_propDelay
propagation delay
Definition: wifi-test.cc:491
unsigned int m_numSentPackets
number of sent packets
Definition: wifi-test.cc:495
Time m_secondTransmissionTime
second transmission time
Definition: wifi-test.cc:494
Time m_firstTransmissionTime
first transmission time
Definition: wifi-test.cc:493
ObjectFactory m_manager
manager
Definition: wifi-test.cc:489
void SendOnePacket(Ptr< WifiNetDevice > dev)
Send one packet function.
Definition: wifi-test.cc:525
Data rate verification test for MCSs of different RU sizes.
Definition: wifi-test.cc:3543
bool CheckDataRate(HeRu::RuType ruType, std::string mcs, uint8_t nss, uint16_t guardInterval, uint16_t expectedDataRate)
Compare the data rate computed for the provided combination with standard defined one.
Definition: wifi-test.cc:3572
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:3594
Make sure that Ideal rate manager properly selects MCS based on the configured channel width.
Definition: wifi-test.cc:2939
WifiMode m_txMode
Store the last selected mode to send data packet.
Definition: wifi-test.cc:2977
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:3025
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
Triggers the transmission of a 1000 Byte-long data packet from the source device.
Definition: wifi-test.cc:2997
void CheckLastSelectedMode(WifiMode expectedMode)
Check if the selected WifiMode is correct.
Definition: wifi-test.cc:3016
void TxCallback(std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback that indicates a PSDU is being transmitted.
Definition: wifi-test.cc:3004
void ChangeChannelWidth(uint16_t channelWidth)
Change the configured channel width for all nodes.
Definition: wifi-test.cc:2990
~IdealRateManagerChannelWidthTest() override
Definition: wifi-test.cc:2985
Test to validate that Ideal rate manager properly selects TXVECTOR in scenarios where MIMO is used.
Definition: wifi-test.cc:3134
~IdealRateManagerMimoTest() override
Definition: wifi-test.cc:3191
void CheckLastSelectedNss(uint8_t expectedNss)
Check if the selected Nss is correct.
Definition: wifi-test.cc:3237
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:3256
void TxCallback(std::string context, WifiConstPsduMap psdus, WifiTxVector txVector, double txPowerW)
Callback that indicates a PSDU is being transmitted.
Definition: wifi-test.cc:3225
void SetApMimoSettings(uint8_t antennas, uint8_t maxStreams)
Change the configured MIMO settings for AP node.
Definition: wifi-test.cc:3196
WifiTxVector m_txVector
Store the last TXVECTOR used to transmit Data.
Definition: wifi-test.cc:3183
void SetStaMimoSettings(uint8_t antennas, uint8_t maxStreams)
Change the configured MIMO settings for STA node.
Definition: wifi-test.cc:3207
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
Triggers the transmission of a 1000 Byte-long data packet from the source device.
Definition: wifi-test.cc:3218
void CheckLastSelectedMode(WifiMode expectedMode)
Check if the selected WifiMode is correct.
Definition: wifi-test.cc:3246
void SwitchCh(Ptr< WifiNetDevice > dev)
Switch channel function.
Definition: wifi-test.cc:328
void SendOnePacket(Ptr< WifiNetDevice > dev)
Send one packet function.
Definition: wifi-test.cc:321
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:376
ObjectFactory m_manager
manager
Definition: wifi-test.cc:310
ObjectFactory m_propDelay
propagation delay
Definition: wifi-test.cc:312
Ptr< Node > CreateOne(Vector pos, Ptr< YansWifiChannel > channel)
Create one function.
Definition: wifi-test.cc:335
Make sure that Ideal rate manager is able to handle non best-effort traffic.
Definition: wifi-test.cc:2782
void SendPackets(uint8_t numPackets, Ptr< NetDevice > sourceDevice, Address &destination, uint8_t priority)
Triggers the transmission of a 1000 Byte-long data packet from the source device.
Definition: wifi-test.cc:2824
~Issue169TestCase() override
Definition: wifi-test.cc:2819
void TxCallback(std::string context, WifiConstPsduMap psdus, WifiTxVector txVector, double txPowerW)
Callback that indicates a PSDU is being transmitted.
Definition: wifi-test.cc:2840
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:2854
Make sure that Ideal rate manager recovers when the station is moving away from the access point.
Definition: wifi-test.cc:2550
uint16_t m_txCount
Count number of transmitted data packets.
Definition: wifi-test.cc:2584
uint16_t m_txMacFinalDataFailedCount
Count number of unsuccessfuly transmitted data packets.
Definition: wifi-test.cc:2586
void RunOne(bool useAmpdu)
Run one function.
Definition: wifi-test.cc:2625
uint16_t m_rxCount
Count number of successfully received data packets.
Definition: wifi-test.cc:2583
void RxSuccessCallback(std::string context, Ptr< const Packet > p)
Callback when packet is successfully received.
Definition: wifi-test.cc:2602
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:2759
void TxFinalDataFailedCallback(std::string context, Mac48Address address)
Transmit final data failed function.
Definition: wifi-test.cc:2619
void SendPackets(uint8_t numPackets, Ptr< NetDevice > sourceDevice, Address &destination)
Triggers the arrival of 1000 Byte-long packets in the source device.
Definition: wifi-test.cc:2608
~Issue40TestCase() override
Definition: wifi-test.cc:2597
Test management header.
Definition: wifi-test.cc:3641
static TypeId GetTypeId()
Register this type.
Definition: wifi-test.cc:3662
~MgtTestHeader() override=default
TypeId GetInstanceTypeId() const override
Definition: wifi-test.cc:3672
Make sure that fragmentation works with QoS stations.
Definition: wifi-test.cc:783
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:844
uint32_t m_received
received packets
Definition: wifi-test.cc:791
~QosFragmentationTestCase() override
Definition: wifi-test.cc:818
uint32_t m_fragments
transmitted fragments
Definition: wifi-test.cc:792
void Transmit(std::string context, Ptr< const Packet > p, double power)
Callback invoked when PHY transmits a packet.
Definition: wifi-test.cc:832
void Receive(std::string context, Ptr< const Packet > p, const Address &adr)
Receive function.
Definition: wifi-test.cc:823
Qos Utils Is Old Packet Test.
Definition: wifi-test.cc:243
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:250
Set Channel Frequency Test.
Definition: wifi-test.cc:939
Ptr< YansWifiPhy > GetYansWifiPhyPtr(const NetDeviceContainer &nc) const
Get yans wifi phy function.
Definition: wifi-test.cc:960
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:968
Make sure that Wifi STA is correctly associating to the best AP (i.e., nearest from STA).
Definition: wifi-test.cc:1941
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:2065
void TurnBeaconGenerationOn(Ptr< Node > apNode)
Turn beacon generation on the AP node.
Definition: wifi-test.cc:1991
Mac48Address m_associatedApBssid
Associated AP's bssid.
Definition: wifi-test.cc:1972
~StaWifiMacScanningTestCase() override
Definition: wifi-test.cc:1980
void TurnApOff(Ptr< Node > apNode)
Turn the AP node off.
Definition: wifi-test.cc:1999
NodeContainer Setup(bool nearestApBeaconGeneration, bool staActiveProbe)
Setup test.
Definition: wifi-test.cc:2007
void AssocCallback(std::string context, Mac48Address bssid)
Callback function on STA assoc event.
Definition: wifi-test.cc:1985
Mgt header (de)serialization Test Suite.
Definition: wifi-test.cc:3684
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:3699
~WifiMgtHeaderTest() override=default
Wifi Test.
Definition: wifi-test.cc:104
void CreateOne(Vector pos, Ptr< YansWifiChannel > channel)
Create one function.
Definition: wifi-test.cc:143
void RunOne()
Run one function.
Definition: wifi-test.cc:187
void DoRun() override
Implementation to actually run this TestCase.
Definition: wifi-test.cc:206
ObjectFactory m_mac
MAC.
Definition: wifi-test.cc:126
void SendOnePacket(Ptr< WifiNetDevice > dev)
Send one packet function.
Definition: wifi-test.cc:136
ObjectFactory m_manager
manager
Definition: wifi-test.cc:125
ObjectFactory m_propDelay
propagation delay
Definition: wifi-test.cc:127
Wifi Test Suite.
Definition: wifi-test.cc:3788
a polymophic address class
Definition: address.h:101
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
The Extended Supported Rates Information Element.
RuType
The different HE Resource Unit (RU) types.
Definition: he-ru.h:41
Protocol header serialization and deserialization.
Definition: header.h:44
Subclass of TestCase class adding the ability to test the serialization and deserialization of a Head...
void TestHeaderSerialization(const T &hdr, Args &&... args)
Serialize the given header in a buffer, then create a new header by deserializing from the buffer and...
The HT Operation Information Element.
Definition: ht-operation.h:51
void SetList(const std::list< uint64_t > &packetlist)
Definition: error-model.cc:456
an EUI-48 address
Definition: mac48-address.h:46
Implement the header for management frames of type beacon.
Definition: mgt-headers.h:512
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 AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:138
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:169
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:152
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:315
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:244
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:471
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:259
State
Represents the state for this agreement.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:960
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:305
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.
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Ptr< T > Get() const
Definition: pointer.h:202
calculate a propagation delay.
Handle packet fragmentation and retransmissions for QoS data frames as well as MSDU aggregation (A-MS...
Definition: qos-txop.h:74
indicates whether the socket has a priority set.
Definition: socket.h:1316
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition: socket.cc:854
size_t GetNumBands() const
Bands::const_iterator Begin() const
Const Iterator to the model Bands container start.
Ptr< const SpectrumModel > GetSpectrumModel() const
Make it easy to create and manage PHY objects for the spectrum model.
void SetChannel(const Ptr< SpectrumChannel > channel)
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
char * PeekString() const
Peek the SSID.
Definition: ssid.cc:78
Hold variables of type string.
Definition: string.h:56
The Supported Rates Information Element.
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
Handle packet fragmentation and retransmissions for data and management frames.
Definition: txop.h:74
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition: txop.cc:564
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Hold an unsigned integer type.
Definition: uinteger.h:45
Vector3D Vector
Vector alias typedef for compatibility with mobility models.
Definition: vector.h:324
a (time, location) pair.
Definition: waypoint.h:36
void AddWaypoint(const Waypoint &waypoint)
helps to create WifiNetDevice objects
Definition: wifi-helper.h:324
Implements the IEEE 802.11 MAC header.
bool IsAssocReq() const
Return true if the header is an Association Request header.
bool IsBeacon() const
Return true if the header is a Beacon header.
bool IsAssocResp() const
Return true if the header is an Association Response header.
bool IsAction() const
Return true if the header is an Action header.
bool IsData() const
Return true if the Type is DATA.
bool IsQosData() const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
create MAC layers for a ns3::WifiNetDevice.
void SetType(std::string type, Args &&... args)
base class for all MAC-level wifi objects.
Definition: wifi-mac.h:96
Ptr< FrameExchangeManager > GetFrameExchangeManager(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get the Frame Exchange Manager associated with the given link.
Definition: wifi-mac.cc:864
virtual void SetMacQueueScheduler(Ptr< WifiMacQueueScheduler > scheduler)
Set the wifi MAC queue scheduler.
Definition: wifi-mac.cc:569
virtual void SetAddress(Mac48Address address)
Definition: wifi-mac.cc:445
virtual void ConfigureStandard(WifiStandard standard)
Definition: wifi-mac.cc:748
Ptr< WifiPhy > GetWifiPhy(uint8_t linkId=SINGLE_LINK_OP_ID) const
Definition: wifi-mac.cc:1171
void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-mac.cc:428
Implement the header for management frames.
represent a single transmission mode
Definition: wifi-mode.h:51
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:185
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:122
Hold together all Wifi-related objects.
void SetMac(const Ptr< WifiMac > mac)
void SetHtConfiguration(Ptr< HtConfiguration > htConfiguration)
Address GetBroadcast() const override
Ptr< WifiMac > GetMac() const
bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber) override
void SetRemoteStationManager(const Ptr< WifiRemoteStationManager > manager)
void SetStandard(WifiStandard standard)
Set the Wifi standard.
Ptr< WifiPhy > GetPhy() const
uint32_t GetIfIndex() const override
void SetPhy(const Ptr< WifiPhy > phy)
Address GetAddress() const override
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:163
void SetErrorRateModel(std::string type, Args &&... args)
Helper function used to set the error rate model.
Definition: wifi-helper.h:550
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition: wifi-phy.cc:639
uint16_t GetChannelWidth() const
Definition: wifi-phy.cc:1051
uint16_t GetFrequency() const
Definition: wifi-phy.cc:1039
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:961
void SetPostReceptionErrorModel(const Ptr< ErrorModel > em)
Attach a receive ErrorModel to the WifiPhy.
Definition: wifi-phy.cc:646
void SetOperatingChannel(const ChannelTuple &channelTuple)
If the standard for this object has not been set yet, store the given channel settings.
Definition: wifi-phy.cc:1098
uint8_t GetChannelNumber() const
Return current channel number.
Definition: wifi-phy.cc:1045
virtual void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:607
std::tuple< uint8_t, uint16_t, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:891
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:619
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1033
bool IsSet() const
Return true if a valid channel has been set, false otherwise.
hold a list of per-remote-station state.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode.
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
uint16_t GetChannelWidth() const
manage and create wifi channel objects for the YANS model.
Make it easy to create and manage PHY objects for the YANS model.
802.11 PHY layer model
Definition: yans-wifi-phy.h:48
void SetChannel(const Ptr< YansWifiChannel > channel)
Set the YansWifiChannel this YansWifiPhy is to be connected to.
void SetInterferenceHelper(const Ptr< InterferenceHelper > helper) override
Sets the interference helper.
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:974
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:876
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
#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:144
#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:830
#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:251
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
TypeOfStation
Enumeration for type of WiFi station.
Definition: wifi-mac.h:64
bool QosUtilsIsOldPacket(uint16_t startingSeq, uint16_t seqNumber)
This function checks if packet with sequence number seqNumber is an "old" packet.
Definition: qos-utils.cc:182
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
@ STA
Definition: wifi-mac.h:65
@ AP
Definition: wifi-mac.h:66
@ WIFI_STANDARD_80211a
@ WIFI_STANDARD_80211p
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211g
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ WIFI_STANDARD_80211b
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
@ 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.
NodeContainer nodes
void SendOnePacket(Ptr< LrWpanPhy > sender, Ptr< LrWpanPhy > receiver)
Send one packet.
address
Definition: first.py:47
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.h:25255
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
@ WIFI_MAC_MGT_ACTION
std::map< WifiSpectrumBandInfo, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:77
staDevices
Definition: third.py:100
ssid
Definition: third.py:93
channel
Definition: third.py:88
mac
Definition: third.py:92
wifi
Definition: third.py:95
apDevices
Definition: third.py:103
wifiApNode
Definition: third.py:86
mobility
Definition: third.py:105
phy
Definition: third.py:89
Struct containing all supported rates.
SupportedRates rates
supported rates
std::optional< ExtendedSupportedRatesIE > extendedRates
supported extended rates
void AddSupportedRate(uint64_t bs)
Add the given rate to the supported rates.
MpduInfo structure.
Definition: phy-entity.h:62
MpduType type
type of MPDU
Definition: phy-entity.h:63
SignalNoiseDbm structure.
Definition: phy-entity.h:55
Ptr< SpectrumValue > psd
The Power Spectral Density of the waveform, in linear units.
static void AssignWifiRandomStreams(Ptr< WifiMac > mac, int64_t stream)
Definition: wifi-test.cc:67
static WifiTestSuite g_wifiTestSuite
the test suite
Definition: wifi-test.cc:3816
std::tuple< SupportedRates, std::optional< ExtendedSupportedRatesIE >, std::vector< Ssid > > MgtTestElems
List of Information Elements included in the test management frame.
Definition: wifi-test.cc:3632