A Discrete-Event Network Simulator
API
wifi-channel-switching-test.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2021 2020 Universita' degli Studi di Napoli Federico II
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  * Author: Stefano Avallone <stavallo@unina.it>
19  */
20 
21 #include "ns3/test.h"
22 #include "ns3/string.h"
23 #include "ns3/boolean.h"
24 #include "ns3/qos-utils.h"
25 #include "ns3/wifi-psdu.h"
26 #include "ns3/wifi-net-device.h"
27 #include "ns3/ap-wifi-mac.h"
28 #include "ns3/mobility-helper.h"
29 #include "ns3/spectrum-wifi-helper.h"
30 #include "ns3/multi-model-spectrum-channel.h"
31 #include "ns3/packet-socket-server.h"
32 #include "ns3/packet-socket-client.h"
33 #include "ns3/packet-socket-helper.h"
34 #include "ns3/rng-seed-manager.h"
35 #include "ns3/config.h"
36 #include <array>
37 
38 using namespace ns3;
39 
40 NS_LOG_COMPONENT_DEFINE ("WifiChannelSwitchingTest");
41 
53 {
54 public:
59  virtual ~WifiChannelSwitchingTest ();
60 
61  virtual void DoRun (void);
62 
69  void Associated (Mac48Address bssid);
78  void Transmit (WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW);
85  void L7Receive (Ptr<const Packet> p, const Address &addr);
89  void SendPacket (void);
93  void ChannelSwitch (void);
102  void StateChange (uint32_t nodeId, Time start, Time duration, WifiPhyState state);
103 
104 private:
109  uint8_t m_assocCount;
110  uint8_t m_txCount;
111  uint64_t m_rxBytes;
112  uint32_t m_payloadSize;
113  std::array<uint8_t, 2> m_channelSwitchCount {0, 0};
114 };
115 
117  : TestCase ("Test case for resuming data transmission when the recipient moves back"),
118  m_assocCount (0),
119  m_txCount (0),
120  m_rxBytes (0),
121  m_payloadSize (2000)
122 {
123 }
124 
126 {
127 }
128 
129 void
131 {
132  m_assocCount++;
133 }
134 
135 void
137 {
138  for (const auto& psduPair : psduMap)
139  {
140  std::stringstream ss;
141  ss << " " << psduPair.second->GetHeader (0).GetTypeString ()
142  << " seq " << psduPair.second->GetHeader (0).GetSequenceNumber ()
143  << " from " << psduPair.second->GetAddr2 ()
144  << " to " << psduPair.second->GetAddr1 ();
145  NS_LOG_INFO (ss.str ());
146  }
147  NS_LOG_INFO (" TXVECTOR " << txVector << "\n");
148 
149  if (psduMap.begin ()->second->GetHeader (0).IsQosData ())
150  {
151  m_txCount++;
152 
153  if (!psduMap.begin ()->second->GetHeader (0).IsRetry ())
154  {
155  // packet transmitted after first association. Switch channel during its
156  // transmission
157  Time txDuration = WifiPhy::CalculateTxDuration (psduMap, txVector, WIFI_PHY_BAND_5GHZ);
158  Simulator::Schedule (txDuration / 2, &WifiChannelSwitchingTest::ChannelSwitch, this);
159  }
160  }
161 }
162 
163 void
165 {
166  if (p->GetSize () == m_payloadSize)
167  {
169  }
170 }
171 
172 void
174 {
175  PacketSocketAddress socket;
176  socket.SetSingleDevice (m_apDevice.Get (0)->GetIfIndex ());
177  socket.SetPhysicalAddress (m_staDevice.Get (0)->GetAddress ());
178  socket.SetProtocol (1);
179 
180  // give packet socket powers to nodes.
181  PacketSocketHelper packetSocket;
182  packetSocket.Install (m_staNode);
183  packetSocket.Install (m_apNode);
184 
185  Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient> ();
186  client->SetAttribute ("PacketSize", UintegerValue (m_payloadSize));
187  client->SetAttribute ("MaxPackets", UintegerValue (1));
188  client->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
189  client->SetRemote (socket);
190  m_apNode.Get (0)->AddApplication (client);
191  client->SetStartTime (Seconds (0.5));
192  client->SetStopTime (Seconds (1.0));
193 
194  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
195  server->SetLocal (socket);
196  m_staNode.Get (0)->AddApplication (server);
197  server->SetStartTime (Seconds (0.0));
198  server->SetStopTime (Seconds (1.0));
199 }
200 
201 void
203 {
204  NS_LOG_INFO ("CHANNEL SWITCH\n");
205  Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/ChannelSettings",
206  StringValue ("{1, 20, BAND_2_4GHZ, 0}"));
207 }
208 
209 void
211  WifiPhyState state)
212 {
213  if (state == WifiPhyState::SWITCHING)
214  {
215  m_channelSwitchCount[nodeId]++;
216  }
217 }
218 
219 void
221 {
222  Time simulationTime (Seconds (6.0));
223 
224  RngSeedManager::SetSeed (1);
225  RngSeedManager::SetRun (40);
226  int64_t streamNumber = 100;
227 
228  m_apNode.Create (1);
229  m_staNode.Create (1);
230 
231  Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
232  Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
233  spectrumChannel->AddPropagationLossModel (lossModel);
234  Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
235  spectrumChannel->SetPropagationDelayModel (delayModel);
236 
238  phy.SetChannel (spectrumChannel);
239  phy.Set ("ChannelSettings", StringValue ("{36, 20, BAND_5GHZ, 0}"));
240 
242  wifi.SetStandard (WIFI_STANDARD_80211ax);
243  wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
244 
246  mac.SetType ("ns3::StaWifiMac",
247  "Ssid", SsidValue (Ssid ("channel-switching-test")));
248 
249  m_staDevice = wifi.Install (phy, mac, m_staNode);
250 
251  mac.SetType ("ns3::ApWifiMac",
252  "Ssid", SsidValue (Ssid ("channel-switching-test")),
253  "EnableBeaconJitter", BooleanValue (false));
254 
255  m_apDevice = wifi.Install (phy, mac, m_apNode);
256 
257  // Assign fixed streams to random variables in use
258  wifi.AssignStreams (m_apDevice, streamNumber);
259 
261  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
262 
263  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
264  positionAlloc->Add (Vector (5.0, 0.0, 0.0));
265  mobility.SetPositionAllocator (positionAlloc);
266 
267  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
268  mobility.Install (m_apNode);
269  mobility.Install (m_staNode);
270 
271  SendPacket ();
272 
273  Config::ConnectWithoutContext ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/Assoc",
275  Config::ConnectWithoutContext ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxPsduBegin",
277  Config::ConnectWithoutContext ("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx",
279  Config::ConnectWithoutContext ("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/State/State",
281  Config::ConnectWithoutContext ("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/State/State",
283 
284  Simulator::Stop (Seconds (2));
285  Simulator::Run ();
286 
287  NS_TEST_EXPECT_MSG_EQ (+m_assocCount, 2, "STA did not associate twice");
288  NS_TEST_EXPECT_MSG_EQ (+m_txCount, 2, "The QoS Data frame should have been transmitted twice by the AP");
289  NS_TEST_EXPECT_MSG_EQ (m_rxBytes, m_payloadSize, "The QoS Data frame should have been received once by the STA");
290  NS_TEST_EXPECT_MSG_EQ (+m_channelSwitchCount[0], 1, "AP had to perform one channel switch");
291  NS_TEST_EXPECT_MSG_EQ (+m_channelSwitchCount[1], 1, "STA had to perform one channel switch");
292 
293  Simulator::Destroy ();
294 }
295 
303 {
304 public:
306 };
307 
309  : TestSuite ("wifi-channel-switching", UNIT)
310 {
311  AddTestCase (new WifiChannelSwitchingTest, TestCase::QUICK);
312 }
313 
This test verifies that communication between an AP and a STA resumes after that both switch channel ...
virtual void DoRun(void)
Implementation to actually run this TestCase.
uint8_t m_assocCount
count of completed Assoc Request procedures
NetDeviceContainer m_staDevice
STA device container.
void StateChange(uint32_t nodeId, Time start, Time duration, WifiPhyState state)
Callback invoked when the PHY on the given node changes state.
uint32_t m_payloadSize
payload size in bytes
NodeContainer m_staNode
STA node container.
void Associated(Mac48Address bssid)
Callback invoked when a station associates with an AP.
void SendPacket(void)
Send a packet from the AP to the STA through a packet socket.
void L7Receive(Ptr< const Packet > p, const Address &addr)
Function to trace packets received by the server application.
std::array< uint8_t, 2 > m_channelSwitchCount
Per-node number of channel switch events.
NetDeviceContainer m_apDevice
AP device container.
NodeContainer m_apNode
AP node container.
void Transmit(WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback invoked when PHY receives a PSDU to transmit from the MAC.
void ChannelSwitch(void)
Request channel switch on both AP and STA.
uint8_t m_txCount
count of transmissions
a polymophic address class
Definition: address.h:91
AttributeValue implementation for Boolean.
Definition: boolean.h:37
an EUI-48 address
Definition: mac48-address.h:44
Helper class used to assign positions and mobility models to nodes.
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.
virtual Address GetAddress(void) const =0
virtual uint32_t GetIfIndex(void) const =0
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:159
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
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.
Make it easy to create and manage PHY objects for the spectrum model.
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
Definition: ssid.h:105
Hold variables of type string.
Definition: string.h:41
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
AttributeValue implementation for Time.
Definition: nstime.h:1308
Hold an unsigned integer type.
Definition: uinteger.h:44
helps to create WifiNetDevice objects
Definition: wifi-helper.h:274
create MAC layers for a ns3::WifiNetDevice.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:901
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:839
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:240
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1260
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
@ WIFI_STANDARD_80211ax
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
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, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
mac
Definition: third.py:99
wifi
Definition: third.py:96
mobility
Definition: third.py:108
phy
Definition: third.py:93
def start()
Definition: core.py:1853
static WifiChannelSwitchingTestSuite g_issue211TestSuite
the test suite
WifiPhyState
The state of the PHY layer.
@ SWITCHING
The PHY layer is switching to other channel.
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
This example (inspired from tv-trans-example) enables to generate the transmitted spectra of Wi-Fi st...