A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
emlsr-manager.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 EMLSR_MANAGER_H
10#define EMLSR_MANAGER_H
11
12#include "ns3/ctrl-headers.h"
13#include "ns3/mac48-address.h"
14#include "ns3/object.h"
15#include "ns3/sta-wifi-mac.h"
16#include "ns3/wifi-phy-operating-channel.h"
17
18#include <map>
19#include <memory>
20#include <optional>
21#include <set>
22#include <string_view>
23#include <utility>
24
26
27namespace ns3
28{
29
30class EhtFrameExchangeManager;
31class MgtEmlOmn;
32class WifiMpdu;
33
34/**
35 * @ingroup wifi
36 * Base struct for EMLSR Main PHY switch traces.
37 */
39{
40 virtual ~EmlsrMainPhySwitchTrace() = default;
41
42 /// @return the name of this instance
43 virtual std::string_view GetName() const = 0;
44
45 /// @return a pointer to the clone of this object
46 virtual std::shared_ptr<EmlsrMainPhySwitchTrace> Clone() const = 0;
47
48 std::optional<uint8_t> fromLinkId; //!< ID of the link the main PHY is moving from (if any)
49 uint8_t toLinkId{WIFI_LINKID_UNDEFINED}; //!< ID of the link the main PHY is moving to
50};
51
52/**
53 * Implementation for the EMLSR Main PHY switch trace base struct. Child structs are inherited
54 * from this implementation according to the CRTP idiom and must define a static string_view
55 * member containing the name of the child.
56 */
57template <class T>
59{
60 /// @copydoc ns3::EmlsrMainPhySwitchTrace::GetName
61 std::string_view GetName() const override
62 {
63 return T::m_name;
64 }
65
66 /// @copydoc ns3::EmlsrMainPhySwitchTrace::Clone
67 std::shared_ptr<EmlsrMainPhySwitchTrace> Clone() const override
68 {
69 return std::shared_ptr<EmlsrMainPhySwitchTrace>(new T(static_cast<const T&>(*this)));
70 }
71};
72
73/**
74 * @ingroup wifi
75 *
76 * EmlsrManager is an abstract base class defining the API that EHT non-AP MLDs
77 * with EMLSR activated can use to handle the operations on the EMLSR links
78 */
79class EmlsrManager : public Object
80{
81 /// Allow test cases to access private members
82 friend class ::EmlsrCcaBusyTest;
83
84 public:
85 /// The aMediumSyncThreshold defined by Sec. 35.3.16.18.1 of 802.11be D4.0
86 static constexpr uint16_t MEDIUM_SYNC_THRESHOLD_USEC = 72;
87
88 /**
89 * @brief Get the type ID.
90 * @return the object TypeId
91 */
92 static TypeId GetTypeId();
94 ~EmlsrManager() override;
95
96 /**
97 * Set the wifi MAC. Note that it must be the MAC of an EHT non-AP MLD.
98 *
99 * @param mac the wifi MAC
100 */
101 void SetWifiMac(Ptr<StaWifiMac> mac);
102
103 /**
104 * Set the Transition Timeout advertised by the associated AP with EMLSR activated.
105 *
106 * @param timeout the advertised Transition Timeout
107 */
109
110 /**
111 * @return the Transition Timeout, if advertised by the associated AP
112 */
113 std::optional<Time> GetTransitionTimeout() const;
114
115 /**
116 * Set the duration of the MediumSyncDelay timer.
117 *
118 * @param duration the duration of the MediumSyncDelay timer
119 */
120 void SetMediumSyncDuration(Time duration);
121
122 /**
123 * @return the duration of the MediumSyncDelay timer
124 */
126
127 /**
128 * Set the Medium Synchronization OFDM ED threshold (dBm) to use while the MediumSyncDelay
129 * timer is running.
130 *
131 * @param threshold the threshold in dBm (ranges from -72 to -62 dBm)
132 */
133 void SetMediumSyncOfdmEdThreshold(int8_t threshold);
134
135 /**
136 * @return the Medium Synchronization OFDM ED threshold (dBm) to use while the MediumSyncDelay
137 * timer is running.
138 */
140
141 /**
142 * Set the maximum number of TXOPs a non-AP STA is allowed to attempt to initiate while
143 * the MediumSyncDelay timer is running. No value indicates no limit.
144 *
145 * @param nTxops the maximum number of TXOPs a non-AP STA is allowed to attempt to
146 * initiate while the MediumSyncDelay timer is running
147 */
148 void SetMediumSyncMaxNTxops(std::optional<uint8_t> nTxops);
149
150 /**
151 * @return the maximum number of TXOPs a non-AP STA is allowed to attempt to initiate while
152 * the MediumSyncDelay timer is running. No value indicates no limit.
153 */
154 std::optional<uint8_t> GetMediumSyncMaxNTxops() const;
155
156 /**
157 * @return the ID of main PHY (position in the vector of PHYs held by WifiNetDevice)
158 */
159 uint8_t GetMainPhyId() const;
160
161 /**
162 * Take actions to enable EMLSR mode on the given set of links, if non-empty, or
163 * disable EMLSR mode, otherwise.
164 *
165 * @param linkIds the IDs of the links on which EMLSR mode should be enabled
166 * (empty to disable EMLSR mode)
167 */
168 void SetEmlsrLinks(const std::set<uint8_t>& linkIds);
169
170 /**
171 * @return the set of links on which EMLSR mode is enabled
172 */
173 const std::set<uint8_t>& GetEmlsrLinks() const;
174
175 /**
176 * Set the member variable indicating whether the state of the CAM should be reset when
177 * the main PHY switches channel and operates on the link associated with the CAM.
178 *
179 * @param enable whether the CAM state should be reset
180 */
181 void SetCamStateReset(bool enable);
182
183 /**
184 * @return the value of the member variable indicating whether the state of the CAM should be
185 * reset when the main PHY switches channel and operates on the link associated with the CAM.
186 */
187 bool GetCamStateReset() const;
188
189 /**
190 * Notify that an UL TXOP is gained on the given link by the given AC. This method has to
191 * determine whether to start the UL TXOP or release the channel.
192 *
193 * @param linkId the ID of the given link
194 * @param aci the index of the given AC
195 * @return a pair consisting of a boolean value indicating whether the UL TXOP can be started
196 * and a Time value indicating the delay after which the EMLSR client must restart
197 * channel access (if needed) in case the UL TXOP is not started
198 */
199 std::pair<bool, Time> GetDelayUntilAccessRequest(uint8_t linkId, AcIndex aci);
200
201 /**
202 * Set the member variable indicating whether Aux PHYs are capable of transmitting PPDUs.
203 *
204 * @param capable whether Aux PHYs are capable of transmitting PPDUs
205 */
206 void SetAuxPhyTxCapable(bool capable);
207
208 /**
209 * @return whether Aux PHYs are capable of transmitting PPDUs
210 */
211 bool GetAuxPhyTxCapable() const;
212
213 /**
214 * Set the member variable indicating whether in-device interference is such that a PHY cannot
215 * decode anything and cannot decrease the backoff counter when another PHY is transmitting.
216 *
217 * @param enable whether in-device interference is such that a PHY cannot decode anything
218 * and cannot decrease the backoff counter when another PHY is transmitting
219 */
220 void SetInDeviceInterference(bool enable);
221
222 /**
223 * @return whether in-device interference is such that a PHY cannot decode anything and cannot
224 * decrease the backoff counter when another PHY is transmitting
225 */
226 bool GetInDeviceInterference() const;
227
228 /**
229 * Notify the reception of a management frame addressed to us.
230 *
231 * @param mpdu the received MPDU
232 * @param linkId the ID of the link over which the MPDU was received
233 */
234 void NotifyMgtFrameReceived(Ptr<const WifiMpdu> mpdu, uint8_t linkId);
235
236 /**
237 * Notify the reception of an initial Control frame on the given link.
238 *
239 * @param linkId the ID of the link on which the initial Control frame was received
240 */
241 void NotifyIcfReceived(uint8_t linkId);
242
243 /**
244 * Notify the start of an UL TXOP on the given link
245 *
246 * @param linkId the ID of the given link
247 */
248 void NotifyUlTxopStart(uint8_t linkId);
249
250 /**
251 * Notify that RTS transmission is starting on the given link.
252 *
253 * @param linkId the ID of the given link
254 * @param rts the RTS being transmitted
255 * @param txVector the TXVECTOR used to transmit the RTS
256 */
257 virtual void NotifyRtsSent(uint8_t linkId,
259 const WifiTxVector& txVector);
260
261 /**
262 * Notify that protection (if required) is completed and data frame exchange can start
263 * on the given link.
264 *
265 * @param linkId the ID of the given link
266 */
267 void NotifyProtectionCompleted(uint8_t linkId);
268
269 /**
270 * Notify the end of a TXOP on the given link.
271 *
272 * @param linkId the ID of the given link
273 * @param ulTxopNotStarted whether this is a notification of the end of an UL TXOP that did
274 * not even start (no frame transmitted)
275 * @param ongoingDlTxop whether a DL TXOP is ongoing on the given link (if true, this is
276 * a notification of the end of an UL TXOP)
277 */
278 void NotifyTxopEnd(uint8_t linkId, bool ulTxopNotStarted = false, bool ongoingDlTxop = false);
279
280 /**
281 * Notify that an STA affiliated with the EMLSR client is causing in-device interference
282 * for the given amount of time.
283 *
284 * @param linkId the ID of the link on which the STA is operating
285 * @param duration the duration of the in-device interference
286 */
287 virtual void NotifyInDeviceInterferenceStart(uint8_t linkId, Time duration);
288
289 /**
290 * Check whether the MediumSyncDelay timer is running for the STA operating on the given link.
291 * If so, returns the time elapsed since the timer started.
292 *
293 * @param linkId the ID of the given link
294 * @return the time elapsed since the MediumSyncDelay timer started, if this timer is running
295 * for the STA operating on the given link
296 */
297 std::optional<Time> GetElapsedMediumSyncDelayTimer(uint8_t linkId) const;
298
299 /**
300 * Cancel the MediumSyncDelay timer associated with the given link and take the appropriate
301 * actions. This function must not be called when the MediumSyncDelay timer is not running
302 * on the given link.
303 *
304 * @param linkId the ID of the link associated with the MediumSyncDelay timer to cancel
305 */
306 void CancelMediumSyncDelayTimer(uint8_t linkId);
307
308 /**
309 * Decrement the counter indicating the number of TXOP attempts left while the MediumSyncDelay
310 * timer is running. This function must not be called when the MediumSyncDelay timer is not
311 * running on the given link.
312 *
313 * @param linkId the ID of the link on which a new TXOP attempt may be carried out
314 */
315 void DecrementMediumSyncDelayNTxops(uint8_t linkId);
316
317 /**
318 * Reset the counter indicating the number of TXOP attempts left while the MediumSyncDelay
319 * timer is running, so as to remove the limit on the number of attempts that can be made
320 * while the MediumSyncDelay timer is running. This function is normally called when a TXOP
321 * attempt is successful. This function must not be called when the MediumSyncDelay timer is
322 * not running on the given link.
323 *
324 * @param linkId the ID of the link for which the counter of the TXOP attempts is reset
325 */
326 void ResetMediumSyncDelayNTxops(uint8_t linkId);
327
328 /**
329 * Return whether no more TXOP attempt is allowed on the given link. This function must not
330 * be called when the MediumSyncDelay timer is not running on the given link.
331 *
332 * @param linkId the ID of the link on which a new TXOP attempt may be carried out
333 * @return whether no more TXOP attempt on the given link is allowed
334 */
335 bool MediumSyncDelayNTxopsExceeded(uint8_t linkId);
336
337 protected:
338 void DoDispose() override;
339
340 /**
341 * Allow subclasses to take actions when the MAC is set.
342 *
343 * @param mac the wifi MAC
344 */
345 virtual void DoSetWifiMac(Ptr<StaWifiMac> mac);
346
347 /**
348 * @return the MAC of the non-AP MLD managed by this EMLSR Manager.
349 */
351
352 /**
353 * @param linkId the ID of the given link
354 * @return the EHT FrameExchangeManager attached to the non-AP STA operating on the given link
355 */
356 Ptr<EhtFrameExchangeManager> GetEhtFem(uint8_t linkId) const;
357
358 /**
359 * @return the ID of the link on which the EML Operating Mode Notification frame has to be sent
360 */
361 virtual uint8_t GetLinkToSendEmlOmn() = 0;
362
363 /**
364 * A previous EML Operating Mode Notification frame was dropped. Ask the subclass whether
365 * the frame needs to be re-sent on the given link (if any).
366 *
367 * @param mpdu the dropped MPDU that includes the EML Operating Mode Notification frame
368 * @return the ID of the link over which to re-send the frame, if needed
369 */
370 virtual std::optional<uint8_t> ResendNotification(Ptr<const WifiMpdu> mpdu) = 0;
371
372 /**
373 * @param linkId the ID of the given link
374 * @return the operating channel the main PHY must switch to in order to operate
375 * on the given link
376 */
377 const WifiPhyOperatingChannel& GetChannelForMainPhy(uint8_t linkId) const;
378
379 /**
380 * @param linkId the ID of the given link
381 * @return the operating channel an aux PHY must switch to in order to operate
382 * on the given link
383 */
384 const WifiPhyOperatingChannel& GetChannelForAuxPhy(uint8_t linkId) const;
385
386 /**
387 * Switch channel on the Main PHY so that it operates on the given link.
388 *
389 * @param linkId the ID of the link on which the main PHY has to operate
390 * @param noSwitchDelay whether switching delay should be zero
391 * @param resetBackoff whether backoff should be reset on the link on which the main PHY
392 * is operating
393 * @param requestAccess whether channel access should be requested on the link on which the
394 * main PHY is moving onto
395 * @param traceInfo information to pass to the main PHY switch traced callback (the fromLinkId
396 * and toLinkId fields are set by this function)
397 */
398 void SwitchMainPhy(uint8_t linkId,
399 bool noSwitchDelay,
400 bool resetBackoff,
401 bool requestAccess,
402 EmlsrMainPhySwitchTrace&& traceInfo);
403
404 static constexpr bool RESET_BACKOFF = true; //!< reset backoff on main PHY switch
405 static constexpr bool DONT_RESET_BACKOFF = false; //!< do not reset backoff on main PHY switch
406 static constexpr bool REQUEST_ACCESS = true; //!< request channel access when PHY switch ends
407 static constexpr bool DONT_REQUEST_ACCESS =
408 false; //!< do not request channel access when PHY switch ends
409
410 /**
411 * Switch channel on the Aux PHY operating on the given current link so that it operates
412 * on the given next link.
413 *
414 * @param auxPhy the Aux PHY
415 * @param currLinkId the ID of the link on which the aux PHY is currently operating
416 * @param nextLinkId the ID of the link on which the aux PHY will be operating
417 */
418 void SwitchAuxPhy(Ptr<WifiPhy> auxPhy, uint8_t currLinkId, uint8_t nextLinkId);
419
420 /**
421 * Callback connected to the EmlsrLinkSwitch trace source of StaWifiMac.
422 *
423 * @param linkId the ID of the link involved in the EMLSR link switch event
424 * @param phy a pointer to the PHY involved in the EMLSR link switch event
425 */
426 virtual void EmlsrLinkSwitchCallback(uint8_t linkId, Ptr<WifiPhy> phy);
427
428 /**
429 * Set the CCA ED threshold (if needed) on the given PHY that is switching channel to
430 * operate on the given link.
431 *
432 * @param phy the given PHY
433 * @param linkId the ID of the given link
434 */
435 void SetCcaEdThresholdOnLinkSwitch(Ptr<WifiPhy> phy, uint8_t linkId);
436
437 /**
438 * @return the EML Operating Mode Notification to send
439 */
441
442 /**
443 * Subclasses have to provide an implementation for this method, that is called by the base
444 * class when the EMLSR client gets channel access on the given link. This method has to
445 * check possible reasons to give up the TXOP that apply to both main PHY and aux PHYs.
446 *
447 * @param linkId the ID of the given link
448 * @return a pair consisting of a boolean value indicating whether the UL TXOP can be started
449 * and a Time value indicating the delay after which the EMLSR client must restart
450 * channel access (if needed) in case the UL TXOP is not started
451 */
452 virtual std::pair<bool, Time> DoGetDelayUntilAccessRequest(uint8_t linkId) = 0;
453
454 /**
455 * Subclasses have to provide an implementation for this method, that is called by the base
456 * class when the given AC of the EMLSR client gets channel access on the given link, on which
457 * an aux PHY that is not TX capable is operating. This method has to request the main PHY to
458 * switch to the given link to take over the TXOP, unless it is decided to give up the TXOP.
459 *
460 * @param linkId the ID of the given link
461 * @param aci the index of the given AC
462 */
463 virtual void SwitchMainPhyIfTxopGainedByAuxPhy(uint8_t linkId, AcIndex aci) = 0;
464
465 /**
466 * Subclasses have to provide an implementation for this method, that is called by the base
467 * class when the EMLSR client gets channel access on the given link, on which an aux PHY that
468 * is TX capable is operating. This method has to request the main PHY to switch to the
469 * given link to take over the TXOP, if possible, or determine the delay after which the
470 * EMLSR client restarts channel access on the given link, otherwise.
471 *
472 * @param linkId the ID of the given link
473 * @return a pair consisting of a boolean value indicating whether the UL TXOP can be started
474 * and a Time value indicating the delay after which the EMLSR client must restart
475 * channel access (if needed) in case the UL TXOP is not started
476 */
477 virtual std::pair<bool, Time> GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId) = 0;
478
479 /**
480 * Set sleep state or awake state for all aux PHYs.
481 *
482 * @param sleep set sleep state, if true, or awake state, otherwise
483 */
484 void SetSleepStateForAllAuxPhys(bool sleep);
485
486 /**
487 * Cancel all pending events to put aux PHYs into sleep/awake state.
488 */
490
491 Time m_emlsrPaddingDelay; //!< EMLSR Padding delay
492 Time m_emlsrTransitionDelay; //!< EMLSR Transition delay
493 uint8_t m_mainPhyId; //!< ID of main PHY (position in the vector of PHYs held by WifiNetDevice)
494 MHz_u m_auxPhyMaxWidth; //!< max channel width supported by aux PHYs
495 WifiModulationClass m_auxPhyMaxModClass; //!< max modulation class supported by aux PHYs
496 bool m_auxPhyTxCapable; //!< whether Aux PHYs are capable of transmitting PPDUs
497 bool m_auxPhyToSleep; //!< whether Aux PHYs should be put into sleep mode while the Main PHY
498 //!< is carrying out a (DL or UL) TXOP
499 std::map<uint8_t, EventId> m_auxPhyToSleepEvents; //!< PHY ID-indexed map of events scheduled to
500 //!< put an Aux PHY to sleep
501 std::map<uint8_t, Time> m_startSleep; //!< PHY ID-indexed map of last time sleep mode started
502 std::map<uint8_t, EventId> m_ulMainPhySwitch; //!< link ID-indexed map of timers started when
503 //!< an aux PHY gains an UL TXOP and schedules
504 //!< a channel switch for the main PHY
505
506 private:
507 /**
508 * Set the ID of main PHY (position in the vector of PHYs held by WifiNetDevice). This
509 * method cannot be called during or after initialization.
510 *
511 * @param mainPhyId the ID of the main PHY
512 */
513 void SetMainPhyId(uint8_t mainPhyId);
514
515 /**
516 * Compute the operating channels that the main PHY and the aux PHY(s) must switch to in order
517 * to operate on each of the setup links. The operating channels may be different due to
518 * limited channel width capabilities of the aux PHY(s). This method shall be called upon
519 * completion of ML setup.
520 */
522
523 /**
524 * Send an EML Operating Mode Notification frame.
525 */
526 void SendEmlOmn();
527
528 /**
529 * Start the MediumSyncDelay timer and take the appropriate actions.
530 *
531 * @param linkId the ID of the link on which medium synchronization was lost
532 */
533 void StartMediumSyncDelayTimer(uint8_t linkId);
534
535 /**
536 * Take the appropriate actions when the MediumSyncDelay timer expires or is cancelled.
537 *
538 * @param linkId the ID of the link associated with the MediumSyncDelay timer to cancel
539 */
540 void MediumSyncDelayTimerExpired(uint8_t linkId);
541
542 /**
543 * Notify the subclass of the reception of a management frame addressed to us.
544 *
545 * @param mpdu the received MPDU
546 * @param linkId the ID of the link over which the MPDU was received
547 */
548 virtual void DoNotifyMgtFrameReceived(Ptr<const WifiMpdu> mpdu, uint8_t linkId) = 0;
549
550 /**
551 * Notify the subclass of the reception of an initial Control frame on the given link.
552 *
553 * @param linkId the ID of the link on which the initial Control frame was received
554 */
555 virtual void DoNotifyIcfReceived(uint8_t linkId) = 0;
556
557 /**
558 * Notify the subclass of the start of an UL TXOP on the given link
559 *
560 * @param linkId the ID of the given link
561 */
562 virtual void DoNotifyUlTxopStart(uint8_t linkId) = 0;
563
564 /**
565 * Notify the subclass of the end of a TXOP on the given link.
566 *
567 * @param linkId the ID of the given link
568 */
569 virtual void DoNotifyTxopEnd(uint8_t linkId) = 0;
570
571 /**
572 * Notify the acknowledgment of the given MPDU.
573 *
574 * @param mpdu the acknowledged MPDU
575 */
576 void TxOk(Ptr<const WifiMpdu> mpdu);
577
578 /**
579 * Notify that the given MPDU has been discarded for the given reason.
580 *
581 * @param reason the reason why the MPDU was dropped
582 * @param mpdu the dropped MPDU
583 */
585
586 /**
587 * This method is called to make an EMLSR mode change effective after the transition
588 * delay has elapsed or a notification response has been received from the AP.
589 */
590 void ChangeEmlsrMode();
591
592 /**
593 * Adjust the operating channel of all the aux PHYs to meet the constraint on the maximum
594 * channel width supported by aux PHYs.
595 */
597
598 /**
599 * Notify subclass that EMLSR mode changed.
600 */
601 virtual void NotifyEmlsrModeChanged() = 0;
602
603 /**
604 * Notify subclass that the main PHY is switching channel to operate on another link.
605 *
606 * @param currLinkId the ID of the link on which the main PHY is operating (if any)
607 * @param nextLinkId the ID of the link on which the main PHY will be operating
608 * @param auxPhy the aux PHY operating on the link on which the main PHY will be operating
609 * @param duration the channel switch duration
610 */
611 virtual void NotifyMainPhySwitch(std::optional<uint8_t> currLinkId,
612 uint8_t nextLinkId,
613 Ptr<WifiPhy> auxPhy,
614 Time duration) = 0;
615
616 /**
617 * Information about the status of the MediumSyncDelay timer associated with a link.
618 */
620 {
621 EventId timer; //!< the MediumSyncDelay timer
622 std::optional<uint8_t> msdNTxopsLeft; //!< number of TXOP attempts left while the
623 //!< MediumSyncDelay timer is running
624 };
625
626 /**
627 * TracedCallback signature for main PHY switch events.
628 *
629 * @param info the information associated with the main PHY switch event
630 */
631 typedef void (*MainPhySwitchCallback)(const EmlsrMainPhySwitchTrace& info);
632
633 /// TracedCallback for main PHY switch events typedef
635
636 MainPhySwitchTracedCallback m_mainPhySwitchTrace; //!< main PHY switch trace source
637
638 Ptr<StaWifiMac> m_staMac; //!< the MAC of the managed non-AP MLD
639 std::optional<Time> m_emlsrTransitionTimeout; /**< Transition timeout advertised by APs with
640 EMLSR activated */
641 Time m_mediumSyncDuration; //!< duration of the MediumSyncDelay timer
642 int8_t m_msdOfdmEdThreshold; //!< MediumSyncDelay OFDM ED threshold
643 std::optional<uint8_t> m_msdMaxNTxops; //!< MediumSyncDelay max number of TXOPs
644
645 std::map<uint8_t, MediumSyncDelayStatus>
646 m_mediumSyncDelayStatus; //!< the status of MediumSyncDelay timers (link ID-indexed)
647 std::map<Ptr<WifiPhy>, dBm_u> m_prevCcaEdThreshold; //!< the CCA sensitivity threshold
648 //!< to restore once the MediumSyncDelay
649 //!< timer expires or the PHY moves to a
650 //!< link on which the timer is not running
651
652 std::set<uint8_t> m_emlsrLinks; //!< ID of the EMLSR links (empty if EMLSR mode is disabled)
653 std::optional<std::set<uint8_t>> m_nextEmlsrLinks; /**< ID of the links that will become the
654 EMLSR links when the pending
655 notification frame is acknowledged */
656 Time m_lastAdvPaddingDelay; //!< last advertised padding delay
657 Time m_lastAdvTransitionDelay; //!< last advertised transition delay
658 EventId m_transitionTimeoutEvent; /**< Timer started after the successful transmission of an
659 EML Operating Mode Notification frame */
660 bool m_resetCamState; //!< whether to reset the state of CAM when main PHY switches channel
661 bool m_inDeviceInterference; //!< whether in-device interference is such that a PHY cannot
662 //!< decode anything and cannot decrease the backoff counter
663 //!< when another PHY is transmitting
664 std::map<uint8_t, WifiPhyOperatingChannel>
665 m_mainPhyChannels; //!< link ID-indexed map of operating channels for the main PHY
666 std::map<uint8_t, WifiPhyOperatingChannel>
667 m_auxPhyChannels; //!< link ID-indexed map of operating channels for the aux PHYs
668 std::map<uint8_t, Time>
669 m_noPhySince; //!< link ID-indexed map of the time since no PHY is operating on the link
670};
671
672/**
673 * Struct to trace that main PHY switched to start a DL TXOP after that an aux PHY received an ICF.
674 */
676 : public EmlsrMainPhySwitchTraceImpl<EmlsrDlTxopIcfReceivedByAuxPhyTrace>
677{
678 static constexpr std::string_view m_name = "DlTxopIcfReceivedByAuxPhy"; //!< trace name
679};
680
681/**
682 * Struct to trace that main PHY switched to start an UL TXOP after that an aux PHY transmitted an
683 * RTS.
684 */
686 : public EmlsrMainPhySwitchTraceImpl<EmlsrUlTxopRtsSentByAuxPhyTrace>
687{
688 static constexpr std::string_view m_name = "UlTxopRtsSentByAuxPhy"; //!< trace name
689};
690
691/**
692 * Struct to trace that main PHY switched when a (DL or UL) TXOP ended.
693 *
694 * This trace is normally called when aux PHYs do not switch link and the main PHY switches back to
695 * the preferred link when a TXOP carried out on another link ends. In such a case, the remTime
696 * field is set to zero.
697 *
698 * Note that the main PHY may be already switching when the TXOP ends; this happens, e.g., when the
699 * main PHY starts switching to a link on which an aux PHY gained a TXOP and sent an RTS, but the
700 * CTS is not received and the UL TXOP ends before the main PHY channel switch is completed. In this
701 * case, the main PHY switch is postponed until the previous switch is completed and the remTime
702 * field is set to the remaining channel switch delay at the time the TXOP ends:
703 *
704 * |-- main PHY switch --|
705 * |----- to link 1 -----|
706 * ┌───────────┐
707 * │ CTS │
708 * ────────────────────────┬───────────┬───┴X──────────┴─────────────────────────────
709 * [link 1] │ RTS │ │-remTime-│
710 * └───────────┘ │ |-- main PHY switch --|
711 * │ |- to preferred link -|
712 * CTS timeout
713 *
714 * Note also that the Advanced EMLSR manager may allow a main PHY switch to be interrupted. If this
715 * option is enabled and the main PHY is switching when the TXOP ends, the previous switch is
716 * interrupted and the main PHY starts switching to the preferred link (in this case, the remTime
717 * field indicates the time that was left to complete the previous switch). Also note that, with
718 * the Advanced EMLSR manager, this trace may also be called when aux PHYs switch link. This happens
719 * when the TXOP ends while the main PHY is switching; in this case, the previous switch is
720 * interrupted and the main PHY returns to the link on which it was operating before the previous
721 * switch.
722 *
723 * |-- main PHY switch --|
724 * |----- to link 1 -----|(interrupted)
725 * ┌───────────┐
726 * │ CTS │
727 * ────────────────────────┬───────────┬───┴X──────────┴─────────────────────────────
728 * [link 1] │ RTS │ │-remTime-│
729 * └───────────┘ │-- main PHY switch --|
730 * │- to preferred link -|
731 * CTS timeout
732 */
733struct EmlsrTxopEndedTrace : public EmlsrMainPhySwitchTraceImpl<EmlsrTxopEndedTrace>
734{
735 static constexpr std::string_view m_name = "TxopEnded"; //!< trace name
736
737 Time remTime; //!< the remaining time (at TXOP end) until the main PHY completes the
738 //!< channel switch, in case the main PHY is completing a previous switch
739 //!< when the TXOP ends
740
741 /**
742 * Constructor provided because this struct is not an aggregate (it has a base struct), hence
743 * we cannot use designated initializers.
744 *
745 * @param t the value for the sinceTxopEnd field
746 */
748 : remTime(t)
749 {
750 }
751};
752
753/**
754 * Struct to trace that main PHY switched to operate on a link on which an aux PHY that is not
755 * TX capable has gained or is expected to shortly gain a TXOP.
756 */
758 : public EmlsrMainPhySwitchTraceImpl<EmlsrUlTxopAuxPhyNotTxCapableTrace>
759{
760 static constexpr std::string_view m_name = "UlTxopAuxPhyNotTxCapable"; //!< trace name
761
762 AcIndex acIndex; //!< Access category of TXOP on aux PHY
763 Time remTime; //!< Remaining time to complete backoff countdown on the aux PHY link
764 Time remNav; //!< the remaining NAV on main PHY link when main PHY is requested to switch
765
766 /**
767 * Constructor provided because this struct is not an aggregate (it has a base struct), hence
768 * we cannot use designated initializers.
769 *
770 * @param aci the value for the acIndex field
771 * @param delay the value for the remTime field
772 * @param navLeft the value for the remNav field
773 */
774 EmlsrUlTxopAuxPhyNotTxCapableTrace(AcIndex aci, const Time& delay, const Time& navLeft)
775 : acIndex(aci),
776 remTime(delay),
777 remNav(navLeft)
778 {
779 }
780};
781
782} // namespace ns3
783
784#endif /* EMLSR_MANAGER_H */
Test CCA busy notifications on EMLSR clients.
EmlsrManager is an abstract base class defining the API that EHT non-AP MLDs with EMLSR activated can...
void SendEmlOmn()
Send an EML Operating Mode Notification frame.
Time GetMediumSyncDuration() const
void ComputeOperatingChannels()
Compute the operating channels that the main PHY and the aux PHY(s) must switch to in order to operat...
void(* MainPhySwitchCallback)(const EmlsrMainPhySwitchTrace &info)
TracedCallback signature for main PHY switch events.
std::map< uint8_t, Time > m_startSleep
PHY ID-indexed map of last time sleep mode started.
void NotifyProtectionCompleted(uint8_t linkId)
Notify that protection (if required) is completed and data frame exchange can start on the given link...
void SetTransitionTimeout(Time timeout)
Set the Transition Timeout advertised by the associated AP with EMLSR activated.
void CancelMediumSyncDelayTimer(uint8_t linkId)
Cancel the MediumSyncDelay timer associated with the given link and take the appropriate actions.
static constexpr uint16_t MEDIUM_SYNC_THRESHOLD_USEC
The aMediumSyncThreshold defined by Sec. 35.3.16.18.1 of 802.11be D4.0.
bool m_auxPhyTxCapable
whether Aux PHYs are capable of transmitting PPDUs
bool MediumSyncDelayNTxopsExceeded(uint8_t linkId)
Return whether no more TXOP attempt is allowed on the given link.
std::optional< Time > GetTransitionTimeout() const
void ChangeEmlsrMode()
This method is called to make an EMLSR mode change effective after the transition delay has elapsed o...
std::pair< bool, Time > GetDelayUntilAccessRequest(uint8_t linkId, AcIndex aci)
Notify that an UL TXOP is gained on the given link by the given AC.
virtual std::pair< bool, Time > DoGetDelayUntilAccessRequest(uint8_t linkId)=0
Subclasses have to provide an implementation for this method, that is called by the base class when t...
Ptr< EhtFrameExchangeManager > GetEhtFem(uint8_t linkId) const
void TxDropped(WifiMacDropReason reason, Ptr< const WifiMpdu > mpdu)
Notify that the given MPDU has been discarded for the given reason.
void NotifyUlTxopStart(uint8_t linkId)
Notify the start of an UL TXOP on the given link.
void TxOk(Ptr< const WifiMpdu > mpdu)
Notify the acknowledgment of the given MPDU.
void MediumSyncDelayTimerExpired(uint8_t linkId)
Take the appropriate actions when the MediumSyncDelay timer expires or is cancelled.
void NotifyTxopEnd(uint8_t linkId, bool ulTxopNotStarted=false, bool ongoingDlTxop=false)
Notify the end of a TXOP on the given link.
std::map< uint8_t, EventId > m_ulMainPhySwitch
link ID-indexed map of timers started when an aux PHY gains an UL TXOP and schedules a channel switch...
bool m_inDeviceInterference
whether in-device interference is such that a PHY cannot decode anything and cannot decrease the back...
bool GetCamStateReset() const
void SetEmlsrLinks(const std::set< uint8_t > &linkIds)
Take actions to enable EMLSR mode on the given set of links, if non-empty, or disable EMLSR mode,...
void SetMediumSyncOfdmEdThreshold(int8_t threshold)
Set the Medium Synchronization OFDM ED threshold (dBm) to use while the MediumSyncDelay timer is runn...
uint8_t m_mainPhyId
ID of main PHY (position in the vector of PHYs held by WifiNetDevice)
int8_t GetMediumSyncOfdmEdThreshold() const
void NotifyIcfReceived(uint8_t linkId)
Notify the reception of an initial Control frame on the given link.
std::map< uint8_t, EventId > m_auxPhyToSleepEvents
PHY ID-indexed map of events scheduled to put an Aux PHY to sleep.
std::map< uint8_t, MediumSyncDelayStatus > m_mediumSyncDelayStatus
the status of MediumSyncDelay timers (link ID-indexed)
bool m_auxPhyToSleep
whether Aux PHYs should be put into sleep mode while the Main PHY is carrying out a (DL or UL) TXOP
virtual std::pair< bool, Time > GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId)=0
Subclasses have to provide an implementation for this method, that is called by the base class when t...
virtual void SwitchMainPhyIfTxopGainedByAuxPhy(uint8_t linkId, AcIndex aci)=0
Subclasses have to provide an implementation for this method, that is called by the base class when t...
void NotifyMgtFrameReceived(Ptr< const WifiMpdu > mpdu, uint8_t linkId)
Notify the reception of a management frame addressed to us.
virtual uint8_t GetLinkToSendEmlOmn()=0
std::map< uint8_t, WifiPhyOperatingChannel > m_auxPhyChannels
link ID-indexed map of operating channels for the aux PHYs
virtual void DoNotifyUlTxopStart(uint8_t linkId)=0
Notify the subclass of the start of an UL TXOP on the given link.
Ptr< StaWifiMac > m_staMac
the MAC of the managed non-AP MLD
virtual void DoNotifyMgtFrameReceived(Ptr< const WifiMpdu > mpdu, uint8_t linkId)=0
Notify the subclass of the reception of a management frame addressed to us.
Time m_emlsrPaddingDelay
EMLSR Padding delay.
bool GetInDeviceInterference() const
virtual void NotifyMainPhySwitch(std::optional< uint8_t > currLinkId, uint8_t nextLinkId, Ptr< WifiPhy > auxPhy, Time duration)=0
Notify subclass that the main PHY is switching channel to operate on another link.
MHz_u m_auxPhyMaxWidth
max channel width supported by aux PHYs
virtual void NotifyInDeviceInterferenceStart(uint8_t linkId, Time duration)
Notify that an STA affiliated with the EMLSR client is causing in-device interference for the given a...
void SetMediumSyncMaxNTxops(std::optional< uint8_t > nTxops)
Set the maximum number of TXOPs a non-AP STA is allowed to attempt to initiate while the MediumSyncDe...
Time m_emlsrTransitionDelay
EMLSR Transition delay.
void SetWifiMac(Ptr< StaWifiMac > mac)
Set the wifi MAC.
void DecrementMediumSyncDelayNTxops(uint8_t linkId)
Decrement the counter indicating the number of TXOP attempts left while the MediumSyncDelay timer is ...
bool GetAuxPhyTxCapable() const
const std::set< uint8_t > & GetEmlsrLinks() const
MainPhySwitchTracedCallback m_mainPhySwitchTrace
main PHY switch trace source
virtual void EmlsrLinkSwitchCallback(uint8_t linkId, Ptr< WifiPhy > phy)
Callback connected to the EmlsrLinkSwitch trace source of StaWifiMac.
void CancelAllSleepEvents()
Cancel all pending events to put aux PHYs into sleep/awake state.
Time m_mediumSyncDuration
duration of the MediumSyncDelay timer
std::optional< Time > m_emlsrTransitionTimeout
Transition timeout advertised by APs with EMLSR activated.
void SwitchAuxPhy(Ptr< WifiPhy > auxPhy, uint8_t currLinkId, uint8_t nextLinkId)
Switch channel on the Aux PHY operating on the given current link so that it operates on the given ne...
std::map< Ptr< WifiPhy >, dBm_u > m_prevCcaEdThreshold
the CCA sensitivity threshold to restore once the MediumSyncDelay timer expires or the PHY moves to a...
void ResetMediumSyncDelayNTxops(uint8_t linkId)
Reset the counter indicating the number of TXOP attempts left while the MediumSyncDelay timer is runn...
std::optional< Time > GetElapsedMediumSyncDelayTimer(uint8_t linkId) const
Check whether the MediumSyncDelay timer is running for the STA operating on the given link.
virtual void DoNotifyTxopEnd(uint8_t linkId)=0
Notify the subclass of the end of a TXOP on the given link.
virtual void DoSetWifiMac(Ptr< StaWifiMac > mac)
Allow subclasses to take actions when the MAC is set.
std::map< uint8_t, Time > m_noPhySince
link ID-indexed map of the time since no PHY is operating on the link
void SetAuxPhyTxCapable(bool capable)
Set the member variable indicating whether Aux PHYs are capable of transmitting PPDUs.
std::optional< std::set< uint8_t > > m_nextEmlsrLinks
ID of the links that will become the EMLSR links when the pending notification frame is acknowledged.
void SetCcaEdThresholdOnLinkSwitch(Ptr< WifiPhy > phy, uint8_t linkId)
Set the CCA ED threshold (if needed) on the given PHY that is switching channel to operate on the giv...
virtual void NotifyEmlsrModeChanged()=0
Notify subclass that EMLSR mode changed.
void SetMainPhyId(uint8_t mainPhyId)
Set the ID of main PHY (position in the vector of PHYs held by WifiNetDevice).
const WifiPhyOperatingChannel & GetChannelForMainPhy(uint8_t linkId) const
~EmlsrManager() override
void ApplyMaxChannelWidthAndModClassOnAuxPhys()
Adjust the operating channel of all the aux PHYs to meet the constraint on the maximum channel width ...
void SetMediumSyncDuration(Time duration)
Set the duration of the MediumSyncDelay timer.
void SwitchMainPhy(uint8_t linkId, bool noSwitchDelay, bool resetBackoff, bool requestAccess, EmlsrMainPhySwitchTrace &&traceInfo)
Switch channel on the Main PHY so that it operates on the given link.
static constexpr bool RESET_BACKOFF
reset backoff on main PHY switch
Time m_lastAdvTransitionDelay
last advertised transition delay
static constexpr bool REQUEST_ACCESS
request channel access when PHY switch ends
static constexpr bool DONT_REQUEST_ACCESS
do not request channel access when PHY switch ends
void DoDispose() override
Destructor implementation.
void StartMediumSyncDelayTimer(uint8_t linkId)
Start the MediumSyncDelay timer and take the appropriate actions.
int8_t m_msdOfdmEdThreshold
MediumSyncDelay OFDM ED threshold.
std::map< uint8_t, WifiPhyOperatingChannel > m_mainPhyChannels
link ID-indexed map of operating channels for the main PHY
std::optional< uint8_t > m_msdMaxNTxops
MediumSyncDelay max number of TXOPs.
virtual std::optional< uint8_t > ResendNotification(Ptr< const WifiMpdu > mpdu)=0
A previous EML Operating Mode Notification frame was dropped.
Ptr< StaWifiMac > GetStaMac() const
Time m_lastAdvPaddingDelay
last advertised padding delay
WifiModulationClass m_auxPhyMaxModClass
max modulation class supported by aux PHYs
uint8_t GetMainPhyId() const
std::optional< uint8_t > GetMediumSyncMaxNTxops() const
void SetCamStateReset(bool enable)
Set the member variable indicating whether the state of the CAM should be reset when the main PHY swi...
virtual void NotifyRtsSent(uint8_t linkId, Ptr< const WifiPsdu > rts, const WifiTxVector &txVector)
Notify that RTS transmission is starting on the given link.
EventId m_transitionTimeoutEvent
Timer started after the successful transmission of an EML Operating Mode Notification frame.
virtual void DoNotifyIcfReceived(uint8_t linkId)=0
Notify the subclass of the reception of an initial Control frame on the given link.
void SetInDeviceInterference(bool enable)
Set the member variable indicating whether in-device interference is such that a PHY cannot decode an...
const WifiPhyOperatingChannel & GetChannelForAuxPhy(uint8_t linkId) const
bool m_resetCamState
whether to reset the state of CAM when main PHY switches channel
static TypeId GetTypeId()
Get the type ID.
std::set< uint8_t > m_emlsrLinks
ID of the EMLSR links (empty if EMLSR mode is disabled)
static constexpr bool DONT_RESET_BACKOFF
do not reset backoff on main PHY switch
void SetSleepStateForAllAuxPhys(bool sleep)
Set sleep state or awake state for all aux PHYs.
MgtEmlOmn GetEmlOmn()
An identifier for simulation events.
Definition event-id.h:45
Implement the header for Action frames of type EML Operating Mode Notification.
A base class which provides memory management and object aggregation.
Definition object.h:78
Smart pointer class similar to boost::intrusive_ptr.
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
a unique identifier for an interface.
Definition type-id.h:48
Class that keeps track of all information about the current PHY operating channel.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
WifiMacDropReason
The reason why an MPDU was dropped.
Definition wifi-mac.h:70
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition qos-utils.h:62
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static constexpr uint8_t WIFI_LINKID_UNDEFINED
Invalid link identifier.
Definition wifi-utils.h:253
ns3::Time timeout
Struct to trace that main PHY switched to start a DL TXOP after that an aux PHY received an ICF.
static constexpr std::string_view m_name
trace name
Base struct for EMLSR Main PHY switch traces.
virtual ~EmlsrMainPhySwitchTrace()=default
uint8_t toLinkId
ID of the link the main PHY is moving to.
std::optional< uint8_t > fromLinkId
ID of the link the main PHY is moving from (if any)
virtual std::string_view GetName() const =0
virtual std::shared_ptr< EmlsrMainPhySwitchTrace > Clone() const =0
Implementation for the EMLSR Main PHY switch trace base struct.
std::string_view GetName() const override
std::shared_ptr< EmlsrMainPhySwitchTrace > Clone() const override
Information about the status of the MediumSyncDelay timer associated with a link.
std::optional< uint8_t > msdNTxopsLeft
number of TXOP attempts left while the MediumSyncDelay timer is running
EventId timer
the MediumSyncDelay timer
Struct to trace that main PHY switched when a (DL or UL) TXOP ended.
EmlsrTxopEndedTrace(const Time &t)
Constructor provided because this struct is not an aggregate (it has a base struct),...
Time remTime
the remaining time (at TXOP end) until the main PHY completes the channel switch, in case the main PH...
static constexpr std::string_view m_name
trace name
Struct to trace that main PHY switched to operate on a link on which an aux PHY that is not TX capabl...
Time remTime
Remaining time to complete backoff countdown on the aux PHY link.
EmlsrUlTxopAuxPhyNotTxCapableTrace(AcIndex aci, const Time &delay, const Time &navLeft)
Constructor provided because this struct is not an aggregate (it has a base struct),...
static constexpr std::string_view m_name
trace name
AcIndex acIndex
Access category of TXOP on aux PHY.
Time remNav
the remaining NAV on main PHY link when main PHY is requested to switch
Struct to trace that main PHY switched to start an UL TXOP after that an aux PHY transmitted an RTS.
static constexpr std::string_view m_name
trace name