wifi: MediumSyncDelay is started if in-device interference lasts for >72us

This commit is contained in:
Stefano Avallone
2024-06-21 17:28:09 +02:00
parent 94f44e69fc
commit 5243ae5edb
3 changed files with 72 additions and 34 deletions

View File

@@ -388,6 +388,9 @@ EhtFrameExchangeManager::ForwardPsduDown(Ptr<const WifiPsdu> psdu, WifiTxVector&
else if (m_staMac && m_staMac->IsEmlsrLink(m_linkId) &&
m_staMac->GetEmlsrManager()->GetInDeviceInterference())
{
NS_ASSERT(m_staMac->GetEmlsrManager());
m_staMac->GetEmlsrManager()->NotifyInDeviceInterferenceStart(m_linkId, txDuration);
for (const auto linkId : m_staMac->GetLinkIds())
{
if (auto phy = m_mac->GetWifiPhy(linkId);
@@ -474,6 +477,9 @@ EhtFrameExchangeManager::ForwardPsduMapDown(WifiConstPsduMap psduMap, WifiTxVect
else if (m_staMac && m_staMac->IsEmlsrLink(m_linkId) &&
m_staMac->GetEmlsrManager()->GetInDeviceInterference())
{
NS_ASSERT(m_staMac->GetEmlsrManager());
m_staMac->GetEmlsrManager()->NotifyInDeviceInterferenceStart(m_linkId, txDuration);
for (const auto linkId : m_staMac->GetLinkIds())
{
if (auto phy = m_mac->GetWifiPhy(linkId);

View File

@@ -518,11 +518,32 @@ EmlsrManager::NotifyTxopEnd(uint8_t linkId, bool ulTxopNotStarted, bool ongoingD
}
}
m_staMac->UnblockTxOnLink(linkIds, WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK);
StartMediumSyncDelayTimer(linkId);
});
}
void
EmlsrManager::NotifyInDeviceInterferenceStart(uint8_t linkId, Time duration)
{
NS_LOG_FUNCTION(this << linkId << duration.As(Time::US));
NS_ASSERT(m_inDeviceInterference);
// The STA may choose not to (re)start the MediumSyncDelay timer if the transmission duration
// is less than or equal to aMediumSyncThreshold. (Sec. 35.3.16.8.1 802.11be D5.1)
if (duration <= MicroSeconds(MEDIUM_SYNC_THRESHOLD_USEC))
{
return;
}
// iterate over all the other EMLSR links
for (auto id : m_staMac->GetLinkIds())
{
if (id != linkId && m_staMac->IsEmlsrLink(id))
{
Simulator::Schedule(duration, &EmlsrManager::StartMediumSyncDelayTimer, this, id);
}
}
}
void
EmlsrManager::SetCcaEdThresholdOnLinkSwitch(Ptr<WifiPhy> phy, uint8_t linkId)
{
@@ -686,36 +707,37 @@ EmlsrManager::StartMediumSyncDelayTimer(uint8_t linkId)
{
NS_LOG_FUNCTION(this << linkId);
// iterate over all the other EMLSR links
for (auto id : m_staMac->GetLinkIds())
if (m_mediumSyncDuration.IsZero())
{
if (id != linkId && m_staMac->IsEmlsrLink(id))
{
const auto [it, inserted] = m_mediumSyncDelayStatus.try_emplace(id);
// reset the max number of TXOP attempts
it->second.msdNTxopsLeft = m_msdMaxNTxops;
// there are cases in which no PHY is operating on a link; e.g., the main PHY starts
// switching to a link on which an aux PHY gained a TXOP and sent an RTS, but the CTS
// is not received and the UL TXOP ends before the main PHY channel switch is
// completed. The MSD timer is started on the link left "uncovered" by the main PHY
if (auto phy = m_staMac->GetWifiPhy(id); phy && !it->second.timer.IsPending())
{
NS_LOG_DEBUG("Setting CCA ED threshold on link "
<< +id << " to " << +m_msdOfdmEdThreshold << " PHY " << phy);
m_prevCcaEdThreshold[phy] = phy->GetCcaEdThreshold();
phy->SetCcaEdThreshold(m_msdOfdmEdThreshold);
}
// (re)start the timer
it->second.timer.Cancel();
it->second.timer = Simulator::Schedule(m_mediumSyncDuration,
&EmlsrManager::MediumSyncDelayTimerExpired,
this,
id);
}
NS_LOG_DEBUG("MediumSyncDuration is zero");
return;
}
const auto [it, inserted] = m_mediumSyncDelayStatus.try_emplace(linkId);
// reset the max number of TXOP attempts
it->second.msdNTxopsLeft = m_msdMaxNTxops;
// there are cases in which no PHY is operating on a link; e.g., the main PHY starts
// switching to a link on which an aux PHY gained a TXOP and sent an RTS, but the CTS
// is not received and the UL TXOP ends before the main PHY channel switch is
// completed. The MSD timer is started on the link left "uncovered" by the main PHY
if (auto phy = m_staMac->GetWifiPhy(linkId); phy && !it->second.timer.IsPending())
{
NS_LOG_DEBUG("Setting CCA ED threshold on link "
<< +linkId << " to " << +m_msdOfdmEdThreshold << " PHY " << phy);
m_prevCcaEdThreshold[phy] = phy->GetCcaEdThreshold();
phy->SetCcaEdThreshold(m_msdOfdmEdThreshold);
}
// (re)start the timer
it->second.timer.Cancel();
NS_LOG_DEBUG("Starting MediumSyncDelay timer for " << m_mediumSyncDuration.As(Time::US)
<< " on link " << +linkId);
it->second.timer = Simulator::Schedule(m_mediumSyncDuration,
&EmlsrManager::MediumSyncDelayTimerExpired,
this,
linkId);
}
void

View File

@@ -41,6 +41,9 @@ class EmlsrManager : public Object
friend class ::EmlsrCcaBusyTest;
public:
/// The aMediumSyncThreshold defined by Sec. 35.3.16.18.1 of 802.11be D4.0
static constexpr uint16_t MEDIUM_SYNC_THRESHOLD_USEC = 72;
/**
* \brief Get the type ID.
* \return the object TypeId
@@ -214,6 +217,15 @@ class EmlsrManager : public Object
*/
void NotifyTxopEnd(uint8_t linkId, bool ulTxopNotStarted = false, bool ongoingDlTxop = false);
/**
* Notify that an STA affiliated with the EMLSR client is causing in-device interference
* for the given amount of time.
*
* \param linkId the ID of the link on which the STA is operating
* \param duration the duration of the in-device interference
*/
virtual void NotifyInDeviceInterferenceStart(uint8_t linkId, Time duration);
/**
* Check whether the MediumSyncDelay timer is running for the STA operating on the given link.
* If so, returns the time elapsed since the timer started.
@@ -423,11 +435,9 @@ class EmlsrManager : public Object
void SendEmlOmn();
/**
* Start the MediumSyncDelay timer and take the appropriate actions, if the timer is not
* already running.
* Start the MediumSyncDelay timer and take the appropriate actions.
*
* \param linkId the ID of the link on which a TXOP was carried out that caused the STAs
* operating on other links to lose medium synchronization
* \param linkId the ID of the link on which medium synchronization was lost
*/
void StartMediumSyncDelayTimer(uint8_t linkId);