wifi: AP MLD does not block links if it does not reply to an RTS sent by an EMLSR client

This commit is contained in:
Stefano Avallone
2024-09-16 15:51:56 +02:00
parent 5436ff4b1b
commit 3a5923afa0
5 changed files with 38 additions and 31 deletions

View File

@@ -1412,13 +1412,7 @@ EhtFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
NS_ASSERT(mpdu->GetHeader().GetAddr1().IsGroup() || mpdu->GetHeader().GetAddr1() == m_self);
const auto& hdr = mpdu->GetHeader();
if (m_apMac)
{
// if the AP MLD received an MPDU from an EMLSR client that is starting an UL TXOP,
// block transmissions to the EMLSR client on other links
CheckEmlsrClientStartingTxop(hdr, txVector);
}
const auto sender = hdr.GetAddr2();
if (hdr.IsTrigger())
{
@@ -1432,7 +1426,7 @@ EhtFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
if (hdr.GetAddr1() != m_self &&
(!hdr.GetAddr1().IsBroadcast() || !m_staMac->IsAssociated() ||
hdr.GetAddr2() != m_bssid // not sent by the AP this STA is associated with
sender != m_bssid // not sent by the AP this STA is associated with
|| trigger.FindUserInfoWithAid(m_staMac->GetAssociationId()) == trigger.end()))
{
return; // not addressed to us
@@ -1459,7 +1453,7 @@ EhtFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
m_ongoingTxopEnd = Simulator::Schedule(m_phy->GetSifs() + NanoSeconds(1),
&EhtFrameExchangeManager::TxopEnd,
this,
hdr.GetAddr2());
sender);
}
}
@@ -1470,6 +1464,20 @@ EhtFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
}
HeFrameExchangeManager::ReceiveMpdu(mpdu, rxSignalInfo, txVector, inAmpdu);
if (m_apMac && GetWifiRemoteStationManager()->GetEmlsrEnabled(sender))
{
if (hdr.IsRts() && !m_sendCtsEvent.IsPending())
{
// received RTS but did not send CTS (e.g., NAV busy), start transition delay
EmlsrSwitchToListening(sender, Time{0});
return;
}
// if the AP MLD received an MPDU from an EMLSR client that is starting an UL TXOP,
// block transmissions to the EMLSR client on other links
CheckEmlsrClientStartingTxop(hdr, txVector);
}
}
void

View File

@@ -73,10 +73,8 @@ FrameExchangeManager::Reset()
{
NS_LOG_FUNCTION(this);
m_txTimer.Cancel();
if (m_navResetEvent.IsPending())
{
m_navResetEvent.Cancel();
}
m_navResetEvent.Cancel();
m_sendCtsEvent.Cancel();
m_navEnd = Simulator::Now();
m_mpdu = nullptr;
m_txParams.Clear();
@@ -1344,12 +1342,12 @@ FrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
if (VirtualCsMediumIdle())
{
NS_LOG_DEBUG("Received RTS from=" << hdr.GetAddr2() << ", schedule CTS");
Simulator::Schedule(m_phy->GetSifs(),
&FrameExchangeManager::SendCtsAfterRts,
this,
hdr,
txVector.GetMode(),
rxSnr);
m_sendCtsEvent = Simulator::Schedule(m_phy->GetSifs(),
&FrameExchangeManager::SendCtsAfterRts,
this,
hdr,
txVector.GetMode(),
rxSnr);
}
else
{

View File

@@ -508,6 +508,7 @@ class FrameExchangeManager : public Object
Ptr<Txop> m_dcf; //!< the DCF/EDCAF that gained channel access
WifiTxTimer m_txTimer; //!< the timer set upon frame transmission
EventId m_navResetEvent; //!< the event to reset the NAV after an RTS
EventId m_sendCtsEvent; //!< the event to send a CTS after an (MU-)RTS
Ptr<WifiMac> m_mac; //!< the MAC layer on this station
Ptr<ApWifiMac> m_apMac; //!< AP MAC layer pointer (null if not an AP)
Ptr<StaWifiMac> m_staMac; //!< STA MAC layer pointer (null if not a STA)

View File

@@ -2640,12 +2640,12 @@ HeFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
// - The UL MU CS condition indicates that the medium is idle
// (Sec. 26.2.6.3 of 802.11ax-2021)
NS_LOG_DEBUG("Schedule CTS");
Simulator::Schedule(m_phy->GetSifs(),
&HeFrameExchangeManager::SendCtsAfterMuRts,
this,
hdr,
trigger,
rxSignalInfo.snr);
m_sendCtsEvent = Simulator::Schedule(m_phy->GetSifs(),
&HeFrameExchangeManager::SendCtsAfterMuRts,
this,
hdr,
trigger,
rxSignalInfo.snr);
}
else if (trigger.IsMuBar())
{

View File

@@ -806,12 +806,12 @@ QosFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
if (hdr.GetAddr2() == m_txopHolder || VirtualCsMediumIdle())
{
NS_LOG_DEBUG("Received RTS from=" << hdr.GetAddr2() << ", schedule CTS");
Simulator::Schedule(m_phy->GetSifs(),
&QosFrameExchangeManager::SendCtsAfterRts,
this,
hdr,
txVector.GetMode(),
rxSnr);
m_sendCtsEvent = Simulator::Schedule(m_phy->GetSifs(),
&QosFrameExchangeManager::SendCtsAfterRts,
this,
hdr,
txVector.GetMode(),
rxSnr);
}
else
{