wifi: Block transmissions on other EMLSR links as soon as DL TXOP start is detected

This commit is contained in:
Stefano Avallone
2025-05-20 12:57:15 +02:00
parent 15509b9e3e
commit edab558306
4 changed files with 42 additions and 35 deletions

View File

@@ -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

View File

@@ -329,6 +329,7 @@ AdvancedEmlsrManager::ReceivedMacHdr(Ptr<WifiPhy> 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<WifiPhy> 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();

View File

@@ -1526,10 +1526,29 @@ EhtFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> 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<const WifiMpdu> mpdu,
}
}
void
EhtFrameExchangeManager::EndReceiveAmpdu(Ptr<const WifiPsdu> psdu,
const RxSignalInfo& rxSignalInfo,
const WifiTxVector& txVector,
const std::vector<bool>& 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<const WifiMpdu> mpdu) const
{

View File

@@ -189,10 +189,6 @@ class EhtFrameExchangeManager : public HeFrameExchangeManager
RxSignalInfo rxSignalInfo,
const WifiTxVector& txVector,
bool inAmpdu) override;
void EndReceiveAmpdu(Ptr<const WifiPsdu> psdu,
const RxSignalInfo& rxSignalInfo,
const WifiTxVector& txVector,
const std::vector<bool>& perMpduStatus) override;
void NavResetTimeout() override;
void IntraBssNavResetTimeout() override;
void SendCtsAfterRts(const WifiMacHeader& rtsHdr,