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_staDevice.Get(0)->GetIfIndex());
176  socket.SetPhysicalAddress(m_apDevice.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  auto 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);
190  client->SetStartTime(Seconds(0.5));
191  client->SetStopTime(Seconds(1.0));
192 
193  auto server = CreateObject<PacketSocketServer>();
194  server->SetLocal(socket);
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  auto spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
233  auto lossModel = CreateObject<FriisPropagationLossModel>();
234  spectrumChannel->AddPropagationLossModel(lossModel);
235  auto delayModel = CreateObject<ConstantSpeedPropagationDelayModel>();
236  spectrumChannel->SetPropagationDelayModel(delayModel);
237 
239  phy.SetChannel(spectrumChannel);
240  phy.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}"));
241 
243  wifi.SetStandard(WIFI_STANDARD_80211ax);
244  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
245 
247  mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(Ssid("channel-switching-test")));
248 
249  m_staDevice = wifi.Install(phy, mac, m_staNode);
250 
251  mac.SetType("ns3::ApWifiMac",
252  "Ssid",
253  SsidValue(Ssid("channel-switching-test")),
254  "EnableBeaconJitter",
255  BooleanValue(false));
256 
257  m_apDevice = wifi.Install(phy, mac, m_apNode);
258 
259  // Assign fixed streams to random variables in use
260  wifi.AssignStreams(m_apDevice, streamNumber);
261 
263  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
264 
265  positionAlloc->Add(Vector(0.0, 0.0, 0.0));
266  positionAlloc->Add(Vector(5.0, 0.0, 0.0));
267  mobility.SetPositionAllocator(positionAlloc);
268 
269  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
270  mobility.Install(m_apNode);
271  mobility.Install(m_staNode);
272 
273  SendPacket();
274 
276  "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/Assoc",
278  Config::ConnectWithoutContext("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxPsduBegin",
280  Config::ConnectWithoutContext("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx",
283  "/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/State/State",
286  "/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/State/State",
288 
289  Simulator::Stop(Seconds(2));
290  Simulator::Run();
291 
292  NS_TEST_EXPECT_MSG_EQ(+m_assocCount, 2, "STA did not associate twice");
294  2,
295  "The QoS Data frame should have been transmitted twice by the STA");
298  "The QoS Data frame should have been received once by the AP");
299  NS_TEST_EXPECT_MSG_EQ(+m_channelSwitchCount[0], 1, "AP had to perform one channel switch");
300  NS_TEST_EXPECT_MSG_EQ(+m_channelSwitchCount[1], 1, "STA had to perform one channel switch");
301 
302  Simulator::Destroy();
303 }
304 
312 {
313  public:
315 };
316 
318  : TestSuite("wifi-channel-switching", UNIT)
319 {
320  AddTestCase(new WifiChannelSwitchingTest, TestCase::QUICK);
321 }
322 
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 STA to the AP 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:101
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:861
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
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:301
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
Hold an unsigned integer type.
Definition: uinteger.h:45
helps to create WifiNetDevice objects
Definition: wifi-helper.h:324
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:950
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:876
#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:1350
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
@ 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:704
mac
Definition: third.py:92
wifi
Definition: third.py:95
mobility
Definition: third.py:105
phy
Definition: third.py:89
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...