wifi: EMLSR clients honor the limit on max number of TXOP attempts
This commit is contained in:
committed by
Stefano Avallone
parent
74c9b84e3e
commit
edf72af4bf
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user