wifi: Allow starting a DL TXOP even if main PHY does not receive an ICF

This commit is contained in:
Stefano Avallone
2025-03-31 14:08:44 +02:00
parent 2cf07a6c90
commit f9b7ac722d
8 changed files with 42 additions and 30 deletions

View File

@@ -722,7 +722,7 @@ AdvancedEmlsrManager::InterruptSwitchMainPhyBackTimerIfNeeded()
}
void
AdvancedEmlsrManager::DoNotifyIcfReceived(uint8_t linkId)
AdvancedEmlsrManager::DoNotifyDlTxopStart(uint8_t linkId)
{
NS_LOG_FUNCTION(this << linkId);
m_switchMainPhyBackEvent.Cancel();

View File

@@ -140,7 +140,7 @@ class AdvancedEmlsrManager : public DefaultEmlsrManager
private:
void DoNotifyTxopEnd(uint8_t linkId, Ptr<QosTxop> edca) override;
void DoNotifyIcfReceived(uint8_t linkId) override;
void DoNotifyDlTxopStart(uint8_t linkId) override;
void DoNotifyUlTxopStart(uint8_t linkId) override;
bool m_allowUlTxopInRx; //!< whether a (main or aux) PHY is allowed to start an UL

View File

@@ -201,7 +201,7 @@ DefaultEmlsrManager::DoGetDelayUntilAccessRequest(uint8_t linkId)
}
void
DefaultEmlsrManager::DoNotifyIcfReceived(uint8_t linkId)
DefaultEmlsrManager::DoNotifyDlTxopStart(uint8_t linkId)
{
NS_LOG_FUNCTION(this << linkId);
}

View File

@@ -109,7 +109,7 @@ class DefaultEmlsrManager : public EmlsrManager
uint8_t nextLinkId,
Ptr<WifiPhy> auxPhy,
Time duration) override;
void DoNotifyIcfReceived(uint8_t linkId) override;
void DoNotifyDlTxopStart(uint8_t linkId) override;
void DoNotifyUlTxopStart(uint8_t linkId) override;
void DoNotifyTxopEnd(uint8_t linkId, Ptr<QosTxop> edca) override;
void DoNotifyProtectionCompleted(uint8_t linkId) override;

View File

@@ -1363,11 +1363,19 @@ EhtFrameExchangeManager::PostProcessFrame(Ptr<const WifiPsdu> psdu, const WifiTx
}
}
if (m_staMac && m_icfReceived)
if (m_staMac && m_dlTxopStart)
{
// we just got involved in a DL TXOP. Check if we are still involved in the TXOP in a
// SIFS (we are expected to reply in a SIFS)
m_ongoingTxopEnd.Cancel();
NS_LOG_DEBUG("Expected TXOP end=" << (Simulator::Now() + m_phy->GetSifs()).As(Time::S));
m_ongoingTxopEnd = Simulator::Schedule(m_phy->GetSifs() + TimeStep(1),
&EhtFrameExchangeManager::TxopEnd,
this,
psdu->GetAddr2());
// notify the EMLSR manager
m_staMac->GetEmlsrManager()->NotifyIcfReceived(m_linkId);
m_icfReceived = false;
m_staMac->GetEmlsrManager()->NotifyDlTxopStart(m_linkId);
m_dlTxopStart = false;
}
}
@@ -1504,23 +1512,18 @@ EhtFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
return;
}
auto emlsrManager = m_staMac->GetEmlsrManager();
NS_ASSERT(emlsrManager);
m_icfReceived = true;
// we just got involved in a DL TXOP. Check if we are still involved in the TXOP in a
// SIFS (we are expected to reply by sending a CTS frame)
m_ongoingTxopEnd.Cancel();
NS_LOG_DEBUG("Expected TXOP end=" << (Simulator::Now() + m_phy->GetSifs()).As(Time::S));
m_ongoingTxopEnd = Simulator::Schedule(m_phy->GetSifs() + NanoSeconds(1),
&EhtFrameExchangeManager::TxopEnd,
this,
sender);
m_dlTxopStart = true;
}
}
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)))
{
// a frame that is starting a DL TXOP has been received by the main PHY
m_dlTxopStart = true;
}
if (!m_icfReceived && ShallDropReceivedMpdu(mpdu))
if (!m_dlTxopStart && ShallDropReceivedMpdu(mpdu))
{
NS_LOG_DEBUG("Drop received MPDU: " << *mpdu);
return;
@@ -1553,7 +1556,16 @@ EhtFrameExchangeManager::EndReceiveAmpdu(Ptr<const WifiPsdu> psdu,
this << *psdu << rxSignalInfo << txVector << perMpduStatus.size()
<< std::all_of(perMpduStatus.begin(), perMpduStatus.end(), [](bool v) { return v; }));
if (ShallDropReceivedMpdu(*psdu->begin()))
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;
}

View File

@@ -315,8 +315,8 @@ class EhtFrameExchangeManager : public HeFrameExchangeManager
*/
void TxopEnd(const std::optional<Mac48Address>& txopHolder);
bool m_icfReceived{false}; //!< whether an ICF has been received and needs to be notified to
//!< the EMLSR manager after post-processing the frame
bool m_dlTxopStart{false}; //!< whether a DL TXOP start is detected and needs to be notified to
//!< the EMLSR manager after post-processing the initial frame
EventId m_ongoingTxopEnd; //!< event indicating the possible end of the current TXOP (of which
//!< we are not the holder)
std::unordered_map<Mac48Address, EventId, WifiAddressHash>

View File

@@ -467,7 +467,7 @@ EmlsrManager::NotifyMgtFrameReceived(Ptr<const WifiMpdu> mpdu, uint8_t linkId)
}
void
EmlsrManager::NotifyIcfReceived(uint8_t linkId)
EmlsrManager::NotifyDlTxopStart(uint8_t linkId)
{
NS_LOG_FUNCTION(this << linkId);
@@ -538,7 +538,7 @@ EmlsrManager::NotifyIcfReceived(uint8_t linkId)
SetSleepStateForAllAuxPhys(true);
}
DoNotifyIcfReceived(linkId);
DoNotifyDlTxopStart(linkId);
}
std::pair<bool, Time>

View File

@@ -234,11 +234,11 @@ class EmlsrManager : public Object
void NotifyMgtFrameReceived(Ptr<const WifiMpdu> mpdu, uint8_t linkId);
/**
* Notify the reception of an initial Control frame on the given link.
* Notify the start of a DL TXOP on the given link.
*
* @param linkId the ID of the link on which the initial Control frame was received
* @param linkId the ID of the given link
*/
void NotifyIcfReceived(uint8_t linkId);
void NotifyDlTxopStart(uint8_t linkId);
/**
* Notify the start of an UL TXOP on the given link
@@ -580,7 +580,7 @@ class EmlsrManager : public Object
*
* @param linkId the ID of the link on which the initial Control frame was received
*/
virtual void DoNotifyIcfReceived(uint8_t linkId) = 0;
virtual void DoNotifyDlTxopStart(uint8_t linkId) = 0;
/**
* Notify the subclass of the start of an UL TXOP on the given link