diff --git a/src/wifi/model/he/he-frame-exchange-manager.cc b/src/wifi/model/he/he-frame-exchange-manager.cc index 4b975f221..f158a8bae 100644 --- a/src/wifi/model/he/he-frame-exchange-manager.cc +++ b/src/wifi/model/he/he-frame-exchange-manager.cc @@ -519,11 +519,13 @@ HeFrameExchangeManager::TransmissionSucceeded() m_txTimer.IsRunning() && m_txTimer.GetReason() == WifiTxTimer::WAIT_QOS_NULL_AFTER_BSRP_TF) { NS_LOG_DEBUG("Schedule another transmission in a SIFS after successful BSRP TF"); - bool (HeFrameExchangeManager::*fp)(Ptr, Time) = - &HeFrameExchangeManager::StartTransmission; - - // TXOP limit is null, hence the txopDuration parameter is unused - Simulator::Schedule(m_phy->GetSifs(), fp, this, m_edca, Seconds(0)); + Simulator::Schedule(m_phy->GetSifs(), [=, this]() { + // TXOP limit is null, hence the txopDuration parameter is unused + if (!StartTransmission(m_edca, Seconds(0))) + { + SendCfEndIfNeeded(); + } + }); if (m_protectedIfResponded) { m_protectedStas.merge(m_sentFrameTo); @@ -1325,6 +1327,15 @@ HeFrameExchangeManager::TbPpduTimeout(WifiPsduMap* psduMap, std::size_t nSolicit // no station replied, the transmission failed m_edca->UpdateFailedCw(m_linkId); + CtrlTriggerHeader trigger; + psduMap->cbegin()->second->GetPayload(0)->PeekHeader(trigger); + + if (m_continueTxopAfterBsrpTf && m_edca->GetTxopLimit(m_linkId).IsZero() && + trigger.IsBsrp()) + { + SendCfEndIfNeeded(); + } + TransmissionFailed(); } else if (!m_multiStaBaEvent.IsPending()) diff --git a/src/wifi/model/qos-frame-exchange-manager.cc b/src/wifi/model/qos-frame-exchange-manager.cc index ab7abb915..b931da361 100644 --- a/src/wifi/model/qos-frame-exchange-manager.cc +++ b/src/wifi/model/qos-frame-exchange-manager.cc @@ -74,7 +74,6 @@ QosFrameExchangeManager::SendCfEndIfNeeded() { NS_LOG_FUNCTION(this); NS_ASSERT(m_edca); - NS_ASSERT(m_edca->GetTxopLimit(m_linkId).IsStrictlyPositive()); WifiMacHeader cfEnd; cfEnd.SetType(WIFI_MAC_CTL_END); @@ -94,7 +93,7 @@ QosFrameExchangeManager::SendCfEndIfNeeded() WifiPhy::CalculateTxDuration(mpdu->GetSize(), cfEndTxVector, m_phy->GetPhyBand()); // Send the CF-End frame if the remaining duration is long enough to transmit this frame - if (m_edca->GetRemainingTxop(m_linkId) > txDuration) + if (m_edca->GetTxopLimit(m_linkId).IsZero() || m_edca->GetRemainingTxop(m_linkId) > txDuration) { NS_LOG_DEBUG("Send CF-End frame"); ForwardMpduDown(mpdu, cfEndTxVector);