From cb308bd3ddd11e1b47e1fca67876aab14a8d2ef8 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Fri, 12 Jan 2024 12:06:54 +0100 Subject: [PATCH] wifi: Pass the TXOP holder to EHT FEM TxopEnd() because TxopEnd() may be called when the TXOP holder has been already reset, e.g., when a TXOP is terminated with a CF-End frame --- .../model/eht/eht-frame-exchange-manager.cc | 32 +++++++++++-------- .../model/eht/eht-frame-exchange-manager.h | 4 ++- src/wifi/test/wifi-emlsr-test.cc | 28 ++++++++-------- 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/wifi/model/eht/eht-frame-exchange-manager.cc b/src/wifi/model/eht/eht-frame-exchange-manager.cc index 54afe69a5..f7c51cdaf 100644 --- a/src/wifi/model/eht/eht-frame-exchange-manager.cc +++ b/src/wifi/model/eht/eht-frame-exchange-manager.cc @@ -840,7 +840,8 @@ EhtFrameExchangeManager::PostProcessFrame(Ptr psdu, const WifiTx auto delay = m_phy->GetSifs() + m_phy->GetSlot() + MicroSeconds(RX_PHY_START_DELAY_USEC); NS_LOG_DEBUG("Expected TXOP end=" << (Simulator::Now() + delay).As(Time::S)); - m_ongoingTxopEnd = Simulator::Schedule(delay, &EhtFrameExchangeManager::TxopEnd, this); + m_ongoingTxopEnd = + Simulator::Schedule(delay, &EhtFrameExchangeManager::TxopEnd, this, m_txopHolder); } else { @@ -991,7 +992,8 @@ EhtFrameExchangeManager::ReceiveMpdu(Ptr mpdu, 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); + this, + hdr.GetAddr2()); } } @@ -1015,9 +1017,9 @@ EhtFrameExchangeManager::ReceiveMpdu(Ptr mpdu, } void -EhtFrameExchangeManager::TxopEnd() +EhtFrameExchangeManager::TxopEnd(const std::optional& txopHolder) { - NS_LOG_FUNCTION(this); + NS_LOG_FUNCTION(this << txopHolder.has_value()); if (m_phy->IsReceivingPhyHeader()) { @@ -1028,7 +1030,8 @@ EhtFrameExchangeManager::TxopEnd() NS_LOG_DEBUG("PHY is decoding the PHY header of PPDU, postpone TXOP end"); m_ongoingTxopEnd = Simulator::Schedule(MicroSeconds(WAIT_FOR_RXSTART_DELAY_USEC), &EhtFrameExchangeManager::TxopEnd, - this); + this, + txopHolder); return; } @@ -1036,11 +1039,10 @@ EhtFrameExchangeManager::TxopEnd() { m_staMac->GetEmlsrManager()->NotifyTxopEnd(m_linkId); } - else if (m_apMac && m_txopHolder && - GetWifiRemoteStationManager()->GetEmlsrEnabled(*m_txopHolder)) + else if (m_apMac && txopHolder && GetWifiRemoteStationManager()->GetEmlsrEnabled(*txopHolder)) { // EMLSR client terminated its TXOP and is back to listening operation - EmlsrSwitchToListening(*m_txopHolder, Seconds(0)); + EmlsrSwitchToListening(*txopHolder, Seconds(0)); } } @@ -1083,7 +1085,8 @@ EhtFrameExchangeManager::UpdateTxopEndOnTxStart(Time txDuration, Time durationId } NS_LOG_DEBUG("Expected TXOP end=" << (Simulator::Now() + delay).As(Time::S)); - m_ongoingTxopEnd = Simulator::Schedule(delay, &EhtFrameExchangeManager::TxopEnd, this); + m_ongoingTxopEnd = + Simulator::Schedule(delay, &EhtFrameExchangeManager::TxopEnd, this, m_txopHolder); } void @@ -1101,8 +1104,10 @@ EhtFrameExchangeManager::UpdateTxopEndOnRxStartIndication(Time psduDuration) m_ongoingTxopEnd.Cancel(); NS_LOG_DEBUG("Expected TXOP end=" << (Simulator::Now() + psduDuration).As(Time::S)); - m_ongoingTxopEnd = - Simulator::Schedule(psduDuration + NanoSeconds(1), &EhtFrameExchangeManager::TxopEnd, this); + m_ongoingTxopEnd = Simulator::Schedule(psduDuration + NanoSeconds(1), + &EhtFrameExchangeManager::TxopEnd, + this, + m_txopHolder); } void @@ -1123,7 +1128,7 @@ EhtFrameExchangeManager::UpdateTxopEndOnRxEnd(Time durationId) if (durationId <= m_phy->GetSifs()) { NS_LOG_DEBUG("Assume TXOP ended based on Duration/ID value"); - TxopEnd(); + TxopEnd(m_txopHolder); return; } @@ -1131,7 +1136,8 @@ EhtFrameExchangeManager::UpdateTxopEndOnRxEnd(Time durationId) // Postpone the TXOP end by considering the latter (which takes longer) auto delay = m_phy->GetSifs() + m_phy->GetSlot() + MicroSeconds(RX_PHY_START_DELAY_USEC); NS_LOG_DEBUG("Expected TXOP end=" << (Simulator::Now() + delay).As(Time::S)); - m_ongoingTxopEnd = Simulator::Schedule(delay, &EhtFrameExchangeManager::TxopEnd, this); + m_ongoingTxopEnd = + Simulator::Schedule(delay, &EhtFrameExchangeManager::TxopEnd, this, m_txopHolder); } } // namespace ns3 diff --git a/src/wifi/model/eht/eht-frame-exchange-manager.h b/src/wifi/model/eht/eht-frame-exchange-manager.h index cdd276c95..8f87a68e0 100644 --- a/src/wifi/model/eht/eht-frame-exchange-manager.h +++ b/src/wifi/model/eht/eht-frame-exchange-manager.h @@ -156,8 +156,10 @@ class EhtFrameExchangeManager : public HeFrameExchangeManager /** * Take actions when a TXOP (of which we are not the holder) ends. + * + * \param txopHolder the holder of the TXOP (if any) */ - void TxopEnd(); + void TxopEnd(const std::optional& txopHolder); EventId m_ongoingTxopEnd; //!< event indicating the possible end of the current TXOP (of which //!< we are not the holder) diff --git a/src/wifi/test/wifi-emlsr-test.cc b/src/wifi/test/wifi-emlsr-test.cc index 005eaa96f..e0a976f9f 100644 --- a/src/wifi/test/wifi-emlsr-test.cc +++ b/src/wifi/test/wifi-emlsr-test.cc @@ -1483,12 +1483,13 @@ EmlsrDlTxopTest::CheckResults() */ // for each EMLSR client, there should be a frame exchange with ICF and no data frame - // (ICF protects the EML Notification response) and two frame exchanges with data frames + // (ICF protects the EML Notification response) if the EML Notification response is sent + // while EMLSR mode is still enabled and two frame exchanges with data frames for (std::size_t i = 0; i < m_nEmlsrStations; i++) { // the default EMLSR Manager requests to send EML Notification frames on the link where - // the main PHY is operating, hence this link is an EMLSR link and the EML Notification - // frame is protected by an ICF + // the main PHY is operating; if EMLSR mode is still enabled on this link when the AP MLD + // sends the EML Notification response, the latter is protected by an ICF auto exchangeIt = frameExchanges.at(i).cbegin(); auto linkIdOpt = m_staMacs[i]->GetLinkForPhy(m_mainPhyId); @@ -1496,17 +1497,16 @@ EmlsrDlTxopTest::CheckResults() true, "Didn't find a link on which the main PHY is operating"); - NS_TEST_EXPECT_MSG_EQ(IsTrigger(exchangeIt->front()->psduMap), - true, - "Expected an MU-RTS TF as ICF of first frame exchange sequence"); - NS_TEST_EXPECT_MSG_EQ(+exchangeIt->front()->linkId, - +linkIdOpt.value(), - "ICF was not sent on the expected link"); - NS_TEST_EXPECT_MSG_EQ(exchangeIt->size(), - 1, - "Expected no data frame in the first frame exchange sequence"); - - frameExchanges.at(i).pop_front(); + if (IsTrigger(exchangeIt->front()->psduMap)) + { + NS_TEST_EXPECT_MSG_EQ(+exchangeIt->front()->linkId, + +linkIdOpt.value(), + "ICF was not sent on the expected link"); + NS_TEST_EXPECT_MSG_EQ(exchangeIt->size(), + 1, + "Expected no data frame in the first frame exchange sequence"); + frameExchanges.at(i).pop_front(); + } NS_TEST_EXPECT_MSG_GT_OR_EQ(frameExchanges.at(i).size(), 2,