wifi: MediumSyncDelay is started if in-device interference lasts for >72us
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user