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