A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-fils-frame-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 Rami Abdallah
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#include "ns3/ap-wifi-mac.h"
8#include "ns3/assert.h"
9#include "ns3/attribute-container.h"
10#include "ns3/boolean.h"
11#include "ns3/enum.h"
12#include "ns3/error-model.h"
13#include "ns3/log.h"
14#include "ns3/mac48-address.h"
15#include "ns3/mgt-action-headers.h"
16#include "ns3/mgt-headers.h"
17#include "ns3/mobility-helper.h"
18#include "ns3/node-container.h"
19#include "ns3/object-factory.h"
20#include "ns3/rng-seed-manager.h"
21#include "ns3/simulator.h"
22#include "ns3/spectrum-helper.h"
23#include "ns3/string.h"
24#include "ns3/test.h"
25#include "ns3/tuple.h"
26#include "ns3/wifi-mac-header.h"
27#include "ns3/wifi-mac-helper.h"
28#include "ns3/wifi-net-device.h"
29#include "ns3/wifi-psdu.h"
30#include "ns3/wifi-utils.h"
31#include "ns3/yans-wifi-helper.h"
32#include "ns3/yans-wifi-phy.h"
33
34#include <algorithm>
35#include <filesystem>
36#include <iterator>
37#include <optional>
38#include <variant>
39
40using namespace ns3;
41
42/// @ingroup wifi-test
43/// @ingroup tests
44/// @brief Fast Initial Link Setup (FILS) frame Test Suite
45/// Test suite intended to test (de)serialization and timing
46/// of frames associated with FILS procedure.
47/// The test creates a BSS consisting of an AP and client and
48/// and analyzes the timings and contents of frames associated
49/// with FILS procedure.
50
51NS_LOG_COMPONENT_DEFINE("WifiFilsFrameTestSuite");
52
53static const auto DEFAULT_BANDWIDTH = 20;
54static const auto INVALID_CHAN_NUM = 0;
55static const auto DEFAULT_PRIMARY_INDEX = 0;
56static const auto DEFAULT_SIM_STOP_TIME = MilliSeconds(610);
57static const auto DEFAULT_RNG_SEED = 3;
58static const auto DEFAULT_RNG_RUN = 7;
59static const auto DEFAULT_STREAM_INDEX = 100;
60static const auto DUMMY_AP_ADDR = Mac48Address("00:00:00:00:00:10");
61static const auto DEFAULT_STANDARD = WifiStandard::WIFI_STANDARD_80211ax;
62static const auto DEFAULT_BAND = WifiPhyBand::WIFI_PHY_BAND_6GHZ;
63static const auto DEFAULT_SSID = "01234567890123456789012345678901"; // max length (32 bytes)
64static const auto DEFAULT_BCN_INTRVL = 100 * WIFI_TU;
65static const auto DEFAULT_FILS_INTRVL = 20 * WIFI_TU;
66static const auto DEFAULT_TIMING_TOLERANCE = MicroSeconds(100);
67static const auto DEFAULT_UNSOL_PROBE_RESP_EN = false;
68static const auto DEFAULT_PCAP_PREFIX = "ap-fils";
69static const auto DEFAULT_OUTDIR = ".";
70static const auto DEFAULT_ENABLE_PCAP = false;
71static const auto DEFAULT_AP_LOC = Vector(0.01, 0, 0);
72static const auto DEFAULT_CLIENT_LOC = Vector(0, 0, 0);
73static const uint8_t WIFI_11AX_FD_PHY_IDX = 4;
74static const uint8_t WIFI_11BE_FD_PHY_IDX = 5;
75
76/// @brief Wi-Fi FILS frame test parameters
78{
80 MHz_u bw{DEFAULT_BANDWIDTH}; ///< Operation bandwidth
81 std::string ssid{DEFAULT_SSID}; ///< SSID name
82 uint8_t nss{0}; ///< Number of spatial streams
83 Time bcnIntrvl{DEFAULT_BCN_INTRVL}; ///< Time between Beacons
84 Time filsIntrvl{DEFAULT_FILS_INTRVL}; ///< Time between FILS frames
85 bool unsolProbeRespEn{DEFAULT_UNSOL_PROBE_RESP_EN}; ///< Unsolicited Probe Response enable
86 uint8_t expNssFld{0}; ///< Expected NSS field
87 uint8_t expChWidFld{0}; ///< Expected Channel Width field
88};
89
90/// @ingroup wifi-test
91/// @ingroup tests
92/// Test FILS frames
94{
95 public:
96 /// @brief constructor
97 /// @param params the parameters for this test
99
100 /// Transmitted PSDUs
102 {
103 Time timeSt; ///< timestamp
105 };
106
107 private:
108 /// Timing statistic for test validation
110 {
111 size_t cntBcns{0}; ///< Beacon frames count
112 Time bcnTimeSt{0}; ///< last Beacon timestamp
113 size_t cntFilsOrUnsolProbeResps{0}; ///< FILS Discovery or Unsolicited Probe Response count
114 Time filsOrUnsolProbeRespTimeSt{0}; ///< last FILS Discovery or Unsolicited Probe Response
115 ///< timestamp
116 Time filsOrUnsolProbeRespTimeDelta{0}; ///< time between last FILS Discovery or Unsolicited
117 ///< Probe Response and last Beacon
118 };
119
120 /// @brief setup a WifiNetDevice
121 /// @param channel the channel to attach to
122 /// @param isAp whether the device is an AP
123 /// @return the created WifiNetDevice
125
126 /// @brief callback connected to PSDU TX begin trace source
127 /// @param psduMap the transmitted PSDU map
128 /// @param txVector the TXVECTOR
129 /// @param txPowerW the TX power in Watts
130 void PsduTxCallback(WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW);
131
132 /// @brief validate the given FILS Discovery frame
133 /// @param filsDisc the FILS Discovery frame
134 void ValidateFilsDiscFrame(const FilsDiscHeader& filsDisc);
135
136 /// @brief check the correctness of the test
137 void ValidateTest();
138
139 /// @brief Check the number of FILS Discovery frames or unsolicited Probe Response frames
140 /// transmitted since the last Beacon frame
141 /// @param psduCapt information about the transmitted Beacon frame
142 void ValidateCnt(const PsduCapture& psduCapt);
143
144 /// @brief check the timing of the transmitted FILS Discovery or unsolicited Probe Response
145 /// @param psduCapt information about the FILS Discovery or unsolicited Probe Response
146 void ValidateTiming(const PsduCapture& psduCapt);
147
148 /// @brief Get the FILS Discovery header, if present in the given frame
149 /// @param psduCapt information about the given frame
150 /// @return the FILS Discovery header, if present
151 std::optional<FilsDiscHeader> GetFilsDiscFrame(const PsduCapture& psduCapt);
152
153 void DoSetup() override;
154 void DoTeardown() override;
155 void DoRun() override;
156
157 TimeStats m_timeStats; ///< collected timing statistic
158 Ptr<WifiNetDevice> m_ap{nullptr}; ///< AP device
159 Ptr<WifiNetDevice> m_client{nullptr}; ///< Client device
160 WifiFilsFrameTestParams m_params; ///< Test parameters
161 std::vector<PsduCapture> m_txPsdus{}; ///< TX PSDUS frame infos
162};
163
165 : TestCase("WifiFilsFrameTest"),
166 m_params(params)
167{
168}
169
172{
173 NodeContainer node;
175 WifiMacHelper mac;
176 WifiHelper wifi;
177 MobilityHelper mobility;
178 node.Create(1);
179 phy.SetChannel(channel);
182 ';'>
183 channelValue;
184 channelValue.Set(WifiPhy::ChannelSegments{
186 phy.Set("ChannelSettings", channelValue);
187 phy.Set("Antennas", UintegerValue(m_params.nss));
188 phy.Set("MaxSupportedTxSpatialStreams", UintegerValue(m_params.nss));
189 phy.Set("MaxSupportedRxSpatialStreams", UintegerValue(m_params.nss));
190
191 wifi.SetStandard(m_params.standard);
192 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager");
193
194 if (isAp)
195 {
196 mac.SetType("ns3::ApWifiMac",
197 "Ssid",
199 "BeaconGeneration",
200 BooleanValue(true),
201 "BeaconInterval",
203 "FdBeaconInterval6GHz",
205 "SendUnsolProbeResp",
207 }
208 else
209 {
210 mac.SetType("ns3::StaWifiMac",
211 "Ssid",
213 "ActiveProbing",
214 BooleanValue(false));
215 }
216 auto testDevs = wifi.Install(phy, mac, node);
218 auto dev = DynamicCast<WifiNetDevice>(testDevs.Get(0));
219 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
220 mobility.Install(node);
221 node.Get(0)->GetObject<MobilityModel>()->SetPosition(isAp ? DEFAULT_AP_LOC
223 phy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO);
224 if (isAp && DEFAULT_ENABLE_PCAP)
225 {
226 auto path = std::filesystem::path(DEFAULT_OUTDIR);
227 phy.EnablePcap(path.append(DEFAULT_PCAP_PREFIX).string(), testDevs);
228 }
229 return dev;
230}
231
232void
234{
235 auto psdu = psduMap[SU_STA_ID];
236 m_txPsdus.push_back({Simulator::Now(), psdu});
237 NS_LOG_DEBUG("MPDU " << **psdu->begin());
238}
239
240void
242{
245 auto channel = YansWifiChannelHelper::Default().Create();
246 // setup devices and capabilities
247 m_ap = SetupDevice(channel, true);
248 m_client = SetupDevice(channel, false);
249 // setup AP TX PSDU trace
250 auto phy = m_ap->GetPhy();
251 phy->TraceConnectWithoutContext("PhyTxPsduBegin",
253}
254
255void
257{
258 if (m_timeStats.cntBcns > 0)
259 {
262 static_cast<std::size_t>((m_params.bcnIntrvl / m_params.filsIntrvl).GetHigh() - 1),
263 "Number of FILS or Unsolicited Response Frames per Beacon Interval is not expected");
264 }
265 m_timeStats.bcnTimeSt = psduCapt.timeSt;
268}
269
270void
286
287std::optional<FilsDiscHeader>
289{
290 auto pkt = psduCapt.psdu->GetPayload(0)->Copy();
291 WifiActionHeader actionHdr;
292 pkt->RemoveHeader(actionHdr);
293 if ((actionHdr.GetCategory() == WifiActionHeader::PUBLIC) &&
295 {
296 FilsDiscHeader filsDisc;
297 pkt->PeekHeader(filsDisc);
298 return filsDisc;
299 }
300 return std::nullopt;
301}
302
303void
305{
306 for (const auto& psduCapt : m_txPsdus)
307 {
308 auto hdr = psduCapt.psdu->GetHeader(0);
309 if (hdr.IsBeacon())
310 {
311 ValidateCnt(psduCapt);
312 }
313 else
314 {
315 if (m_params.unsolProbeRespEn && hdr.IsProbeResp() && hdr.GetAddr1().IsBroadcast())
316 { // Unsolicited Probe Response frame
317 ValidateTiming(psduCapt);
318 }
319 else if (hdr.IsAction())
320 { // possible FILS Discovery frame
321 if (auto filsDisc = GetFilsDiscFrame(psduCapt))
322 {
323 ValidateFilsDiscFrame(filsDisc.value());
324 ValidateTiming(psduCapt);
325 }
326 }
327 }
329 {
330 break;
331 }
332 }
333}
334
335void
337{
338 NS_TEST_ASSERT_MSG_EQ(filsDisc.GetSsid(), m_params.ssid, "FILS Discovery frame SSID mismatch");
339 NS_TEST_ASSERT_MSG_EQ(+filsDisc.m_fdCap->m_chWidth,
341 "FILS Discovery frame channel width mismatch");
342 NS_TEST_ASSERT_MSG_EQ(+filsDisc.m_fdCap->m_maxNss,
344 "FILS Discovery frame NSS mismatch");
345 NS_TEST_ASSERT_MSG_EQ(+filsDisc.m_fdCap->m_phyIdx,
346 ((m_params.standard == WifiStandard::WIFI_STANDARD_80211be)
349 "FILS Discovery frame PHY idx mismatch");
350}
351
352void
360
361void
363{
364 m_ap->Dispose();
365 m_ap = nullptr;
366 m_client->Dispose();
367 m_client = nullptr;
368 m_txPsdus.clear();
369}
370
371/// Testcases for FILS frame test
383
386{
388 switch (tc)
389 {
391 params.bw = MHz_u{20};
392 params.ssid = DEFAULT_SSID;
393 params.nss = 1;
394 params.expChWidFld = 0;
395 params.expNssFld = 0;
396 break;
398 params.bw = MHz_u{20};
399 params.ssid = "BW20MHZ_NSS3";
400 params.nss = 3;
401 params.filsIntrvl = 15 * WIFI_TU;
402 params.expChWidFld = 0;
403 params.expNssFld = 2;
404 break;
406 params.bw = MHz_u{40};
407 params.ssid = "BW40MHZ_NSS2";
408 params.nss = 2;
409 params.filsIntrvl = 10 * WIFI_TU;
410 params.expChWidFld = 1;
411 params.expNssFld = 1;
412 break;
414 params.bw = MHz_u{80};
415 params.ssid = "BW80MHZ_NSS2";
416 params.nss = 2;
417 params.filsIntrvl = 7 * WIFI_TU;
418 params.expChWidFld = 2;
419 params.expNssFld = 1;
420 break;
422 params.bw = MHz_u{160};
423 params.ssid = "BW160MHZ_NSS2";
424 params.nss = 2;
425 params.filsIntrvl = 5 * WIFI_TU;
426 params.expChWidFld = 3;
427 params.expNssFld = 1;
428 break;
430 params.bw = MHz_u{160};
431 params.ssid = "BW160MHZ_NSS2";
432 params.nss = 2;
433 params.unsolProbeRespEn = true;
434 params.expChWidFld = 3;
435 params.expNssFld = 1;
436 break;
438 params.standard = WifiStandard::WIFI_STANDARD_80211be;
439 params.bw = MHz_u{320};
440 params.ssid = "BW320MHZ_NSS3";
441 params.nss = 3;
442 params.filsIntrvl = 20 * WIFI_TU;
443 params.expChWidFld = 4;
444 params.expNssFld = 2;
445 break;
446 default:
447 NS_ABORT_MSG("Testcase is unsupported");
448 break;
449 }
450 return params;
451}
452
453/// @ingroup wifi-test
454/// @ingroup tests
455/// @brief WiFi FILS frame Test Suite
457{
458 public:
460};
461
479
Ptr< WifiNetDevice > m_ap
AP device.
void DoRun() override
Implementation to actually run this TestCase.
Ptr< WifiNetDevice > m_client
Client device.
void PsduTxCallback(WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
callback connected to PSDU TX begin trace source
Ptr< WifiNetDevice > SetupDevice(Ptr< YansWifiChannel > &channel, bool isAp)
setup a WifiNetDevice
std::vector< PsduCapture > m_txPsdus
TX PSDUS frame infos.
void ValidateCnt(const PsduCapture &psduCapt)
Check the number of FILS Discovery frames or unsolicited Probe Response frames transmitted since the ...
void ValidateTiming(const PsduCapture &psduCapt)
check the timing of the transmitted FILS Discovery or unsolicited Probe Response
TimeStats m_timeStats
collected timing statistic
void ValidateFilsDiscFrame(const FilsDiscHeader &filsDisc)
validate the given FILS Discovery frame
void ValidateTest()
check the correctness of the test
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
WifiFilsFrameTest(const WifiFilsFrameTestParams &params)
constructor
WifiFilsFrameTestParams m_params
Test parameters.
std::optional< FilsDiscHeader > GetFilsDiscFrame(const PsduCapture &psduCapt)
Get the FILS Discovery header, if present in the given frame.
WiFi FILS frame Test Suite.
A container for one type of attribute.
void Set(const T &c)
Copy items from container c.
AttributeValue implementation for Boolean.
Definition boolean.h:26
Implement the FILS (Fast Initial Link Setup) action frame.
const std::string & GetSsid() const
OptFieldWithPresenceInd< FdCapability > m_fdCap
FD Capability.
an EUI-48 address
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
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.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition packet.cc:120
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 void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
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
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
AttributeValue implementation for Ssid.
Definition ssid.h:85
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
int64_t GetTimeStep() const
Get the raw time value, in the current resolution unit.
Definition nstime.h:434
AttributeValue implementation for Time.
Definition nstime.h:1432
AttributeValue implementation for Tuple.
Definition tuple.h:67
Hold an unsigned integer type.
Definition uinteger.h:34
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
CategoryValue GetCategory() const
Return the category value.
ActionValue GetAction() const
Return the action value.
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.
@ DLT_IEEE802_11_RADIO
Include Radiotap link layer information.
std::vector< ChannelTuple > ChannelSegments
segments identifying an operating channel
Definition wifi-phy.h:943
Ptr< const Packet > GetPayload(std::size_t i) const
Get the payload of the i-th MPDU.
Definition wifi-psdu.cc:286
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
static YansWifiChannelHelper Default()
Create a channel helper in a default working state.
Ptr< YansWifiChannel > Create() const
Make it easy to create and manage PHY objects for the YANS model.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:134
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition test.h:327
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1357
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
const Time WIFI_TU
Wi-Fi Time Unit value in microseconds (see IEEE 802.11-2020 sec.
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
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Definition wifi-ppdu.h:38
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Ptr< const WifiPsdu > psdu
PSDU.
Timing statistic for test validation.
Time filsOrUnsolProbeRespTimeDelta
time between last FILS Discovery or Unsolicited Probe Response and last Beacon
Time bcnTimeSt
last Beacon timestamp
Time filsOrUnsolProbeRespTimeSt
last FILS Discovery or Unsolicited Probe Response timestamp
size_t cntFilsOrUnsolProbeResps
FILS Discovery or Unsolicited Probe Response count.
size_t cntBcns
Beacon frames count.
Wi-Fi FILS frame test parameters.
Time filsIntrvl
Time between FILS frames.
uint8_t nss
Number of spatial streams.
std::string ssid
SSID name.
uint8_t expNssFld
Expected NSS field.
bool unsolProbeRespEn
Unsolicited Probe Response enable.
Time bcnIntrvl
Time between Beacons.
MHz_u bw
Operation bandwidth.
WifiStandard standard
Standard.
uint8_t expChWidFld
Expected Channel Width field.
static const auto DEFAULT_SSID
static const auto DUMMY_AP_ADDR
static const auto DEFAULT_UNSOL_PROBE_RESP_EN
static const auto DEFAULT_BANDWIDTH
Fast Initial Link Setup (FILS) frame Test Suite Test suite intended to test (de)serialization and tim...
static const auto DEFAULT_STREAM_INDEX
static const auto DEFAULT_STANDARD
static const uint8_t WIFI_11BE_FD_PHY_IDX
static const auto INVALID_CHAN_NUM
WifiFilsFrameTestCase
Testcases for FILS frame test.
static const auto DEFAULT_RNG_RUN
static const auto DEFAULT_PRIMARY_INDEX
static WifiFilsFrameTestSuite g_WifiFilsFrameTestSuite
static const uint8_t WIFI_11AX_FD_PHY_IDX
static const auto DEFAULT_BCN_INTRVL
static const auto DEFAULT_AP_LOC
static const auto DEFAULT_OUTDIR
static const auto DEFAULT_CLIENT_LOC
static const auto DEFAULT_BAND
WifiFilsFrameTestParams WifiFilsFrameTestBuildCase(const WifiFilsFrameTestCase &tc)
static const auto DEFAULT_ENABLE_PCAP
static const auto DEFAULT_TIMING_TOLERANCE
static const auto DEFAULT_FILS_INTRVL
static const auto DEFAULT_RNG_SEED
static const auto DEFAULT_PCAP_PREFIX
static const auto DEFAULT_SIM_STOP_TIME