wifi: EMLSR clients honor the limit on max number of TXOP attempts

This commit is contained in:
Stefano Avallone
2023-06-19 11:58:22 +02:00
committed by Stefano Avallone
parent 74c9b84e3e
commit edf72af4bf
4 changed files with 111 additions and 1 deletions

View File

@@ -154,6 +154,24 @@ EhtFrameExchangeManager::StartTransmission(Ptr<Txop> edca, uint16_t allowedWidth
NS_ASSERT_MSG(mask && !mask->test(static_cast<std::size_t>(
WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK)),
"StartTransmission called while EMLSR link is being used");
auto emlsrManager = m_staMac->GetEmlsrManager();
if (auto elapsed = emlsrManager->GetElapsedMediumSyncDelayTimer(m_linkId);
elapsed && emlsrManager->MediumSyncDelayNTxopsExceeded(m_linkId))
{
edca->NotifyChannelReleased(m_linkId);
NS_LOG_DEBUG("No new TXOP attempts allowed while MediumSyncDelay is running");
// request channel access if needed when the MediumSyncDelay timer expires
Simulator::Schedule(emlsrManager->GetMediumSyncDuration() - *elapsed, [=]() {
if (edca->GetAccessStatus(m_linkId) == Txop::NOT_REQUESTED &&
edca->HasFramesToTransmit(m_linkId))
{
m_staMac->GetChannelAccessManager(m_linkId)->RequestAccess(edca);
}
});
return false;
}
}
auto started = HeFrameExchangeManager::StartTransmission(edca, allowedWidth);
@@ -489,11 +507,35 @@ EhtFrameExchangeManager::GetEmlsrSwitchToListening(Ptr<const WifiPsdu> psdu,
return true;
}
void
EhtFrameExchangeManager::TransmissionSucceeded()
{
NS_LOG_FUNCTION(this);
if (m_staMac && m_staMac->IsEmlsrLink(m_linkId) &&
m_staMac->GetEmlsrManager()->GetElapsedMediumSyncDelayTimer(m_linkId))
{
NS_LOG_DEBUG("Reset the counter of TXOP attempts allowed while "
"MediumSyncDelay is running");
m_staMac->GetEmlsrManager()->ResetMediumSyncDelayNTxops(m_linkId);
}
HeFrameExchangeManager::TransmissionSucceeded();
}
void
EhtFrameExchangeManager::TransmissionFailed()
{
NS_LOG_FUNCTION(this);
if (m_staMac && m_staMac->IsEmlsrLink(m_linkId) &&
m_staMac->GetEmlsrManager()->GetElapsedMediumSyncDelayTimer(m_linkId))
{
NS_LOG_DEBUG("Decrement the remaining number of TXOP attempts allowed while "
"MediumSyncDelay is running");
m_staMac->GetEmlsrManager()->DecrementMediumSyncDelayNTxops(m_linkId);
}
for (const auto& address : m_txTimer.GetStasExpectedToRespond())
{
if (GetWifiRemoteStationManager()->GetEmlsrEnabled(address))
@@ -509,7 +551,7 @@ EhtFrameExchangeManager::TransmissionFailed()
// protected stations, hence next transmission to this client in this TXOP will be
// protected by ICF
NS_LOG_DEBUG("EMLSR client " << address << " did not respond, continue TXOP");
TransmissionSucceeded();
HeFrameExchangeManager::TransmissionSucceeded();
return;
}
}

View File

@@ -93,6 +93,7 @@ class EhtFrameExchangeManager : public HeFrameExchangeManager
void ForwardPsduDown(Ptr<const WifiPsdu> psdu, WifiTxVector& txVector) override;
void ForwardPsduMapDown(WifiConstPsduMap psduMap, WifiTxVector& txVector) override;
void SendMuRts(const WifiTxParameters& txParams) override;
void TransmissionSucceeded() override;
void TransmissionFailed() override;
void NotifyChannelReleased(Ptr<Txop> txop) override;
void PreProcessFrame(Ptr<const WifiPsdu> psdu, const WifiTxVector& txVector) override;

View File

@@ -621,6 +621,44 @@ EmlsrManager::MediumSyncDelayTimerExpired(uint8_t linkId)
m_prevCcaEdThreshold.erase(threshIt);
}
void
EmlsrManager::DecrementMediumSyncDelayNTxops(uint8_t linkId)
{
NS_LOG_FUNCTION(this << linkId);
const auto timerIt = m_mediumSyncDelayStatus.find(linkId);
NS_ASSERT(timerIt != m_mediumSyncDelayStatus.cend() && timerIt->second.timer.IsRunning());
NS_ASSERT(timerIt->second.msdNTxopsLeft != 0);
if (timerIt->second.msdNTxopsLeft)
{
--timerIt->second.msdNTxopsLeft.value();
}
}
void
EmlsrManager::ResetMediumSyncDelayNTxops(uint8_t linkId)
{
NS_LOG_FUNCTION(this << linkId);
auto timerIt = m_mediumSyncDelayStatus.find(linkId);
NS_ASSERT(timerIt != m_mediumSyncDelayStatus.cend() && timerIt->second.timer.IsRunning());
timerIt->second.msdNTxopsLeft.reset();
}
bool
EmlsrManager::MediumSyncDelayNTxopsExceeded(uint8_t linkId)
{
NS_LOG_FUNCTION(this << linkId);
auto timerIt = m_mediumSyncDelayStatus.find(linkId);
NS_ASSERT(timerIt != m_mediumSyncDelayStatus.cend() && timerIt->second.timer.IsRunning());
return timerIt->second.msdNTxopsLeft == 0;
}
MgtEmlOmn
EmlsrManager::GetEmlOmn()
{

View File

@@ -195,6 +195,35 @@ class EmlsrManager : public Object
*/
void CancelMediumSyncDelayTimer(uint8_t linkId);
/**
* Decrement the counter indicating the number of TXOP attempts left while the MediumSyncDelay
* timer is running. This function must not be called when the MediumSyncDelay timer is not
* running on the given link.
*
* \param linkId the ID of the link on which a new TXOP attempt may be carried out
*/
void DecrementMediumSyncDelayNTxops(uint8_t linkId);
/**
* Reset the counter indicating the number of TXOP attempts left while the MediumSyncDelay
* timer is running, so as to remove the limit on the number of attempts that can be made
* while the MediumSyncDelay timer is running. This function is normally called when a TXOP
* attempt is successful. This function must not be called when the MediumSyncDelay timer is
* not running on the given link.
*
* \param linkId the ID of the link for which the counter of the TXOP attempts is reset
*/
void ResetMediumSyncDelayNTxops(uint8_t linkId);
/**
* Return whether no more TXOP attempt is allowed on the given link. This function must not
* be called when the MediumSyncDelay timer is not running on the given link.
*
* \param linkId the ID of the link on which a new TXOP attempt may be carried out
* \return whether no more TXOP attempt on the given link is allowed
*/
bool MediumSyncDelayNTxopsExceeded(uint8_t linkId);
protected:
void DoDispose() override;