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
This commit is contained in:
committed by
Stefano Avallone
parent
2333d491b6
commit
cb308bd3dd
@@ -840,7 +840,8 @@ EhtFrameExchangeManager::PostProcessFrame(Ptr<const WifiPsdu> 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<const WifiMpdu> 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<const WifiMpdu> mpdu,
|
||||
}
|
||||
|
||||
void
|
||||
EhtFrameExchangeManager::TxopEnd()
|
||||
EhtFrameExchangeManager::TxopEnd(const std::optional<Mac48Address>& 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
|
||||
|
||||
@@ -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<Mac48Address>& txopHolder);
|
||||
|
||||
EventId m_ongoingTxopEnd; //!< event indicating the possible end of the current TXOP (of which
|
||||
//!< we are not the holder)
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user