A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-emlsr-enabling-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2023 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
10
11#include "ns3/advanced-emlsr-manager.h"
12#include "ns3/boolean.h"
13#include "ns3/config.h"
14#include "ns3/ctrl-headers.h"
15#include "ns3/log.h"
16#include "ns3/mgt-action-headers.h"
17#include "ns3/qos-txop.h"
18#include "ns3/simulator.h"
19#include "ns3/string.h"
20#include "ns3/wifi-net-device.h"
21#include "ns3/wifi-phy.h"
22
23#include <algorithm>
24#include <functional>
25#include <iomanip>
26
27using namespace ns3;
28
29NS_LOG_COMPONENT_DEFINE("WifiEmlsrEnablingTest");
30
33 "Check serialization and deserialization of the EML Operating Mode Notification frame")
34{
35}
36
37void
39{
40 MgtEmlOmn frame;
41
42 // Both EMLSR Mode and EMLMR Mode subfields set to 0 (no link bitmap);
44
45 frame.m_emlControl.emlsrMode = 1;
46 frame.SetLinkIdInBitmap(0);
47 frame.SetLinkIdInBitmap(5);
48 frame.SetLinkIdInBitmap(15);
49
50 // Adding Link Bitmap
52
53 NS_TEST_EXPECT_MSG_EQ((frame.GetLinkBitmap() == std::list<uint8_t>{0, 5, 15}),
54 true,
55 "Unexpected link bitmap");
56
57 auto padding = MicroSeconds(64);
58 auto transition = MicroSeconds(128);
59
63 frame.m_emlsrParamUpdate->transitionDelay =
65
66 // Adding the EMLSR Parameter Update field
68
71 padding,
72 "Unexpected EMLSR Padding Delay");
75 transition,
76 "Unexpected EMLSR Transition Delay");
77}
78
79EmlOmnExchangeTest::EmlOmnExchangeTest(const std::set<uint8_t>& linksToEnableEmlsrOn,
80 Time transitionTimeout)
81 : EmlsrOperationsTestBase("Check EML Notification exchange"),
82 m_checkEmlsrLinksCount(0),
83 m_emlNotificationDroppedCount(0)
84{
85 m_linksToEnableEmlsrOn = linksToEnableEmlsrOn;
88 m_transitionTimeout = transitionTimeout;
89 m_duration = Seconds(0.5);
90}
91
92void
94{
96
98 for (std::size_t linkId = 0; linkId < m_apMac->GetNLinks(); linkId++)
99 {
100 m_apMac->GetWifiPhy(linkId)->SetPostReceptionErrorModel(m_errorModel);
101 }
102
103 m_staMacs[0]->TraceConnectWithoutContext("AckedMpdu",
105 m_staMacs[0]->TraceConnectWithoutContext("DroppedMpdu",
107}
108
109void
111 uint8_t phyId,
112 WifiConstPsduMap psduMap,
113 WifiTxVector txVector,
114 double txPowerW)
115{
116 EmlsrOperationsTestBase::Transmit(mac, phyId, psduMap, txVector, txPowerW);
117 auto linkId = m_txPsdus.back().linkId;
118
119 auto psdu = psduMap.begin()->second;
120
121 switch (psdu->GetHeader(0).GetType())
122 {
124 NS_TEST_EXPECT_MSG_EQ(+linkId, +m_mainPhyId, "AssocReq not sent by the main PHY");
125 CheckEmlCapabilitiesInAssocReq(*psdu->begin(), txVector, linkId);
126 break;
127
129 CheckEmlCapabilitiesInAssocResp(*psdu->begin(), txVector, linkId);
130 break;
131
133 if (auto [category, action] = WifiActionHeader::Peek(psdu->GetPayload(0));
135 action.protectedEhtAction ==
137 {
138 CheckEmlNotification(psdu, txVector, linkId);
139
141 m_staMacs[0]->GetLinkIdByAddress(psdu->GetAddr2()) == linkId)
142 {
143 // transmitted by non-AP MLD, we need to corrupt it
144 m_uidList.push_front(psdu->GetPacket()->GetUid());
146 }
147 break;
148 }
149
150 default:;
151 }
152}
153
154void
156 const WifiTxVector& txVector,
157 uint8_t linkId)
158{
160 mpdu->GetPacket()->PeekHeader(frame);
161
162 const auto& mle = frame.Get<MultiLinkElement>();
163 NS_TEST_ASSERT_MSG_EQ(mle.has_value(), true, "Multi-Link Element must be present in AssocReq");
164
165 NS_TEST_ASSERT_MSG_EQ(mle->HasEmlCapabilities(),
166 true,
167 "Multi-Link Element in AssocReq must have EML Capabilities");
168 NS_TEST_ASSERT_MSG_EQ(mle->IsEmlsrSupported(),
169 true,
170 "EML Support subfield of EML Capabilities in AssocReq must be set to 1");
171 NS_TEST_ASSERT_MSG_EQ(mle->GetEmlsrPaddingDelay(),
172 m_paddingDelay.at(0),
173 "Unexpected Padding Delay in EML Capabilities included in AssocReq");
174 NS_TEST_ASSERT_MSG_EQ(mle->GetEmlsrTransitionDelay(),
175 m_transitionDelay.at(0),
176 "Unexpected Transition Delay in EML Capabilities included in AssocReq");
177}
178
179void
181 const WifiTxVector& txVector,
182 uint8_t linkId)
183{
184 bool sentToEmlsrClient =
185 (m_staMacs[0]->GetLinkIdByAddress(mpdu->GetHeader().GetAddr1()) == linkId);
186
187 if (!sentToEmlsrClient)
188 {
189 // nothing to check
190 return;
191 }
192
194 mpdu->GetPacket()->PeekHeader(frame);
195
196 const auto& mle = frame.Get<MultiLinkElement>();
197 NS_TEST_ASSERT_MSG_EQ(mle.has_value(), true, "Multi-Link Element must be present in AssocResp");
198
199 NS_TEST_ASSERT_MSG_EQ(mle->HasEmlCapabilities(),
200 true,
201 "Multi-Link Element in AssocResp must have EML Capabilities");
202 NS_TEST_ASSERT_MSG_EQ(mle->IsEmlsrSupported(),
203 true,
204 "EML Support subfield of EML Capabilities in AssocResp must be set to 1");
206 mle->GetTransitionTimeout(),
208 "Unexpected Transition Timeout in EML Capabilities included in AssocResp");
209}
210
211void
213 const WifiTxVector& txVector,
214 uint8_t linkId)
215{
216 MgtEmlOmn frame;
217 auto mpdu = *psdu->begin();
218 auto pkt = mpdu->GetPacket()->Copy();
220 pkt->RemoveHeader(frame);
221 NS_LOG_DEBUG(frame);
222
223 bool sentbyNonApMld = m_staMacs[0]->GetLinkIdByAddress(mpdu->GetHeader().GetAddr2()) == linkId;
224
226 1,
227 "EMLSR Mode subfield should be set to 1 (frame sent by non-AP MLD: "
228 << std::boolalpha << sentbyNonApMld << ")");
229
231 0,
232 "EMLMR Mode subfield should be set to 0 (frame sent by non-AP MLD: "
233 << std::boolalpha << sentbyNonApMld << ")");
234
236 true,
237 "Link Bitmap subfield should be present (frame sent by non-AP MLD: "
238 << std::boolalpha << sentbyNonApMld << ")");
239
240 auto setupLinks = m_staMacs[0]->GetSetupLinkIds();
241 std::list<uint8_t> expectedEmlsrLinks;
242 std::set_intersection(setupLinks.begin(),
243 setupLinks.end(),
246 std::back_inserter(expectedEmlsrLinks));
247
248 NS_TEST_EXPECT_MSG_EQ((expectedEmlsrLinks == frame.GetLinkBitmap()),
249 true,
250 "Unexpected Link Bitmap subfield (frame sent by non-AP MLD: "
251 << std::boolalpha << sentbyNonApMld << ")");
252
253 if (!sentbyNonApMld)
254 {
255 // the frame has been sent by the AP MLD
258 0,
259 "EMLSR Parameter Update Control should be set to 0 in frames sent by the AP MLD");
260
261 // as soon as the non-AP MLD receives this frame, it sets the EMLSR links
262 auto delay = WifiPhy::CalculateTxDuration(psdu,
263 txVector,
264 m_staMacs[0]->GetWifiPhy(linkId)->GetPhyBand()) +
265 MicroSeconds(1); // to account for propagation delay
267 }
268
270 +linkId,
271 "EML Notification received on unexpected link (frame sent by non-AP MLD: "
272 << std::boolalpha << sentbyNonApMld << ")");
273}
274
275void
277{
278 const auto& hdr = mpdu->GetHeader();
279
280 if (hdr.IsMgt() && hdr.IsAction())
281 {
282 if (auto [category, action] = WifiActionHeader::Peek(mpdu->GetPacket());
284 action.protectedEhtAction ==
286 {
287 // the EML Operating Mode Notification frame that the non-AP MLD sent has been
288 // acknowledged; after the transition timeout, the EMLSR links have been set
291 this);
292 }
293 }
294}
295
296void
298{
299 const auto& hdr = mpdu->GetHeader();
300
301 if (hdr.IsMgt() && hdr.IsAction())
302 {
303 if (auto [category, action] = WifiActionHeader::Peek(mpdu->GetPacket());
305 action.protectedEhtAction ==
307 {
308 // the EML Operating Mode Notification frame has been dropped. Don't
309 // corrupt it anymore
311 }
312 }
313}
314
315void
317{
319
320 auto setupLinks = m_staMacs[0]->GetSetupLinkIds();
321 std::set<uint8_t> expectedEmlsrLinks;
322 std::set_intersection(setupLinks.begin(),
323 setupLinks.end(),
326 std::inserter(expectedEmlsrLinks, expectedEmlsrLinks.end()));
327
328 NS_TEST_EXPECT_MSG_EQ((expectedEmlsrLinks == m_staMacs[0]->GetEmlsrManager()->GetEmlsrLinks()),
329 true,
330 "Unexpected set of EMLSR links)");
331}
332
333void
335{
338
340 2,
341 "Unexpected number of times CheckEmlsrLinks() is called");
344 1,
345 "Unexpected number of times the EML Notification frame is dropped due to max retry limit");
346
348}
349
351 : TestSuite("wifi-emlsr-enabling", Type::UNIT)
352{
353 AddTestCase(new EmlOperatingModeNotificationTest(), TestCase::Duration::QUICK);
354 AddTestCase(new EmlOmnExchangeTest({1, 2}, MicroSeconds(0)), TestCase::Duration::QUICK);
355 AddTestCase(new EmlOmnExchangeTest({1, 2}, MicroSeconds(2048)), TestCase::Duration::QUICK);
356 AddTestCase(new EmlOmnExchangeTest({0, 1, 2, 3}, MicroSeconds(0)), TestCase::Duration::QUICK);
357 AddTestCase(new EmlOmnExchangeTest({0, 1, 2, 3}, MicroSeconds(2048)),
358 TestCase::Duration::QUICK);
359}
360
Test the exchange of EML Operating Mode Notification frames.
void CheckEmlCapabilitiesInAssocResp(Ptr< const WifiMpdu > mpdu, const WifiTxVector &txVector, uint8_t linkId)
Check the content of the EML Capabilities subfield of the Multi-Link Element included in the Associat...
void TxOk(Ptr< const WifiMpdu > mpdu)
Callback invoked when the non-AP MLD receives the acknowledgment for a transmitted MPDU.
std::list< uint64_t > m_uidList
list of UIDs of packets to corrupt
std::size_t m_checkEmlsrLinksCount
counter for the number of times CheckEmlsrLinks is called (should be two: when the transition timeout...
Ptr< ListErrorModel > m_errorModel
error rate model to corrupt packets at AP MLD
void DoSetup() override
Implementation to do any local setup required for this TestCase.
EmlOmnExchangeTest(const std::set< uint8_t > &linksToEnableEmlsrOn, Time transitionTimeout)
Constructor.
std::size_t m_emlNotificationDroppedCount
counter for the number of times the EML Notification frame sent by the non-AP MLD has been dropped du...
void CheckEmlsrLinks()
Check that the EMLSR mode has been enabled on the expected EMLSR links.
void CheckEmlCapabilitiesInAssocReq(Ptr< const WifiMpdu > mpdu, const WifiTxVector &txVector, uint8_t linkId)
Check the content of the EML Capabilities subfield of the Multi-Link Element included in the Associat...
void TxDropped(WifiMacDropReason reason, Ptr< const WifiMpdu > mpdu)
Callback invoked when the non-AP MLD drops the given MPDU for the given reason.
void CheckEmlNotification(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector, uint8_t linkId)
Check the content of a received EML Operating Mode Notification frame.
void Transmit(Ptr< WifiMac > mac, uint8_t phyId, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW) override
Callback invoked when a FEM passes PSDUs to the PHY.
void DoRun() override
Implementation to actually run this TestCase.
Test EML Operating Mode Notification frame serialization and deserialization.
void DoRun() override
Implementation to actually run this TestCase.
Base class for EMLSR Operations tests.
std::size_t m_nNonEmlsrStations
number of stations to create that do not activate EMLSR
std::size_t m_nEmlsrStations
number of stations to create that activate EMLSR
std::vector< Time > m_paddingDelay
Padding Delay advertised by the non-AP MLD.
std::set< uint8_t > m_linksToEnableEmlsrOn
IDs of the links on which EMLSR mode has to be enabled.
Ptr< ApWifiMac > m_apMac
AP wifi MAC.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
uint8_t m_mainPhyId
ID of the main PHY.
Time m_duration
simulation duration
std::vector< FrameInfo > m_txPsdus
transmitted PSDUs
virtual void Transmit(Ptr< WifiMac > mac, uint8_t phyId, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback invoked when a FEM passes PSDUs to the PHY.
std::vector< Time > m_transitionDelay
Transition Delay advertised by the non-AP MLD.
Time m_transitionTimeout
Transition Timeout advertised by the AP MLD.
std::vector< Ptr< StaWifiMac > > m_staMacs
MACs of the non-AP MLDs.
wifi EMLSR suite to test the procedure for enabling EMLSR mode
Subclass of TestCase class adding the ability to test the serialization and deserialization of a Head...
void TestHeaderSerialization(const T &hdr, Args &&... args)
Serialize the given header in a buffer, then create a new header by deserializing from the buffer and...
void SetList(const std::list< uint64_t > &packetlist)
Implement the header for management frames of type association request.
Implement the header for management frames of type association and reassociation response.
Implement the header for Action frames of type EML Operating Mode Notification.
void SetLinkIdInBitmap(uint8_t linkId)
Set the bit position in the link bitmap corresponding to the given link.
EmlControl m_emlControl
EML Control field.
std::optional< EmlsrParamUpdate > m_emlsrParamUpdate
EMLSR Parameter Update field.
std::list< uint8_t > GetLinkBitmap() const
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:561
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
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
static std::pair< CategoryValue, ActionValue > Peek(Ptr< const Packet > pkt)
Peek an Action header from the given packet.
static std::pair< CategoryValue, ActionValue > Remove(Ptr< Packet > pkt)
Remove an Action header from the given packet.
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition wifi-phy.cc:1563
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#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
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#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_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:1369
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1381
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1345
WifiMacDropReason
The reason why an MPDU was dropped.
Definition wifi-mac.h:71
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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
@ WIFI_MAC_MGT_ACTION
@ WIFI_MAC_MGT_ASSOCIATION_RESPONSE
@ WIFI_MAC_MGT_ASSOCIATION_REQUEST
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Definition wifi-ppdu.h:38
static uint8_t EncodeEmlsrTransitionDelay(Time delay)
static Time DecodeEmlsrTransitionDelay(uint8_t value)
static Time DecodeEmlsrPaddingDelay(uint8_t value)
static uint8_t EncodeEmlsrPaddingDelay(Time delay)
uint8_t emlsrParamUpdateCtrl
EMLSR Parameter Update Control.
std::optional< uint16_t > linkBitmap
EMLSR/EMLMR Link Bitmap.
EMLSR Parameter Update field.
static WifiEmlsrEnablingTestSuite g_wifiEmlsrEnablingTestSuite
the test suite