diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 0e0360968..be23651fd 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -39,6 +39,7 @@ ns-3 has switched to the C++23 standard by default. ### Bugs fixed - (internet) #1251 - Added check for longest prefix match in GlobalRouting +- (wifi) Block transmission on other EMLSR links as soon as it is detected that the main PHY is receiving an A-MPDU, to prevent that the EMLSR client starts an UL TXOP before the end of the A-MPDU ## Release 3.45 diff --git a/src/wifi/model/eht/advanced-emlsr-manager.cc b/src/wifi/model/eht/advanced-emlsr-manager.cc index 96e0c3af2..3577be0a4 100644 --- a/src/wifi/model/eht/advanced-emlsr-manager.cc +++ b/src/wifi/model/eht/advanced-emlsr-manager.cc @@ -329,6 +329,7 @@ AdvancedEmlsrManager::ReceivedMacHdr(Ptr phy, NS_LOG_FUNCTION(this << *linkId << macHdr << txVector << psduDuration.As(Time::MS)); auto& ongoingTxopEnd = GetEhtFem(*linkId)->GetOngoingTxopEndEvent(); + const auto isMainPhy = (phy->GetPhyId() == GetMainPhyId()); if (ongoingTxopEnd.IsPending() && macHdr.GetAddr1() != GetEhtFem(*linkId)->GetAddress() && !macHdr.GetAddr1().IsBroadcast() && @@ -346,13 +347,30 @@ AdvancedEmlsrManager::ReceivedMacHdr(Ptr phy, Simulator::ScheduleNow(&AdvancedEmlsrManager::NotifyTxopEnd, this, *linkId, nullptr); } + if (!ongoingTxopEnd.IsPending() && GetStaMac()->IsEmlsrLink(*linkId) && isMainPhy && + !GetEhtFem(*linkId)->UsingOtherEmlsrLink() && + (macHdr.IsRts() || macHdr.IsBlockAckReq() || macHdr.IsData()) && + (macHdr.GetAddr1() == GetEhtFem(*linkId)->GetAddress())) + { + // a frame that is starting a DL TXOP is being received by the main PHY; start blocking + // transmission on other links (which is normally done later on by PostProcessFrame()) to + // avoid starting an UL TXOP before the end of the MPDU + for (auto id : GetStaMac()->GetLinkIds()) + { + if (id != *linkId && GetStaMac()->IsEmlsrLink(id)) + { + GetStaMac()->BlockTxOnLink(id, WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK); + } + } + return; + } + // if the MAC header has been received on the link on which the main PHY is operating (or on // the link the main PHY is switching to), the switch main PHY back timer is running and channel // access is not expected to be gained by the main PHY before the switch main PHY back timer // expires (plus a channel switch delay), try to switch the main PHY back to the preferred link const auto mainPhyInvolved = - (phy->GetPhyId() == GetMainPhyId()) || - (m_mainPhySwitchInfo.disconnected && m_mainPhySwitchInfo.to == *linkId); + isMainPhy || (m_mainPhySwitchInfo.disconnected && m_mainPhySwitchInfo.to == *linkId); const auto delay = Simulator::GetDelayLeft(m_switchMainPhyBackEvent) + phy->GetChannelSwitchDelay(); diff --git a/src/wifi/model/eht/eht-frame-exchange-manager.cc b/src/wifi/model/eht/eht-frame-exchange-manager.cc index ede0b4488..d0e7d4259 100644 --- a/src/wifi/model/eht/eht-frame-exchange-manager.cc +++ b/src/wifi/model/eht/eht-frame-exchange-manager.cc @@ -1526,10 +1526,29 @@ EhtFrameExchangeManager::ReceiveMpdu(Ptr mpdu, } else if (m_staMac && m_staMac->IsEmlsrLink(m_linkId) && !m_ongoingTxopEnd.IsPending() && m_phy->GetPhyId() == m_staMac->GetEmlsrManager()->GetMainPhyId() && - (hdr.IsRts() || hdr.IsBlockAckReq() || (hdr.IsData() && hdr.GetAddr1() == m_self))) + (hdr.IsRts() || hdr.IsBlockAckReq() || hdr.IsData()) && hdr.GetAddr1() == m_self) { - // a frame that is starting a DL TXOP has been received by the main PHY + // a frame that is starting a DL TXOP has been received by the main PHY, check if the frame + // shall be dropped + if (DropReceivedIcf(mpdu)) + { + return; + } + m_dlTxopStart = true; + + if (inAmpdu) + { + // start blocking transmission on other links (which is normally done later on by + // PostProcessFrame()) to avoid starting an UL TXOP before end of A-MPDU + for (auto id : m_staMac->GetLinkIds()) + { + if (id != m_linkId && m_staMac->IsEmlsrLink(id)) + { + m_staMac->BlockTxOnLink(id, WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK); + } + } + } } if (!m_dlTxopStart && ShallDropReceivedMpdu(mpdu)) @@ -1555,33 +1574,6 @@ EhtFrameExchangeManager::ReceiveMpdu(Ptr mpdu, } } -void -EhtFrameExchangeManager::EndReceiveAmpdu(Ptr psdu, - const RxSignalInfo& rxSignalInfo, - const WifiTxVector& txVector, - const std::vector& perMpduStatus) -{ - NS_LOG_FUNCTION( - this << *psdu << rxSignalInfo << txVector << perMpduStatus.size() - << std::all_of(perMpduStatus.begin(), perMpduStatus.end(), [](bool v) { return v; })); - - const auto& hdr = psdu->GetHeader(0); - if (m_staMac && m_staMac->IsEmlsrLink(m_linkId) && !m_ongoingTxopEnd.IsPending() && - m_phy->GetPhyId() == m_staMac->GetEmlsrManager()->GetMainPhyId() && - (hdr.IsData() && hdr.GetAddr1() == m_self)) - { - // a frame that is starting a DL TXOP has been received by the main PHY - m_dlTxopStart = true; - } - - if (!m_dlTxopStart && ShallDropReceivedMpdu(*psdu->begin())) - { - return; - } - - HeFrameExchangeManager::EndReceiveAmpdu(psdu, rxSignalInfo, txVector, perMpduStatus); -} - bool EhtFrameExchangeManager::ShallDropReceivedMpdu(Ptr mpdu) const { diff --git a/src/wifi/model/eht/eht-frame-exchange-manager.h b/src/wifi/model/eht/eht-frame-exchange-manager.h index ca8bbbd19..ee4a9717c 100644 --- a/src/wifi/model/eht/eht-frame-exchange-manager.h +++ b/src/wifi/model/eht/eht-frame-exchange-manager.h @@ -189,10 +189,6 @@ class EhtFrameExchangeManager : public HeFrameExchangeManager RxSignalInfo rxSignalInfo, const WifiTxVector& txVector, bool inAmpdu) override; - void EndReceiveAmpdu(Ptr psdu, - const RxSignalInfo& rxSignalInfo, - const WifiTxVector& txVector, - const std::vector& perMpduStatus) override; void NavResetTimeout() override; void IntraBssNavResetTimeout() override; void SendCtsAfterRts(const WifiMacHeader& rtsHdr,