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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Stefano Avallone <stavallo@unina.it>
7 */
8
9#include "ns3/ap-wifi-mac.h"
10#include "ns3/boolean.h"
11#include "ns3/config.h"
12#include "ns3/mobility-helper.h"
13#include "ns3/multi-model-spectrum-channel.h"
14#include "ns3/packet-socket-client.h"
15#include "ns3/packet-socket-helper.h"
16#include "ns3/packet-socket-server.h"
17#include "ns3/qos-utils.h"
18#include "ns3/rng-seed-manager.h"
19#include "ns3/spectrum-wifi-helper.h"
20#include "ns3/string.h"
21#include "ns3/test.h"
22#include "ns3/wifi-net-device.h"
23#include "ns3/wifi-psdu.h"
24
25#include <array>
26
27using namespace ns3;
28
29NS_LOG_COMPONENT_DEFINE("WifiChannelSwitchingTest");
30
31/**
32 * @ingroup wifi-test
33 * @ingroup tests
34 *
35 * This test verifies that communication between an AP and a STA resumes
36 * after that both switch channel and PHY band. The channel switch is
37 * scheduled to happen during the transmission of a frame sent by the STA
38 * to the AP. AP discards the frame, STA associates with the AP again and
39 * the AP finally receives the frame successfully.
40 */
42{
43 public:
44 /**
45 * @brief Constructor
46 */
49
50 void DoRun() override;
51
52 /**
53 * Callback invoked when a station associates with an AP. Tracks the number of
54 * times the association procedure is performed.
55 *
56 * @param bssid the BSSID
57 */
58 void Associated(Mac48Address bssid);
59 /**
60 * Callback invoked when PHY receives a PSDU to transmit from the MAC. Tracks the
61 * number of times a QoS data frame is transmitted by the STA.
62 *
63 * @param psduMap the PSDU map
64 * @param txVector the TX vector
65 * @param txPowerW the tx power in Watts
66 */
67 void Transmit(WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW);
68 /**
69 * Function to trace packets received by the server application
70 *
71 * @param p the packet
72 * @param addr the address
73 */
74 void L7Receive(Ptr<const Packet> p, const Address& addr);
75 /**
76 * Send a packet from the STA to the AP through a packet socket
77 */
78 void SendPacket();
79 /**
80 * Request channel switch on both AP and STA
81 */
82 void ChannelSwitch();
83 /**
84 * Callback invoked when the PHY on the given node changes state.
85 *
86 * @param nodeId the given node ID
87 * @param start the time state changes
88 * @param duration the time the PHY will stay in the new state
89 * @param state the new PHY state
90 */
91 void StateChange(uint32_t nodeId, Time start, Time duration, WifiPhyState state);
92
93 private:
94 NodeContainer m_apNode; ///< AP node container
95 NodeContainer m_staNode; ///< STA node container
96 NetDeviceContainer m_apDevice; ///< AP device container
97 NetDeviceContainer m_staDevice; ///< STA device container
98 uint8_t m_assocCount; ///< count of completed Assoc Request procedures
99 uint8_t m_txCount; ///< count of transmissions
100 uint64_t m_rxBytes; ///< RX bytes
101 uint32_t m_payloadSize; ///< payload size in bytes
102 std::array<uint8_t, 2> m_channelSwitchCount{0, 0}; ///< Per-node number of channel switch events
103};
104
106 : TestCase("Test case for resuming data transmission when the recipient moves back"),
107 m_assocCount(0),
108 m_txCount(0),
109 m_rxBytes(0),
110 m_payloadSize(2000)
111{
112}
113
117
118void
123
124void
126{
127 for (const auto& psduPair : psduMap)
128 {
129 std::stringstream ss;
130 ss << " " << psduPair.second->GetHeader(0).GetTypeString() << " seq "
131 << psduPair.second->GetHeader(0).GetSequenceNumber() << " from "
132 << psduPair.second->GetAddr2() << " to " << psduPair.second->GetAddr1();
133 NS_LOG_INFO(ss.str());
134 }
135 NS_LOG_INFO(" TXVECTOR " << txVector << "\n");
136
137 if (psduMap.begin()->second->GetHeader(0).IsQosData())
138 {
139 m_txCount++;
140
141 if (!psduMap.begin()->second->GetHeader(0).IsRetry())
142 {
143 // packet transmitted after first association. Switch channel during its
144 // transmission
145 Time txDuration = WifiPhy::CalculateTxDuration(psduMap, txVector, WIFI_PHY_BAND_5GHZ);
147 }
148 }
149}
150
151void
153{
154 if (p->GetSize() == m_payloadSize)
155 {
157 }
158}
159
160void
162{
163 PacketSocketAddress socket;
164 socket.SetSingleDevice(m_staDevice.Get(0)->GetIfIndex());
165 socket.SetPhysicalAddress(m_apDevice.Get(0)->GetAddress());
166 socket.SetProtocol(1);
167
168 // give packet socket powers to nodes.
169 PacketSocketHelper packetSocket;
170 packetSocket.Install(m_staNode);
171 packetSocket.Install(m_apNode);
172
173 auto client = CreateObject<PacketSocketClient>();
174 client->SetAttribute("PacketSize", UintegerValue(m_payloadSize));
175 client->SetAttribute("MaxPackets", UintegerValue(1));
176 client->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
177 client->SetRemote(socket);
178 m_staNode.Get(0)->AddApplication(client);
179 client->SetStartTime(Seconds(0.5));
180 client->SetStopTime(Seconds(1));
181
182 auto server = CreateObject<PacketSocketServer>();
183 server->SetLocal(socket);
184 m_apNode.Get(0)->AddApplication(server);
185 server->SetStartTime(Seconds(0));
186 server->SetStopTime(Seconds(1));
187}
188
189void
191{
192 NS_LOG_INFO("CHANNEL SWITCH\n");
193 Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/ChannelSettings",
194 StringValue("{1, 20, BAND_2_4GHZ, 0}"));
195}
196
197void
199 ns3::Time start,
200 ns3::Time duration,
201 WifiPhyState state)
202{
203 if (state == WifiPhyState::SWITCHING)
204 {
205 m_channelSwitchCount[nodeId]++;
206 }
207}
208
209void
211{
212 Time simulationTime(Seconds(6));
213
216 int64_t streamNumber = 100;
217
218 m_apNode.Create(1);
219 m_staNode.Create(1);
220
221 auto spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
223 spectrumChannel->AddPropagationLossModel(lossModel);
225 spectrumChannel->SetPropagationDelayModel(delayModel);
226
228 phy.SetChannel(spectrumChannel);
229 phy.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}"));
230
231 WifiHelper wifi;
232 wifi.SetStandard(WIFI_STANDARD_80211ax);
233 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
234
235 WifiMacHelper mac;
236 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(Ssid("channel-switching-test")));
237
238 m_staDevice = wifi.Install(phy, mac, m_staNode);
239
240 mac.SetType("ns3::ApWifiMac",
241 "Ssid",
242 SsidValue(Ssid("channel-switching-test")),
243 "EnableBeaconJitter",
244 BooleanValue(false));
245
246 m_apDevice = wifi.Install(phy, mac, m_apNode);
247
248 // Assign fixed streams to random variables in use
250
251 MobilityHelper mobility;
253
254 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
255 positionAlloc->Add(Vector(5.0, 0.0, 0.0));
256 mobility.SetPositionAllocator(positionAlloc);
257
258 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
259 mobility.Install(m_apNode);
260 mobility.Install(m_staNode);
261
262 SendPacket();
263
265 "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/Assoc",
267 Config::ConnectWithoutContext("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxPsduBegin",
269 Config::ConnectWithoutContext("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx",
272 "/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/State/State",
275 "/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/State/State",
277
280
281 NS_TEST_EXPECT_MSG_EQ(+m_assocCount, 2, "STA did not associate twice");
283 2,
284 "The QoS Data frame should have been transmitted twice by the STA");
287 "The QoS Data frame should have been received once by the AP");
288 NS_TEST_EXPECT_MSG_EQ(+m_channelSwitchCount[0], 1, "AP had to perform one channel switch");
289 NS_TEST_EXPECT_MSG_EQ(+m_channelSwitchCount[1], 1, "STA had to perform one channel switch");
290
292}
293
294/**
295 * @ingroup wifi-test
296 * @ingroup tests
297 *
298 * @brief Block Ack Test Suite
299 */
301{
302 public:
304};
305
307 : TestSuite("wifi-channel-switching", Type::UNIT)
308{
309 AddTestCase(new WifiChannelSwitchingTest, TestCase::Duration::QUICK);
310}
311
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:90
AttributeValue implementation for Boolean.
Definition boolean.h:26
an EUI-48 address
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:153
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.
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:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Make it easy to create and manage PHY objects for the spectrum model.
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
AttributeValue implementation for Ssid.
Definition ssid.h:85
Hold variables of type string.
Definition string.h:45
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
AttributeValue implementation for Time.
Definition nstime.h:1431
Hold an unsigned integer type.
Definition uinteger.h:34
helps to create WifiNetDevice objects
static int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by the PHY and MAC aspects ...
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:1587
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:943
void Set(std::string path, const AttributeValue &value)
Definition config.cc:869
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#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:241
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1368
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
@ WIFI_STANDARD_80211ax
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
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:684
static WifiChannelSwitchingTestSuite g_issue211TestSuite
the test suite