A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
38using namespace ns3;
39
40NS_LOG_COMPONENT_DEFINE("WifiChannelSwitchingTest");
41
42/**
43 * \ingroup wifi-test
44 * \ingroup tests
45 *
46 * This test verifies that communication between an AP and a STA resumes
47 * after that both switch channel and PHY band. The channel switch is
48 * scheduled to happen during the transmission of a frame sent by the STA
49 * to the AP. AP discards the frame, STA associates with the AP again and
50 * the AP finally receives the frame successfully.
51 */
53{
54 public:
55 /**
56 * \brief Constructor
57 */
60
61 void DoRun() override;
62
63 /**
64 * Callback invoked when a station associates with an AP. Tracks the number of
65 * times the association procedure is performed.
66 *
67 * \param bssid the BSSID
68 */
69 void Associated(Mac48Address bssid);
70 /**
71 * Callback invoked when PHY receives a PSDU to transmit from the MAC. Tracks the
72 * number of times a QoS data frame is transmitted by the STA.
73 *
74 * \param psduMap the PSDU map
75 * \param txVector the TX vector
76 * \param txPowerW the tx power in Watts
77 */
78 void Transmit(WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW);
79 /**
80 * Function to trace packets received by the server application
81 *
82 * \param p the packet
83 * \param addr the address
84 */
85 void L7Receive(Ptr<const Packet> p, const Address& addr);
86 /**
87 * Send a packet from the STA to the AP through a packet socket
88 */
89 void SendPacket();
90 /**
91 * Request channel switch on both AP and STA
92 */
93 void ChannelSwitch();
94 /**
95 * Callback invoked when the PHY on the given node changes state.
96 *
97 * \param nodeId the given node ID
98 * \param start the time state changes
99 * \param duration the time the PHY will stay in the new state
100 * \param state the new PHY state
101 */
102 void StateChange(uint32_t nodeId, Time start, Time duration, WifiPhyState state);
103
104 private:
105 NodeContainer m_apNode; ///< AP node container
106 NodeContainer m_staNode; ///< STA node container
107 NetDeviceContainer m_apDevice; ///< AP device container
108 NetDeviceContainer m_staDevice; ///< STA device container
109 uint8_t m_assocCount; ///< count of completed Assoc Request procedures
110 uint8_t m_txCount; ///< count of transmissions
111 uint64_t m_rxBytes; ///< RX bytes
112 uint32_t m_payloadSize; ///< payload size in bytes
113 std::array<uint8_t, 2> m_channelSwitchCount{0, 0}; ///< Per-node number of channel switch events
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
129void
131{
132 m_assocCount++;
133}
134
135void
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);
158 }
159 }
160}
161
162void
164{
165 if (p->GetSize() == m_payloadSize)
166 {
168 }
169}
170
171void
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);
189 m_staNode.Get(0)->AddApplication(client);
190 client->SetStartTime(Seconds(0.5));
191 client->SetStopTime(Seconds(1.0));
192
193 auto server = CreateObject<PacketSocketServer>();
194 server->SetLocal(socket);
195 m_apNode.Get(0)->AddApplication(server);
196 server->SetStartTime(Seconds(0.0));
197 server->SetStopTime(Seconds(1.0));
198}
199
200void
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
208void
210 ns3::Time start,
211 ns3::Time duration,
212 WifiPhyState state)
213{
214 if (state == WifiPhyState::SWITCHING)
215 {
216 m_channelSwitchCount[nodeId]++;
217 }
218}
219
220void
222{
223 Time simulationTime(Seconds(6.0));
224
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
242 WifiHelper wifi;
243 wifi.SetStandard(WIFI_STANDARD_80211ax);
244 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
245
246 WifiMacHelper mac;
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
262 MobilityHelper mobility;
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
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
303}
304
305/**
306 * \ingroup wifi-test
307 * \ingroup tests
308 *
309 * \brief Block Ack Test Suite
310 */
312{
313 public:
315};
316
318 : TestSuite("wifi-channel-switching", Type::UNIT)
319{
320 AddTestCase(new WifiChannelSwitchingTest, TestCase::Duration::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
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:164
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.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
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:96
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1413
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.
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1529
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:954
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:880
#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:252
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.
WifiPhyState
The state of the PHY layer.
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
static WifiChannelSwitchingTestSuite g_issue211TestSuite
the test suite