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.
This commit is contained in:
Stefano Avallone
2023-06-12 16:32:20 +02:00
committed by Stefano Avallone
parent 4fc5162f97
commit bf7cf39231
3 changed files with 125 additions and 136 deletions

View File

@@ -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<uint8_t>
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<BASIC_VARIANT>(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<BASIC_VARIANT>(m_commonInfo).m_mediumSyncDelayInfo;
if (!mediumSyncDelayInfo.has_value())
{
mediumSyncDelayInfo = CommonInfoBasicMle::MediumSyncDelayInfo{};
}
mediumSyncDelayInfo.value().mediumSyncDuration = (delayUs & 0xff);
}
Time
MultiLinkElement::GetMediumSyncDelayTimer() const
{
return MicroSeconds(
(std::get<BASIC_VARIANT>(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<BASIC_VARIANT>(m_commonInfo).m_mediumSyncDelayInfo;
if (!mediumSyncDelayInfo.has_value())
{
mediumSyncDelayInfo = CommonInfoBasicMle::MediumSyncDelayInfo{};
}
mediumSyncDelayInfo.value().mediumSyncOfdmEdThreshold = value;
}
int8_t
MultiLinkElement::GetMediumSyncOfdmEdThreshold() const
{
return (std::get<BASIC_VARIANT>(m_commonInfo)
.m_mediumSyncDelayInfo.value()
.mediumSyncOfdmEdThreshold) -
72;
}
void
MultiLinkElement::SetMediumSyncMaxNTxops(uint8_t nTxops)
{
NS_ASSERT(nTxops > 0);
nTxops--;
auto& mediumSyncDelayInfo = std::get<BASIC_VARIANT>(m_commonInfo).m_mediumSyncDelayInfo;
if (!mediumSyncDelayInfo.has_value())
{
mediumSyncDelayInfo = CommonInfoBasicMle::MediumSyncDelayInfo{};
}
mediumSyncDelayInfo.value().mediumSyncMaxNTxops = (nTxops & 0x0f);
}
uint8_t
MultiLinkElement::GetMediumSyncMaxNTxops() const
{
return (std::get<BASIC_VARIANT>(m_commonInfo)
.m_mediumSyncDelayInfo.value()
.mediumSyncMaxNTxops) +
1;
}
bool
MultiLinkElement::HasMediumSyncDelayInfo() const
{
return std::get<BASIC_VARIANT>(m_commonInfo).m_mediumSyncDelayInfo.has_value();
}
void
MultiLinkElement::SetEmlsrSupported(bool supported)
{

View File

@@ -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<uint8_t> 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

View File

@@ -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())
{