A Discrete-Event Network Simulator
API
wifi-channel-switching-test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 2020 Universita' degli Studi di Napoli Federico II
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Stefano Avallone <stavallo@unina.it>
18  */
19 
20 #include "ns3/ap-wifi-mac.h"
21 #include "ns3/boolean.h"
22 #include "ns3/config.h"
23 #include "ns3/mobility-helper.h"
24 #include "ns3/multi-model-spectrum-channel.h"
25 #include "ns3/packet-socket-client.h"
26 #include "ns3/packet-socket-helper.h"
27 #include "ns3/packet-socket-server.h"
28 #include "ns3/qos-utils.h"
29 #include "ns3/rng-seed-manager.h"
30 #include "ns3/spectrum-wifi-helper.h"
31 #include "ns3/string.h"
32 #include "ns3/test.h"
33 #include "ns3/wifi-net-device.h"
34 #include "ns3/wifi-psdu.h"
35 
36 #include <array>
37 
38 using namespace ns3;
39 
40 NS_LOG_COMPONENT_DEFINE("WifiChannelSwitchingTest");
41 
53 {
54  public:
59  ~WifiChannelSwitchingTest() override;
60 
61  void DoRun() override;
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();
93  void ChannelSwitch();
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() << " seq "
142  << psduPair.second->GetHeader(0).GetSequenceNumber() << " from "
143  << psduPair.second->GetAddr2() << " to " << psduPair.second->GetAddr1();
144  NS_LOG_INFO(ss.str());
145  }
146  NS_LOG_INFO(" TXVECTOR " << txVector << "\n");
147 
148  if (psduMap.begin()->second->GetHeader(0).IsQosData())
149  {
150  m_txCount++;
151 
152  if (!psduMap.begin()->second->GetHeader(0).IsRetry())
153  {
154  // packet transmitted after first association. Switch channel during its
155  // transmission
156  Time txDuration = WifiPhy::CalculateTxDuration(psduMap, txVector, WIFI_PHY_BAND_5GHZ);
157  Simulator::Schedule(txDuration / 2, &WifiChannelSwitchingTest::ChannelSwitch, this);
158  }
159  }
160 }
161 
162 void
164 {
165  if (p->GetSize() == m_payloadSize)
166  {
168  }
169 }
170 
171 void
173 {
174  PacketSocketAddress socket;
175  socket.SetSingleDevice(m_apDevice.Get(0)->GetIfIndex());
176  socket.SetPhysicalAddress(m_staDevice.Get(0)->GetAddress());
177  socket.SetProtocol(1);
178 
179  // give packet socket powers to nodes.
180  PacketSocketHelper packetSocket;
181  packetSocket.Install(m_staNode);
182  packetSocket.Install(m_apNode);
183 
184  Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient>();
185  client->SetAttribute("PacketSize", UintegerValue(m_payloadSize));
186  client->SetAttribute("MaxPackets", UintegerValue(1));
187  client->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
188  client->SetRemote(socket);
189  m_apNode.Get(0)->AddApplication(client);
190  client->SetStartTime(Seconds(0.5));
191  client->SetStopTime(Seconds(1.0));
192 
193  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer>();
194  server->SetLocal(socket);
195  m_staNode.Get(0)->AddApplication(server);
196  server->SetStartTime(Seconds(0.0));
197  server->SetStopTime(Seconds(1.0));
198 }
199 
200 void
202 {
203  NS_LOG_INFO("CHANNEL SWITCH\n");
204  Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/ChannelSettings",
205  StringValue("{1, 20, BAND_2_4GHZ, 0}"));
206 }
207 
208 void
211  ns3::Time duration,
212  WifiPhyState state)
213 {
214  if (state == WifiPhyState::SWITCHING)
215  {
216  m_channelSwitchCount[nodeId]++;
217  }
218 }
219 
220 void
222 {
223  Time simulationTime(Seconds(6.0));
224 
225  RngSeedManager::SetSeed(1);
226  RngSeedManager::SetRun(40);
227  int64_t streamNumber = 100;
228 
229  m_apNode.Create(1);
230  m_staNode.Create(1);
231 
232  Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
233  Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel>();
234  spectrumChannel->AddPropagationLossModel(lossModel);
236  CreateObject<ConstantSpeedPropagationDelayModel>();
237  spectrumChannel->SetPropagationDelayModel(delayModel);
238 
240  phy.SetChannel(spectrumChannel);
241  phy.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}"));
242 
244  wifi.SetStandard(WIFI_STANDARD_80211ax);
245  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
246 
248  mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(Ssid("channel-switching-test")));
249 
250  m_staDevice = wifi.Install(phy, mac, m_staNode);
251 
252  mac.SetType("ns3::ApWifiMac",
253  "Ssid",
254  SsidValue(Ssid("channel-switching-test")),
255  "EnableBeaconJitter",
256  BooleanValue(false));
257 
258  m_apDevice = wifi.Install(phy, mac, m_apNode);
259 
260  // Assign fixed streams to random variables in use
261  wifi.AssignStreams(m_apDevice, streamNumber);
262 
264  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
265 
266  positionAlloc->Add(Vector(0.0, 0.0, 0.0));
267  positionAlloc->Add(Vector(5.0, 0.0, 0.0));
268  mobility.SetPositionAllocator(positionAlloc);
269 
270  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
271  mobility.Install(m_apNode);
272  mobility.Install(m_staNode);
273 
274  SendPacket();
275 
277  "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/Assoc",
279  Config::ConnectWithoutContext("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxPsduBegin",
281  Config::ConnectWithoutContext("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx",
284  "/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/State/State",
287  "/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/State/State",
289 
290  Simulator::Stop(Seconds(2));
291  Simulator::Run();
292 
293  NS_TEST_EXPECT_MSG_EQ(+m_assocCount, 2, "STA did not associate twice");
295  2,
296  "The QoS Data frame should have been transmitted twice by the AP");
299  "The QoS Data frame should have been received once by the STA");
300  NS_TEST_EXPECT_MSG_EQ(+m_channelSwitchCount[0], 1, "AP had to perform one channel switch");
301  NS_TEST_EXPECT_MSG_EQ(+m_channelSwitchCount[1], 1, "STA had to perform one channel switch");
302 
303  Simulator::Destroy();
304 }
305 
313 {
314  public:
316 };
317 
319  : TestSuite("wifi-channel-switching", UNIT)
320 {
321  AddTestCase(new WifiChannelSwitchingTest, TestCase::QUICK);
322 }
323 
This test verifies that communication between an AP and a STA resumes after that both switch channel ...
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()
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.
void ChannelSwitch()
Request channel switch on both AP and STA.
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 DoRun() override
Implementation to actually run this TestCase.
uint8_t m_txCount
count of transmissions
a polymophic address class
Definition: address.h:100
AttributeValue implementation for Boolean.
Definition: boolean.h:37
an EUI-48 address
Definition: mac48-address.h:46
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.
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:169
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
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.
Hold variables of type string.
Definition: string.h:56
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:305
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1423
Hold an unsigned integer type.
Definition: uinteger.h:45
helps to create WifiNetDevice objects
Definition: wifi-helper.h:325
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:951
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:877
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#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:1360
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
@ 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, 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:707
mac
Definition: third.py:85
wifi
Definition: third.py:88
mobility
Definition: third.py:96
phy
Definition: third.py:82
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...