diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 9f6fb8095..f6b9af91c 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -41,6 +41,7 @@ The required Doxygen version for documentation generation is now version 1.13. - (mobility) !2397 - Fix Rectangle::GetClosestSideOrCorner. It could assign the incorrect side when the checked position was outside the rectangle. - (wifi) #2368 - Fix various issues related to Content Channels and RU allocation. Fixes mostly covers cases where OFDMA is used with central 26 tones, where a single user is being assigned the whole PPDU bandwidth or where a RU is larger than 20 MHz. - (zigbee) !2383 - Fix malformed RREP command with missing command options field. +- (wifi) Fix the time the `NSlotsLeftAlert` trace source of `ChannelAccessManager` is fired (it cannot be earlier than the access grant start time) ## Release 3.44 diff --git a/src/wifi/doc/source/wifi-design.rst b/src/wifi/doc/source/wifi-design.rst index 33383c605..a789c6a01 100644 --- a/src/wifi/doc/source/wifi-design.rst +++ b/src/wifi/doc/source/wifi-design.rst @@ -1408,22 +1408,45 @@ A similar check is applied to possibly postpone the switch back to the preferred SwitchMainPhyBack timer expires. The Advanced EMLSR Manager also connects a callback to the ``NSlotsLeftAlert`` trace source of the -Channel Access Manager, which sends notifications when at most a configurable number of slots -remain until the backoff of an AC expires. When the Advanced EMLSR Manager receives such a -notification, it evaluates the opportunity of switching the main PHY to the auxiliary link on which -the notification has been received. Specifically, the Advanced EMLSR Manager performs the check -described above to determine whether the potential UL transmit opportunity shall be dropped (it is -dropped if a PPDU being received on another EMLSR link might be an ICF and the ``AllowUlTxopInRx`` -attribute is set to false) and then it checks whether it is convenient for the main PHY to switch -to the auxiliary link as described above (with the exception that the expected delay until backoff -end is also taken into account). If the main PHY is requested to switch to the auxiliary link and -the backoff on the auxiliary link counts down to zero while the main PHY is switching, a NAV and -CCA check is performed as described above (by the aux PHY in the PIFS period preceding the main PHY -channel switch end or by the main PHY in the PIFS period following the main PHY channel switch end). -Similarly, a NAV and CCA check is performed (by the main PHY) if the remaining backoff time when -the main PHY switch is completed is less than a PIFS. Otherwise, SwitchMainPhyBack timer is started -having a duration of SwitchMainPhyBackDelay plus the remaining time until the backoff of the AC -involved in the Channel Access Manager notification is expected to expire. +Channel Access Manager, which sends notifications when at most a configurable number of slots remain +until the backoff of an AC expires. It must be noted that this notification is only sent if channel +access has been requested by the AC for which the number of remaining backoff slots has reached +the given threshold. Thus, if an AC terminates a TXOP and generates a new backoff value, but it +has no packets in the queue, then channel access is not requested and the notification is not +scheduled; if a new packet arrives after that the backoff counter has reached zero, channel access +is requested and notification is sent immediately (while channel access is gained at the next slot +boundary, which may be a few microseconds later). If channel access is requested while the backoff +counter is non-zero, the notification is sent when the number of slots remaining until the backoff +of an AC expires reaches the configured value, if the backoff counter starts at a value greater than +or equal to the configured value, or as soon as the notification can be sent based on the value of +the ``NSlotsLeftMinDelay`` attribute of the Channel Access Manager. This attribute indicates the +minimum amount of time that must elapse since the start of the AIFS to enable the dispatching of +the notification. Example: + +:: + + BE AC (thus AIFS = SIFS + 3 * slots), Backoff = 3, NSlotsLeft >= 5, NSlotsLeftMinDelay = PIFS + + |------AIFS--------| + | SIFS | s | s | s | s | s | s | + ^ + | + send notification + +When the Advanced EMLSR Manager receives such a notification, it evaluates the opportunity of +switching the main PHY to the auxiliary link on which the notification has been received. Specifically, +the Advanced EMLSR Manager performs the check described above to determine whether the potential UL +transmit opportunity shall be dropped (it is dropped if a PPDU being received on another EMLSR link +might be an ICF and the ``AllowUlTxopInRx`` attribute is set to false) and then it checks whether it is +convenient for the main PHY to switch to the auxiliary link as described above (with the exception that +the expected delay until backoff end is also taken into account). If the main PHY is requested to switch +to the auxiliary link and the backoff on the auxiliary link counts down to zero while the main PHY is +switching, a NAV and CCA check is performed as described above (by the aux PHY in the PIFS period +preceding the main PHY channel switch end or by the main PHY in the PIFS period following the main PHY +channel switch end). Similarly, a NAV and CCA check is performed (by the main PHY) if the remaining +backoff time when the main PHY switch is completed is less than a PIFS. Otherwise, SwitchMainPhyBack +timer is started having a duration of SwitchMainPhyBackDelay plus the remaining time until the backoff +of the AC involved in the Channel Access Manager notification is expected to expire. The Advanced EMLSR Manager has the ``InterruptSwitch`` attribute that can be set to true to interrupt a main PHY switch when it is determined that the main PHY shall switch to a different diff --git a/src/wifi/model/channel-access-manager.cc b/src/wifi/model/channel-access-manager.cc index 4349bdef0..f011d7a36 100644 --- a/src/wifi/model/channel-access-manager.cc +++ b/src/wifi/model/channel-access-manager.cc @@ -29,6 +29,8 @@ NS_LOG_COMPONENT_DEFINE("ChannelAccessManager"); NS_OBJECT_ENSURE_REGISTERED(ChannelAccessManager); +const Time ChannelAccessManager::DEFAULT_N_SLOTS_LEFT_MIN_DELAY = MicroSeconds(25); + /** * Listener for PHY events. Forwards to ChannelAccessManager. * The ChannelAccessManager may handle multiple PHY listeners connected to distinct PHYs, @@ -187,16 +189,23 @@ ChannelAccessManager::GetTypeId() MakeBooleanAccessor(&ChannelAccessManager::m_proactiveBackoff), MakeBooleanChecker()) .AddAttribute("NSlotsLeft", - "Fire the NSlotsLeftAlert trace source when the backoff counter with " - "the minimum value among all ACs reaches this value or it is started " - "with a value less than this attribute. If this value is zero, the " - "trace source is never fired.", + "The NSlotsLeftAlert trace source is fired when the number of remaining " + "backoff slots for any AC is equal to or less than the value of this " + "attribute. Note that the trace source is fired only if the AC for which " + "the previous condition is met has requested channel access. Also, if " + "the value of this attribute is zero, the trace source is never fired.", UintegerValue(0), MakeUintegerAccessor(&ChannelAccessManager::m_nSlotsLeft), MakeUintegerChecker()) + .AddAttribute("NSlotsLeftMinDelay", + "The minimum gap between the end of a medium busy event and the time " + "the NSlotsLeftAlert trace source can be fired.", + TimeValue(ChannelAccessManager::DEFAULT_N_SLOTS_LEFT_MIN_DELAY), + MakeTimeAccessor(&ChannelAccessManager::m_nSlotsLeftMinDelay), + MakeTimeChecker()) .AddTraceSource("NSlotsLeftAlert", - "The backoff counter of the AC with the given index reached the " - "threshold set through the NSlotsLeft attribute.", + "The number of remaining backoff slots for the AC with the given index " + "reached the threshold set through the NSlotsLeft attribute.", MakeTraceSourceAccessor(&ChannelAccessManager::m_nSlotsLeftCallback), "ns3::ChannelAccessManager::NSlotsLeftCallback"); return tid; @@ -799,10 +808,14 @@ ChannelAccessManager::DoRestartAccessTimeoutIfNeeded() if (m_nSlotsLeft > 0) { - if (const auto slots = m_nSlotsLeft * GetSlot(); expectedBackoffDelay > slots) + const auto expectedNotifyTime = + Max(expectedBackoffEnd - m_nSlotsLeft * GetSlot(), + accessGrantStart - GetSifs() + m_nSlotsLeftMinDelay); + + if (expectedNotifyTime > now) { - // make the timer expire when the specified number of slots are left - expectedBackoffDelay -= slots; + // make the timer expire when it's time to notify that the given slots are left + expectedBackoffDelay = expectedNotifyTime - now; } else { diff --git a/src/wifi/model/channel-access-manager.h b/src/wifi/model/channel-access-manager.h index 40f7cf572..50c8ea869 100644 --- a/src/wifi/model/channel-access-manager.h +++ b/src/wifi/model/channel-access-manager.h @@ -511,6 +511,11 @@ class ChannelAccessManager : public Object uint8_t m_nSlotsLeft; //!< fire the NSlotsLeftAlert trace source when the //!< backoff counter with the minimum value among all //!< ACs reaches this value + Time m_nSlotsLeftMinDelay; //!< the minimum gap between the end of a medium busy event and + //!< the time the NSlotsLeftAlert trace source can be fired + + /// default value for the NSlotsLeftMinDelay attribute, corresponds to a PIFS in 5GHz/6GHz bands + static const Time DEFAULT_N_SLOTS_LEFT_MIN_DELAY; /** * TracedCallback signature for NSlotsLeft alerts.