wifi: Block transmissions on other EMLSR links as soon as DL TXOP start is detected
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user