A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-emlsr-link-switch-test.h
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
9#ifndef WIFI_EMLSR_LINK_SWITCH_TEST_H
10#define WIFI_EMLSR_LINK_SWITCH_TEST_H
11
13
14#include <list>
15
16using namespace ns3;
17using namespace std::string_literals;
18
19// forward declaration
20namespace ns3
21{
23}
24
25/**
26 * @ingroup wifi-test
27 * @ingroup tests
28 *
29 * @brief Test the switching of PHYs on EMLSR clients.
30 *
31 * An AP MLD and an EMLSR client setup 3 links, on which EMLSR mode is enabled. The AP MLD
32 * transmits 4 QoS data frames (one after another, each protected by ICF):
33 *
34 * - the first one on the link used for ML setup, hence no PHY switch occurs
35 * - the second one on another link, thus causing the main PHY to switch link
36 * - the third one on the remaining link, thus causing the main PHY to switch link again
37 * - the fourth one on the link used for ML setup
38 *
39 * Afterwards, the EMLSR client transmits 2 QoS data frames; the first one on the link used for
40 * ML setup (hence, no RTS is sent), the second one on another link.
41 */
43{
44 public:
45 /**
46 * Parameters for the EMLSR link switching test
47 */
48 struct Params
49 {
50 bool
51 switchAuxPhy; //!< whether AUX PHY should switch channel to operate on the link on which
52 //!< the Main PHY was operating before moving to the link of the Aux PHY
53 bool resetCamStateAndInterruptSwitch; //!< this variable controls two boolean values that
54 //!< are either both set to true or both set to false;
55 //!< the first value controls whether to reset the
56 //!< state of the ChannelAccessManager associated
57 //!< with the link on which the main PHY has just
58 //!< switched to, the second value controls whether
59 //!< a main PHY channel switch can be interrupted
60 MHz_u auxPhyMaxChWidth; //!< max channel width supported by aux PHYs
61 };
62
63 /**
64 * Constructor
65 *
66 * @param params parameters for the EMLSR link switching test
67 */
68 EmlsrLinkSwitchTest(const Params& params);
69
70 ~EmlsrLinkSwitchTest() override = default;
71
72 protected:
73 void DoSetup() override;
74 void DoRun() override;
75 void Transmit(Ptr<WifiMac> mac,
76 uint8_t phyId,
77 WifiConstPsduMap psduMap,
78 WifiTxVector txVector,
79 double txPowerW) override;
80
81 /**
82 * Check that the simulation produced the expected results.
83 */
84 void CheckResults();
85
86 /**
87 * Check that the Main PHY (and possibly the Aux PHY) correctly switches channel when the
88 * reception of an ICF ends.
89 *
90 * @param psduMap the PSDU carrying the MU-RTS TF
91 * @param txVector the TXVECTOR used to send the PPDU
92 * @param linkId the ID of the given link
93 */
95 const WifiTxVector& txVector,
96 uint8_t linkId);
97
98 /**
99 * Check that appropriate actions are taken by the AP MLD transmitting a PPDU containing
100 * QoS data frames to the EMLSR client on the given link.
101 *
102 * @param psduMap the PSDU(s) carrying QoS data frames
103 * @param txVector the TXVECTOR used to send the PPDU
104 * @param linkId the ID of the given link
105 */
106 void CheckQosFrames(const WifiConstPsduMap& psduMap,
107 const WifiTxVector& txVector,
108 uint8_t linkId);
109
110 /**
111 * Check that appropriate actions are taken by the EMLSR client transmitting a PPDU containing
112 * an RTS frame to the AP MLD on the given link.
113 *
114 * @param psduMap the PSDU carrying RTS frame
115 * @param txVector the TXVECTOR used to send the PPDU
116 * @param linkId the ID of the given link
117 */
118 void CheckRtsFrame(const WifiConstPsduMap& psduMap,
119 const WifiTxVector& txVector,
120 uint8_t linkId);
121
122 private:
123 bool m_switchAuxPhy; /**< whether AUX PHY should switch channel to operate on the link on which
124 the Main PHY was operating before moving to the link of Aux PHY */
125 bool
126 m_resetCamStateAndInterruptSwitch; /**< whether to reset the state of the
127 ChannelAccessManager associated with the link on which the main PHY
128 has just switched to and whether main PHY switch can be interrupted */
129 MHz_u m_auxPhyMaxChWidth; //!< max channel width supported by aux PHYs
130 std::size_t m_countQoSframes; //!< counter for QoS data frames
131 std::size_t m_countIcfFrames; //!< counter for ICF frames
132 std::size_t m_countRtsFrames; //!< counter for RTS frames
133 std::size_t m_txPsdusPos; //!< position in the vector of TX PSDUs of the first ICF
134 Ptr<ListErrorModel> m_errorModel; ///< error rate model to corrupt packets at AP MLD
135};
136
137/**
138 * @ingroup wifi-test
139 * @ingroup tests
140 *
141 * @brief Test CCA busy notifications on EMLSR clients.
142 *
143 * SwitchAuxPhy is set to true, so that the aux PHY starts switching when the main PHY switch is
144 * completed.
145 *
146 * - Main PHY switches to a link on which an aux PHY is operating. Right after the start of the
147 * channel switch, the AP transmits a frame to another device on the aux PHY link. Verify that,
148 * once the main PHY is operating on the new link, the channel access manager on that link is
149 * notified of CCA busy until the end of the transmission
150 * - When the main PHY switch is completed, the aux PHY switches to a link on which no PHY is
151 * operating. Before the aux PHY starts switching, the AP starts transmitting a frame to another
152 * device on the link on which no PHY is operating. Verify that, once the aux PHY is operating
153 * on the new link, the channel access manager on that link is notified of CCA busy until the
154 * end of the transmission
155 */
157{
158 public:
159 /**
160 * Constructor
161 *
162 * @param auxPhyMaxChWidth max channel width supported by aux PHYs
163 */
164 EmlsrCcaBusyTest(MHz_u auxPhyMaxChWidth);
165
166 ~EmlsrCcaBusyTest() override = default;
167
168 protected:
169 void DoSetup() override;
170 void DoRun() override;
171
172 private:
173 void StartTraffic() override;
174
175 /**
176 * Make the other MLD transmit a packet to the AP on the given link.
177 *
178 * @param linkId the ID of the given link
179 */
180 void TransmitPacketToAp(uint8_t linkId);
181
182 /**
183 * Perform checks after that the preamble of the first PPDU has been received.
184 */
185 void CheckPoint1();
186
187 /**
188 * Perform checks after that the main PHY completed the link switch.
189 */
190 void CheckPoint2();
191
192 /**
193 * Perform checks after that the aux PHY completed the link switch.
194 */
195 void CheckPoint3();
196
197 MHz_u m_auxPhyMaxChWidth; //!< max channel width supported by aux PHYs
198 Time m_channelSwitchDelay; //!< the PHY channel switch delay
199 uint8_t m_currMainPhyLinkId; //!< the ID of the link the main PHY switches from
200 uint8_t m_nextMainPhyLinkId; //!< the ID of the link the main PHY switches to
201};
202
203/**
204 * @ingroup wifi-test
205 * @ingroup tests
206 *
207 * @brief Test ML setup and data exchange between an AP MLD and a single link EMLSR client.
208 *
209 * A single link EMLSR client performs ML setup with an AP MLD having three links and then enables
210 * EMLSR mode on the unique link. A Block Ack agreement is established (for both the downlink and
211 * uplink directions) and QoS data frames (aggregated in an A-MPDU) are transmitted by both the
212 * AP MLD and the EMLSR client.
213 *
214 * It is checked that:
215 * - the expected sequence of frames is transmitted, including ICFs before downlink transmissions
216 * - EMLSR mode is enabled on the single EMLSR link
217 * - the address of the EMLSR client is seen as an MLD address
218 * - the AP MLD starts the transition delay timer at the end of each TXOP
219 */
221{
222 public:
223 /**
224 * Constructor.
225 *
226 * @param switchAuxPhy whether aux PHYs switch link
227 * @param auxPhyTxCapable whether aux PHYs are TX capable
228 */
229 SingleLinkEmlsrTest(bool switchAuxPhy, bool auxPhyTxCapable);
230
231 protected:
232 void DoSetup() override;
233 void DoRun() override;
234
235 void Transmit(Ptr<WifiMac> mac,
236 uint8_t phyId,
237 WifiConstPsduMap psduMap,
238 WifiTxVector txVector,
239 double txPowerW) override;
240
241 /// Actions and checks to perform upon the transmission of each frame
242 struct Events
243 {
244 /**
245 * Constructor.
246 *
247 * @param type the frame MAC header type
248 * @param f function to perform actions and checks
249 */
251 std::function<void(Ptr<const WifiPsdu>, const WifiTxVector&)>&& f = {})
252 : hdrType(type),
253 func(f)
254 {
255 }
256
257 WifiMacType hdrType; ///< MAC header type of frame being transmitted
258 std::function<void(Ptr<const WifiPsdu>, const WifiTxVector&)>
259 func; ///< function to perform actions and checks
260 };
261
262 private:
263 bool m_switchAuxPhy; //!< whether aux PHYs switch link
264 bool m_auxPhyTxCapable; //!< whether aux PHYs are TX capable
265 std::list<Events> m_events; //!< list of events for a test run
266 std::list<Events>::const_iterator m_eventIt; //!< iterator over the list of events
267};
268
269/**
270 * @ingroup wifi-test
271 * @ingroup tests
272 *
273 * @brief Check ICF reception while main PHY is switching.
274 *
275 * An AP MLD and an EMLSR client, both having 3 links, are considered in this test. Aux PHYs are
276 * not TX capable and do not switch links; the preferred link is link 0. In order to control link
277 * switches, a TID-to-Link mapping is configured so that TIDs 0 and 3 are mapped onto link 1 in the
278 * DL direction, while TID 0 is mapped to link 1 and TID 3 is mapped to link 2 in the UL direction.
279 * In this way, the AP MLD always requests channel access on link 1, while the EMLSR client requests
280 * channel access on link 1 or link 2, depending on the TID. This test consists in having the AP MLD
281 * and the EMLSR client gain channel access simultaneously: the AP MLD starts transmitting an ICF,
282 * while the main PHY starts switching to the link on which the EMLSR client gained channel access,
283 * which could be either the link on which the ICF is being transmitted or another one, depending
284 * on the TID of the MPDU the EMLSR client has to transmit.
285 *
286 * The channel switch delay for the main PHY varies across test scenarios and is computed so that
287 * the channel switch terminates during one of the different steps of the reception of the ICF:
288 * during preamble detection period, before the PHY header end, before the MAC header end, before
289 * the padding start and after the padding start.
290 *
291 \verbatim
292 ┌────────┬──────┬──────┬────────────────────┬───────┐
293 │PREAMBLE│ PHY │ MAC │ MAC PAYLOAD │ │
294 │ DETECT │HEADER│HEADER│(COMMON & USER INFO)│PADDING│
295 └────────┴──────┴──────┴────────────────────┴───────┘
296 \endverbatim
297 *
298 * All the combinations of the following are tested:
299 * - main PHY switches to the same link as ICF or to another link
300 * - channel switch can be interrupted or not
301 * - MAC header reception information is available and can be used or not
302 *
303 * In all the cases, we check that the EMLSR client responds to the ICF:
304 * - if the main PHY switches to the same link as the ICF, connecting the main PHY to the link is
305 * postponed until the end of the ICF
306 * - if the main PHY switches to another link, the UL TXOP does not start because it is detected
307 * that a frame which could be an ICF is being received on another link
308 *
309 * At the end of the DL TXOP, it is checked that:
310 * - if the KeepMainPhyAfterDlTxop attribute of the AdvancedEmlsrManager is false, the main PHY
311 * switches back to the preferred link
312 * - if the KeepMainPhyAfterDlTxop attribute of the AdvancedEmlsrManager is true, the main PHY
313 * stays on the current link to start an UL TXOP, if the UL frame can be sent on the same link
314 * as the DL frame, or switches back to the preferred link, otherwise
315 *
316 * At the end of the UL TXOP, the main PHY returns to the preferred link.
317 *
318 * It is also checked that the in-device interference generated by every transmission of the EMLSR
319 * client is tracked by all the PHY interfaces of all the PHYs but the PHY that is transmitting
320 * for the entire duration of the transmission.
321 */
323{
324 public:
325 /// Constructor.
327
328 /**
329 * Enumeration indicating the duration of a main PHY channel switch compared to the ICF fields
330 */
340
341 protected:
342 void DoSetup() override;
343 void DoRun() override;
344 void Transmit(Ptr<WifiMac> mac,
345 uint8_t phyId,
346 WifiConstPsduMap psduMap,
347 WifiTxVector txVector,
348 double txPowerW) override;
349
350 /// Runs a test case and invokes itself for the next test case
351 void RunOne();
352
353 /**
354 * Callback connected to the EmlsrLinkSwitch trace source of the StaWifiMac of the EMLSR client.
355 *
356 * @param linkId the ID of the link which the PHY is connected to/disconnected from
357 * @param phy a pointer to the PHY that is connected to/disconnected from the given link
358 * @param connected true if the PHY is connected, false if the PHY is disconnected
359 */
360 void EmlsrLinkSwitchCb(uint8_t linkId, Ptr<WifiPhy> phy, bool connected);
361
362 /**
363 * Generate noise on all the links of the given MAC for the given time duration. This is used
364 * to align the EDCA backoff boundary on all the links for the given MAC.
365 *
366 * @param mac the given MAC
367 * @param duration the given duration
368 */
369 void GenerateNoiseOnAllLinks(Ptr<WifiMac> mac, Time duration);
370
371 /**
372 * Check that the in-device interference generated by a transmission of the given duration
373 * on the given link is tracked by all the PHY interfaces of all the PHYs but the PHY that
374 * is transmitting.
375 *
376 * @param testStr the test string
377 * @param linkId the ID of the given link
378 * @param duration the duration of the transmission
379 */
380 void CheckInDeviceInterference(const std::string& testStr, uint8_t linkId, Time duration);
381
382 /// Actions and checks to perform upon the transmission of each frame
383 struct Events
384 {
385 /**
386 * Constructor.
387 *
388 * @param type the frame MAC header type
389 * @param f function to perform actions and checks
390 */
392 std::function<void(Ptr<const WifiPsdu>, const WifiTxVector&, uint8_t)>&& f = {})
393 : hdrType(type),
394 func(f)
395 {
396 }
397
398 WifiMacType hdrType; ///< MAC header type of frame being transmitted
399 std::function<void(Ptr<const WifiPsdu>, const WifiTxVector&, uint8_t)>
400 func; ///< function to perform actions and checks
401 };
402
403 /// Store information about a main PHY switch
405 {
406 Time time; ///< the time the main PHY left/was connected to a link
407 uint8_t linkId; ///< the ID of the link the main PHY switched from/to
408 };
409
410 private:
411 void StartTraffic() override;
412
414 BEFORE_PHY_HDR_END}; //!< index to iterate over channel switch durations
415 uint8_t m_testIndex{0}; //!< index to iterate over test scenarios
416 std::string m_testStr; //!< test scenario description
417 bool m_setupDone{false}; //!< whether association, BA, ... have been done
418 std::optional<MainPhySwitchInfo> m_switchFrom; //!< info for main PHY leaving a link
419 std::optional<MainPhySwitchInfo> m_switchTo; //!< info for main PHY connected to a link
420 std::array<WifiSpectrumBandInfo, 3> m_bands; //!< bands of the 3 frequency channels
421 std::list<Events> m_events; //!< list of events for a test run
422 std::size_t m_processedEvents{0}; //!< number of processed events
423 const uint8_t m_linkIdForTid3{2}; //!< ID of the link on which TID 3 is mapped
424};
425
426/**
427 * @ingroup wifi-test
428 * @ingroup tests
429 *
430 * @brief Switch main PHY back timer test
431 *
432 * An AP MLD and an EMLSR client, both having 3 links, are considered in this test. Aux PHYs are
433 * not TX capable, do not switch links and support up to the HT modulation class; the preferred link
434 * is link 2. In order to control link switches, a TID-to-Link mapping is configured so that TID 0
435 * is mapped onto link 1 and TID 4 is mapped onto link 0 (for both DL and UL). In this test, the
436 * main PHY switches to link 1 to start an UL TXOP but, while the main PHY is switching or shortly
437 * after the channel switch ends, the AP MLD transmits a QoS Data broadcast frame on link 1 using a
438 * modulation supported by the aux PHYs. Different situations are tested and it is verified that
439 * the main PHY switches back to the preferred link as expected. Scenarios:
440 *
441 * - RXSTART_WHILE_SWITCH_NO_INTERRUPT: the AP MLD transmits an HT PPDU while the main PHY is
442 * switching; at the end of the PHY header reception (while the main PHY is still switching), the
443 * MAC of the EMLSR client receives the RX start notification, which indicates that the modulation
444 * is HT (hence the PPDU does not carry an ICF) and the PPDU duration exceeds the switch main PHY
445 * back delay. The EMLSR client decides to switch the main PHY back to the preferred link (with
446 * reason RX_END), but the actual main PHY switch is postponed until the ongoing channel switch
447 * terminates.
448 * - RXSTART_WHILE_SWITCH_INTERRUPT: same as previous scenario, except that the main PHY switch can
449 * be interrupted, hence the main PHY switches back to the preferred link as soon as the reception
450 * of the PHY header ends.
451 * - RXSTART_AFTER_SWITCH_HT_PPDU: the AP MLD transmits an HT PPDU some time after the main PHY
452 * starts switching to link 1; the delay is computed so that the RX START notification is sent
453 * after that the main PHY has completed the channel switch. When the main PHY completes the
454 * switch to link 1, it is determined that the PPDU being received (using HT modulation) cannot
455 * be an ICF, hence the main PHY is connected to link 1. Connecting the main PHY to link 1
456 * triggers a CCA busy notification until the end of the PPDU (we assume this information is
457 * available from the PHY header decoded by the aux PHY), thus the main PHY switches back to the
458 * preferred link (with reason BUSY_END).
459 * - NON_HT_PPDU_DONT_USE_MAC_HDR: the AP MLD transmits a non-HT PPDU on link 1 (it does not really
460 * matter if the RX START notification is sent before or after the end of main PHY switch). When
461 * the main PHY completes the switch to link 1, it is detected that the aux PHY on link 1 is
462 * receiving a PPDU which may be an ICF (the modulation is non-HT), hence the main PHY is not
463 * connected to link 1 until the end of the PPDU reception (MAC header info is not used). At that
464 * time, it is detected that the PPDU does not contain an ICF, but it is determined that channel
465 * access can be gained before the end of the switch main PHY back timer, hence the main PHY stays
466 * on link 1 and transmits its unicast data frame. The start of the UL TXOP cancels the main PHY
467 * switch back timer and the main PHY switches back to the preferred link at the end of the TXOP.
468 * - NON_HT_PPDU_USE_MAC_HDR: same as previous scenario, except that the MAC header info can be
469 * used. After completing the channel switch, the main PHY is not connected to link 1 because the
470 * non-HT PPDU being received may be an ICF. When the MAC header info is notified, it is detected
471 * that the PPDU does not contain an ICF, channel access would not be gained before the end of the
472 * switch main PHY back timer and therefore the main PHY switches back to the preferred link (with
473 * reason RX_END).
474 * - LONG_SWITCH_BACK_DELAY_DONT_USE_MAC_HDR: same as the NON_HT_PPDU_DONT_USE_MAC_HDR scenario,
475 * except that the switch main PHY back delay is longer and exceeds the PPDU duration, but it is
476 * does not exceed the PPDU duration plus AIFS and the backoff slots. Therefore, at the end of the
477 * PPDU reception, it is determined that the backoff counter will not reach zero before the end of
478 * the switch main PHY back timer plus a channel switch delay and the main PHY switches back to
479 * the preferred link (with reason BACKOFF_END).
480 * - LONG_SWITCH_BACK_DELAY_USE_MAC_HDR: same as the NON_HT_PPDU_USE_MAC_HDR scenario,
481 * except that the switch main PHY back delay is longer and exceeds the PPDU duration, but it
482 * does not exceed the PPDU duration plus AIFS and the backoff slots. Therefore, at the end of the
483 * MAC header reception, it is determined that the backoff counter will not reach zero before the
484 * end of the switch main PHY back timer plus a channel switch delay and the main PHY switches
485 * back to the preferred link (with reason BACKOFF_END).
486 *
487 * Except for the NON_HT_PPDU_DONT_USE_MAC_HDR case, in which the main PHY stays on link 1 and
488 * transmits a data frame, receives the Ack and switches back to the preferred link at the TXOP end,
489 * in all other cases the main PHY switches back to the preferred link without sending a frame on
490 * link 1. A few microseconds after starting the switch to the preferred link, a frame with TID 4
491 * is queued. If interrupt switching is enabled, the switch to the preferred link is interrupted
492 * and the main PHY switches to link 0, where it transmits the data frame with TID 4 as soon as
493 * completing the switch. Afterwards, the main PHY switches back to the preferred link and, except
494 * for the NON_HT_PPDU_DONT_USE_MAC_HDR case, it switches to link 1 to transmit the queued frame
495 * with TID 0.
496 */
498{
499 public:
500 /// Constructor.
502
503 /**
504 * Enumeration indicating the tested scenario
505 */
517
518 protected:
519 void DoSetup() override;
520 void DoRun() override;
521 void Transmit(Ptr<WifiMac> mac,
522 uint8_t phyId,
523 WifiConstPsduMap psduMap,
524 WifiTxVector txVector,
525 double txPowerW) override;
526 void MainPhySwitchInfoCallback(std::size_t index, const EmlsrMainPhySwitchTrace& info) override;
527
528 /// Insert events corresponding to the UL TXOP to transmit the QoS Data frame with TID 4
530
531 /// Runs a test case and invokes itself for the next test case
532 void RunOne();
533
534 /// Actions and checks to perform upon the transmission of each frame
535 struct Events
536 {
537 /**
538 * Constructor.
539 *
540 * @param type the frame MAC header type
541 * @param f function to perform actions and checks
542 */
544 std::function<void(Ptr<const WifiPsdu>, const WifiTxVector&, uint8_t)>&& f = {})
545 : hdrType(type),
546 func(f)
547 {
548 }
549
550 WifiMacType hdrType; ///< MAC header type of frame being transmitted
551 std::function<void(Ptr<const WifiPsdu>, const WifiTxVector&, uint8_t)>
552 func; ///< function to perform actions and checks
553 };
554
555 private:
556 void StartTraffic() override;
557
558 uint8_t m_testIndex{0}; //!< index to iterate over test scenarios
559 bool m_setupDone{false}; //!< whether association, BA, ... have been done
560 bool m_dlPktDone{false}; //!< whether the DL packet has been generated
561 std::list<Events> m_events; //!< list of events for a test run
562 std::size_t m_processedEvents{0}; //!< number of processed events
563 const uint8_t m_linkIdForTid0{1}; //!< ID of the link on which TID 0 is mapped
564 const uint8_t m_linkIdForTid4{0}; //!< ID of the link on which TID 4 is mapped
565 Ptr<WifiMpdu> m_bcastFrame; //!< the broadcast frame sent by the AP MLD
566 Time m_switchMainPhyBackDelay; //!< the switch main PHY back delay
567 Time m_expectedMainPhySwitchBackTime; //!< expected main PHY switch back time
568};
569
570/**
571 * @ingroup wifi-test
572 * @ingroup tests
573 *
574 * @brief Check NAV and CCA in the last PIFS test
575 *
576 * An AP MLD and an EMLSR client, both having 3 links, are considered in this test. Aux PHYs are
577 * not TX capable, do not switch links and operate on 20 MHz channels; the main PHY operates on
578 * 40 MHz channels and the preferred link is link 1. In order to control link switches, a
579 * TID-to-Link mapping is configured so that TID 0 is mapped onto link 2 for both DL and UL. In this
580 * test, the main PHY switches to link 2 to start an UL TXOP a predefined number of slots before
581 * the backoff ends on link 2. We consider different durations of the channel switch delay to
582 * verify the time the data frame is transmitted by the EMLSR client on link 2 and the data frame
583 * TX width in various situations:
584 *
585 * AuxPhyCca = false AuxPhyCca = true
586 * ┌────┐ ┌────┐
587 * │QoS │40 │QoS │20
588 * |--PIFS--│Data│MHz |--PIFS--│Data│MHz
589 * ──────┬─────────┬────────┴────┴──── ──────┬─────────┼────┴─────────────
590 * Backoff Switch Backoff Switch
591 * end end end end
592 *
593 *
594 * AuxPhyCca = false AuxPhyCca = true
595 * ┌────┐ ┌────┐
596 * │QoS │40 │QoS │20
597 * |--PIFS--│Data│MHz |--PIFS--│Data│MHz
598 * ─────────┬──────┬─┴────┴─────────── ──────────┬─────┼────┴─────────────
599 * Switch Backoff Switch Backoff
600 * end end end end
601 *
602 *
603 * AuxPhyCca = false/true
604 * ┌────┐
605 * │QoS │40
606 * |--PIFS--| │Data│MHz
607 * ─────────┬───────────┼────┴────────
608 * Switch Backoff
609 * end end
610 *
611 * In all the cases, it is verified that the EMLSR client transmits the data frame, at the expected
612 * time and on the expected channel width, and receives the acknowledgment.
613 */
615{
616 public:
617 /// Constructor.
619
620 /**
621 * Enumeration indicating the tested scenario
622 */
630
631 protected:
632 void DoSetup() override;
633 void DoRun() override;
634 void Transmit(Ptr<WifiMac> mac,
635 uint8_t phyId,
636 WifiConstPsduMap psduMap,
637 WifiTxVector txVector,
638 double txPowerW) override;
639
640 /// Runs a test case and invokes itself for the next test case
641 void RunOne();
642
643 /// Actions and checks to perform upon the transmission of each frame
644 struct Events
645 {
646 /**
647 * Constructor.
648 *
649 * @param type the frame MAC header type
650 * @param f function to perform actions and checks
651 */
653 std::function<void(Ptr<const WifiPsdu>, const WifiTxVector&, uint8_t)>&& f = {})
654 : hdrType(type),
655 func(f)
656 {
657 }
658
659 WifiMacType hdrType; ///< MAC header type of frame being transmitted
660 std::function<void(Ptr<const WifiPsdu>, const WifiTxVector&, uint8_t)>
661 func; ///< function to perform actions and checks
662 };
663
664 private:
665 void StartTraffic() override;
666
667 std::size_t m_testIndex{0}; //!< index to iterate over test scenarios
668 bool m_setupDone{false}; //!< whether association, BA, ... have been done
669 std::list<Events> m_events; //!< list of events for a test run
670 std::size_t m_processedEvents{0}; //!< number of processed events
671 const uint8_t m_linkIdForTid0{2}; //!< ID of the link on which TID 0 is mapped
672 const uint8_t m_nSlotsLeft{4}; //!< value for the CAM NSlotsLeft attribute
673 const MHz_u m_mainPhyWidth{40}; //!< main PHY channel width
674 const MHz_u m_auxPhyWidth{20}; //!< aux PHY channel width
675 Time m_expectedTxStart; //!< expected start time for frame transmission
676 MHz_u m_expectedWidth; //!< expected channel width for frame transmission
677};
678
679/**
680 * @ingroup wifi-test
681 * @ingroup tests
682 *
683 * @brief wifi EMLSR suite to test link switch operations
684 */
686{
687 public:
689};
690
691#endif /* WIFI_EMLSR_LINK_SWITCH_TEST_H */
Test CCA busy notifications on EMLSR clients.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
uint8_t m_nextMainPhyLinkId
the ID of the link the main PHY switches to
uint8_t m_currMainPhyLinkId
the ID of the link the main PHY switches from
void StartTraffic() override
Start the generation of traffic (needs to be overridden)
MHz_u m_auxPhyMaxChWidth
max channel width supported by aux PHYs
~EmlsrCcaBusyTest() override=default
void TransmitPacketToAp(uint8_t linkId)
Make the other MLD transmit a packet to the AP on the given link.
void DoRun() override
Implementation to actually run this TestCase.
Time m_channelSwitchDelay
the PHY channel switch delay
void CheckPoint1()
Perform checks after that the preamble of the first PPDU has been received.
void CheckPoint3()
Perform checks after that the aux PHY completed the link switch.
EmlsrCcaBusyTest(MHz_u auxPhyMaxChWidth)
Constructor.
void CheckPoint2()
Perform checks after that the main PHY completed the link switch.
Check NAV and CCA in the last PIFS test.
const uint8_t m_nSlotsLeft
value for the CAM NSlotsLeft attribute
void DoRun() override
Implementation to actually run this TestCase.
void StartTraffic() override
Start the generation of traffic (needs to be overridden)
const uint8_t m_linkIdForTid0
ID of the link on which TID 0 is mapped.
std::size_t m_testIndex
index to iterate over test scenarios
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.
TestScenario
Enumeration indicating the tested scenario.
bool m_setupDone
whether association, BA, ... have been done
void RunOne()
Runs a test case and invokes itself for the next test case.
Time m_expectedTxStart
expected start time for frame transmission
std::list< Events > m_events
list of events for a test run
MHz_u m_expectedWidth
expected channel width for frame transmission
std::size_t m_processedEvents
number of processed events
const MHz_u m_auxPhyWidth
aux PHY channel width
void DoSetup() override
Implementation to do any local setup required for this TestCase.
const MHz_u m_mainPhyWidth
main PHY channel width
Check ICF reception while main PHY is switching.
ChannelSwitchEnd m_csdIndex
index to iterate over channel switch durations
void CheckInDeviceInterference(const std::string &testStr, uint8_t linkId, Time duration)
Check that the in-device interference generated by a transmission of the given duration on the given ...
const uint8_t m_linkIdForTid3
ID of the link on which TID 3 is mapped.
void RunOne()
Runs a test case and invokes itself for the next test case.
void StartTraffic() override
Start the generation of traffic (needs to be overridden)
bool m_setupDone
whether association, BA, ... have been done
std::array< WifiSpectrumBandInfo, 3 > m_bands
bands of the 3 frequency channels
void DoRun() override
Implementation to actually run this TestCase.
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.
uint8_t m_testIndex
index to iterate over test scenarios
void GenerateNoiseOnAllLinks(Ptr< WifiMac > mac, Time duration)
Generate noise on all the links of the given MAC for the given time duration.
void EmlsrLinkSwitchCb(uint8_t linkId, Ptr< WifiPhy > phy, bool connected)
Callback connected to the EmlsrLinkSwitch trace source of the StaWifiMac of the EMLSR client.
std::size_t m_processedEvents
number of processed events
std::optional< MainPhySwitchInfo > m_switchFrom
info for main PHY leaving a link
std::list< Events > m_events
list of events for a test run
ChannelSwitchEnd
Enumeration indicating the duration of a main PHY channel switch compared to the ICF fields.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
std::optional< MainPhySwitchInfo > m_switchTo
info for main PHY connected to a link
std::string m_testStr
test scenario description
Base class for EMLSR Operations tests.
Switch main PHY back timer test.
void DoRun() override
Implementation to actually run this TestCase.
const uint8_t m_linkIdForTid4
ID of the link on which TID 4 is mapped.
Ptr< WifiMpdu > m_bcastFrame
the broadcast frame sent by the AP MLD
void InsertEventsForQosTid4()
Insert events corresponding to the UL TXOP to transmit the QoS Data frame with TID 4.
std::size_t m_processedEvents
number of processed events
void MainPhySwitchInfoCallback(std::size_t index, const EmlsrMainPhySwitchTrace &info) override
Callback connected to the EMLSR Manager MainPhySwitch trace source.
bool m_dlPktDone
whether the DL packet has been generated
bool m_setupDone
whether association, BA, ... have been done
void DoSetup() override
Implementation to do any local setup required for this TestCase.
std::list< Events > m_events
list of events for a test run
Time m_expectedMainPhySwitchBackTime
expected main PHY switch back time
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.
uint8_t m_testIndex
index to iterate over test scenarios
void RunOne()
Runs a test case and invokes itself for the next test case.
TestScenario
Enumeration indicating the tested scenario.
Time m_switchMainPhyBackDelay
the switch main PHY back delay
void StartTraffic() override
Start the generation of traffic (needs to be overridden)
const uint8_t m_linkIdForTid0
ID of the link on which TID 0 is mapped.
Smart pointer class similar to boost::intrusive_ptr.
A suite of tests to run.
Definition test.h:1267
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
WifiMacType
Combination of valid MAC header type/subtype.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Definition wifi-ppdu.h:38
Actions and checks to perform upon the transmission of each frame.
std::function< void(Ptr< const WifiPsdu >, const WifiTxVector &, uint8_t)> func
function to perform actions and checks
Events(WifiMacType type, std::function< void(Ptr< const WifiPsdu >, const WifiTxVector &, uint8_t)> &&f={})
Constructor.
WifiMacType hdrType
MAC header type of frame being transmitted.
Actions and checks to perform upon the transmission of each frame.
std::function< void(Ptr< const WifiPsdu >, const WifiTxVector &, uint8_t)> func
function to perform actions and checks
Events(WifiMacType type, std::function< void(Ptr< const WifiPsdu >, const WifiTxVector &, uint8_t)> &&f={})
Constructor.
WifiMacType hdrType
MAC header type of frame being transmitted.
Time time
the time the main PHY left/was connected to a link
uint8_t linkId
the ID of the link the main PHY switched from/to
Actions and checks to perform upon the transmission of each frame.
Events(WifiMacType type, std::function< void(Ptr< const WifiPsdu >, const WifiTxVector &, uint8_t)> &&f={})
Constructor.
std::function< void(Ptr< const WifiPsdu >, const WifiTxVector &, uint8_t)> func
function to perform actions and checks
WifiMacType hdrType
MAC header type of frame being transmitted.
Base struct for EMLSR Main PHY switch traces.