Skip to content

Commit

Permalink
wifi: EMLSR clients honor the limit on max number of TXOP attempts
Browse files Browse the repository at this point in the history
  • Loading branch information
stavallo authored and Stefano Avallone committed Oct 12, 2023
1 parent 74c9b84 commit edf72af
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 1 deletion.
44 changes: 43 additions & 1 deletion src/wifi/model/eht/eht-frame-exchange-manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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))
Expand All @@ -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;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/wifi/model/eht/eht-frame-exchange-manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
38 changes: 38 additions & 0 deletions src/wifi/model/eht/emlsr-manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down
29 changes: 29 additions & 0 deletions src/wifi/model/eht/emlsr-manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit edf72af

Please sign in to comment.