From bf7cf39231439a313f032010c955eb830da5ba24 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Mon, 12 Jun 2023 16:32:20 +0200 Subject: [PATCH] wifi: Support setting no max number of TXOPs during medium access recovery Also, methods related to the Common Info field of the Basic variant MLE are moved to the corresponding struct. --- src/wifi/model/eht/multi-link-element.cc | 148 +++++++++++----------- src/wifi/model/eht/multi-link-element.h | 106 +++++++--------- src/wifi/test/wifi-eht-info-elems-test.cc | 7 +- 3 files changed, 125 insertions(+), 136 deletions(-) diff --git a/src/wifi/model/eht/multi-link-element.cc b/src/wifi/model/eht/multi-link-element.cc index 9f69744c6..de51c0a61 100644 --- a/src/wifi/model/eht/multi-link-element.cc +++ b/src/wifi/model/eht/multi-link-element.cc @@ -219,6 +219,79 @@ CommonInfoBasicMle::DecodeEmlsrTransitionDelay(uint8_t value) return MicroSeconds(1 << (3 + value)); } +void +CommonInfoBasicMle::SetMediumSyncDelayTimer(Time delay) +{ + int64_t delayUs = delay.GetMicroSeconds(); + NS_ABORT_MSG_IF(delayUs % 32 != 0, "Delay must be a multiple of 32 microseconds"); + delayUs /= 32; + + if (!m_mediumSyncDelayInfo.has_value()) + { + m_mediumSyncDelayInfo = CommonInfoBasicMle::MediumSyncDelayInfo{}; + } + m_mediumSyncDelayInfo->mediumSyncDuration = (delayUs & 0xff); +} + +Time +CommonInfoBasicMle::GetMediumSyncDelayTimer() const +{ + NS_ASSERT(m_mediumSyncDelayInfo); + return MicroSeconds(m_mediumSyncDelayInfo->mediumSyncDuration * 32); +} + +void +CommonInfoBasicMle::SetMediumSyncOfdmEdThreshold(int8_t threshold) +{ + NS_ABORT_MSG_IF(threshold < -72 || threshold > -62, "Threshold may range from -72 to -62 dBm"); + uint8_t value = 72 + threshold; + + if (!m_mediumSyncDelayInfo.has_value()) + { + m_mediumSyncDelayInfo = CommonInfoBasicMle::MediumSyncDelayInfo{}; + } + m_mediumSyncDelayInfo->mediumSyncOfdmEdThreshold = value; +} + +int8_t +CommonInfoBasicMle::GetMediumSyncOfdmEdThreshold() const +{ + NS_ASSERT(m_mediumSyncDelayInfo); + return (m_mediumSyncDelayInfo->mediumSyncOfdmEdThreshold) - 72; +} + +void +CommonInfoBasicMle::SetMediumSyncMaxNTxops(uint8_t nTxops) +{ + NS_ASSERT_MSG(nTxops < 16, "Value " << +nTxops << "cannot be encoded in 4 bits"); + + if (!m_mediumSyncDelayInfo.has_value()) + { + m_mediumSyncDelayInfo = CommonInfoBasicMle::MediumSyncDelayInfo{}; + } + + if (nTxops == 0) + { + // no limit on max number of TXOPs + m_mediumSyncDelayInfo->mediumSyncMaxNTxops = 15; + return; + } + + m_mediumSyncDelayInfo->mediumSyncMaxNTxops = --nTxops; +} + +std::optional +CommonInfoBasicMle::GetMediumSyncMaxNTxops() const +{ + NS_ASSERT(m_mediumSyncDelayInfo); + uint8_t nTxops = m_mediumSyncDelayInfo->mediumSyncMaxNTxops; + if (nTxops == 15) + { + return std::nullopt; + } + return nTxops + 1; +} + /** * MultiLinkElement */ @@ -329,81 +402,6 @@ MultiLinkElement::GetBssParamsChangeCount() const return std::get(m_commonInfo).m_bssParamsChangeCount.value(); } -void -MultiLinkElement::SetMediumSyncDelayTimer(Time delay) -{ - int64_t delayUs = delay.GetMicroSeconds(); - NS_ABORT_MSG_IF(delayUs % 32 != 0, "Delay must be a multiple of 32 microseconds"); - delayUs /= 32; - - auto& mediumSyncDelayInfo = std::get(m_commonInfo).m_mediumSyncDelayInfo; - if (!mediumSyncDelayInfo.has_value()) - { - mediumSyncDelayInfo = CommonInfoBasicMle::MediumSyncDelayInfo{}; - } - mediumSyncDelayInfo.value().mediumSyncDuration = (delayUs & 0xff); -} - -Time -MultiLinkElement::GetMediumSyncDelayTimer() const -{ - return MicroSeconds( - (std::get(m_commonInfo).m_mediumSyncDelayInfo.value().mediumSyncDuration) * - 32); -} - -void -MultiLinkElement::SetMediumSyncOfdmEdThreshold(int8_t threshold) -{ - NS_ABORT_MSG_IF(threshold < -72 || threshold > -62, "Threshold may range from -72 to -62 dBm"); - uint8_t value = 72 + threshold; - - auto& mediumSyncDelayInfo = std::get(m_commonInfo).m_mediumSyncDelayInfo; - if (!mediumSyncDelayInfo.has_value()) - { - mediumSyncDelayInfo = CommonInfoBasicMle::MediumSyncDelayInfo{}; - } - mediumSyncDelayInfo.value().mediumSyncOfdmEdThreshold = value; -} - -int8_t -MultiLinkElement::GetMediumSyncOfdmEdThreshold() const -{ - return (std::get(m_commonInfo) - .m_mediumSyncDelayInfo.value() - .mediumSyncOfdmEdThreshold) - - 72; -} - -void -MultiLinkElement::SetMediumSyncMaxNTxops(uint8_t nTxops) -{ - NS_ASSERT(nTxops > 0); - nTxops--; - - auto& mediumSyncDelayInfo = std::get(m_commonInfo).m_mediumSyncDelayInfo; - if (!mediumSyncDelayInfo.has_value()) - { - mediumSyncDelayInfo = CommonInfoBasicMle::MediumSyncDelayInfo{}; - } - mediumSyncDelayInfo.value().mediumSyncMaxNTxops = (nTxops & 0x0f); -} - -uint8_t -MultiLinkElement::GetMediumSyncMaxNTxops() const -{ - return (std::get(m_commonInfo) - .m_mediumSyncDelayInfo.value() - .mediumSyncMaxNTxops) + - 1; -} - -bool -MultiLinkElement::HasMediumSyncDelayInfo() const -{ - return std::get(m_commonInfo).m_mediumSyncDelayInfo.has_value(); -} - void MultiLinkElement::SetEmlsrSupported(bool supported) { diff --git a/src/wifi/model/eht/multi-link-element.h b/src/wifi/model/eht/multi-link-element.h index 2d1b1a2ca..21bcd5b40 100644 --- a/src/wifi/model/eht/multi-link-element.h +++ b/src/wifi/model/eht/multi-link-element.h @@ -140,6 +140,54 @@ struct CommonInfoBasicMle * \return the corresponding EMLSR Transition delay */ static Time DecodeEmlsrTransitionDelay(uint8_t value); + + /** + * Set the Medium Synchronization Duration subfield of the Medium Synchronization + * Delay Information in the Common Info field. + * + * \param delay the timer duration (must be a multiple of 32 microseconds) + */ + void SetMediumSyncDelayTimer(Time delay); + /** + * Set the Medium Synchronization OFDM ED Threshold subfield of the Medium Synchronization + * Delay Information in the Common Info field. + * + * \param threshold the threshold in dBm (ranges from -72 to -62 dBm) + */ + void SetMediumSyncOfdmEdThreshold(int8_t threshold); + /** + * Set the Medium Synchronization Maximum Number of TXOPs subfield of the Medium Synchronization + * Delay Information in the Common Info field. A value of zero indicates no limit on the + * maximum number of TXOPs. + * + * \param nTxops the maximum number of TXOPs a non-AP STA is allowed to attempt to + * initiate while the MediumSyncDelay timer is running at a non-AP STA + */ + void SetMediumSyncMaxNTxops(uint8_t nTxops); + /** + * Get the Medium Synchronization Duration subfield of the Medium Synchronization Delay + * Information in the Common Info field. Make sure that the Medium Synchronization Delay + * Information subfield is present. + * + * \return the timer duration + */ + Time GetMediumSyncDelayTimer() const; + /** + * Get the Medium Synchronization OFDM ED Threshold in dBm. Make sure that the Medium + * Synchronization Delay Information subfield is present. + * + * \return the threshold in dBm + */ + int8_t GetMediumSyncOfdmEdThreshold() const; + /** + * Get the maximum number of TXOPs a non-AP STA is allowed to attempt to initiate + * while the MediumSyncDelay timer is running at a non-AP STA. If no value is returned, + * no limit is imposed on the number of TXOPs. Make sure that the Medium Synchronization + * Delay Information subfield is present. + * + * \return the number of TXOPs + */ + std::optional GetMediumSyncMaxNTxops() const; }; /** @@ -285,64 +333,6 @@ class MultiLinkElement : public WifiInformationElement */ uint8_t GetBssParamsChangeCount() const; - /** - * Set the Medium Synchronization Duration subfield of the Medium Synchronization - * Delay information in the Common Info field. Make sure that this is a Basic - * Multi-Link Element. - * - * \param delay the timer duration (must be a multiple of 32 microseconds) - */ - void SetMediumSyncDelayTimer(Time delay); - /** - * Set the Medium Synchronization OFDM ED Threshold subfield of the Medium Synchronization - * Delay information in the Common Info field. Make sure that this is a Basic - * Multi-Link Element. - * - * \param threshold the threshold in dBm (ranges from -72 to -62 dBm) - */ - void SetMediumSyncOfdmEdThreshold(int8_t threshold); - /** - * Set the Medium Synchronization Maximum Number of TXOPs subfield of the Medium Synchronization - * Delay information in the Common Info field. Make sure that this is a Basic - * Multi-Link Element. - * - * \param nTxops the maximum number of TXOPs a non-AP STA is allowed to attempt to - * initiate while the MediumSyncDelay timer is running at a non-AP STA - */ - void SetMediumSyncMaxNTxops(uint8_t nTxops); - /** - * Return true if the Medium Synchronization Delay Information subfield in the - * Common Info field is present and false otherwise. Make sure that this is a Basic - * Multi-Link Element. - * - * \return true if the Medium Synchronization Delay Information subfield in the - * Common Info field is present and false otherwise - */ - bool HasMediumSyncDelayInfo() const; - /** - * Get the Medium Synchronization Duration subfield of the Medium Synchronization - * Delay information in the Common Info field. Make sure that this is a Basic - * Multi-Link Element and the Medium Synchronization Duration subfield is present. - * - * \return the timer duration - */ - Time GetMediumSyncDelayTimer() const; - /** - * Get the Medium Synchronization OFDM ED Threshold in dBm. Make sure that this is a Basic - * Multi-Link Element and the Medium Synchronization Duration subfield is present. - * - * \return the threshold in dBm - */ - int8_t GetMediumSyncOfdmEdThreshold() const; - /** - * Get the maximum number of TXOPs a non-AP STA is allowed to attempt to initiate - * while the MediumSyncDelay timer is running at a non-AP STA. Make sure that this is a - * Basic Multi-Link Element and the Medium Synchronization Duration subfield is present. - * - * \return the number of TXOPs - */ - uint8_t GetMediumSyncMaxNTxops() const; - /** * Set the EMLSR Support subfield of the EML Capabilities subfield in the Common Info field * to 1 if EMLSR mode is supported and set it to 0 otherwise. Make sure that this is a Basic diff --git a/src/wifi/test/wifi-eht-info-elems-test.cc b/src/wifi/test/wifi-eht-info-elems-test.cc index 2897cd0da..ee19ddf63 100644 --- a/src/wifi/test/wifi-eht-info-elems-test.cc +++ b/src/wifi/test/wifi-eht-info-elems-test.cc @@ -97,11 +97,12 @@ BasicMultiLinkElementTest::GetMultiLinkElement( } if (commonInfo.m_mediumSyncDelayInfo.has_value()) { - mle.SetMediumSyncDelayTimer( + mle.GetCommonInfoBasic().SetMediumSyncDelayTimer( MicroSeconds(32 * commonInfo.m_mediumSyncDelayInfo->mediumSyncDuration)); - mle.SetMediumSyncOfdmEdThreshold( + mle.GetCommonInfoBasic().SetMediumSyncOfdmEdThreshold( commonInfo.m_mediumSyncDelayInfo->mediumSyncOfdmEdThreshold - 72); - mle.SetMediumSyncMaxNTxops(commonInfo.m_mediumSyncDelayInfo->mediumSyncMaxNTxops + 1); + mle.GetCommonInfoBasic().SetMediumSyncMaxNTxops( + commonInfo.m_mediumSyncDelayInfo->mediumSyncMaxNTxops + 1); } if (commonInfo.m_emlCapabilities.has_value()) {