wifi: Add ICF drop traced callback to WifiMac

This commit is contained in:
Stefano Avallone
2024-02-05 13:46:21 +01:00
committed by Stefano Avallone
parent 7eda9db2fb
commit 3e70cc182b
4 changed files with 79 additions and 2 deletions

View File

@@ -1334,6 +1334,7 @@ EhtFrameExchangeManager::DropReceivedIcf()
// started before the reception of the ICF ended. We drop this ICF and let the
// UL TXOP continue.
NS_LOG_DEBUG("Drop ICF because another EMLSR link is being used");
m_icfDropCallback(WifiIcfDrop::USING_OTHER_LINK, m_linkId);
return true;
}
}
@@ -1362,22 +1363,28 @@ EhtFrameExchangeManager::DropReceivedIcf()
{
const auto delay = mainPhy->GetChannelSwitchDelay();
auto lastTime = mainPhy->GetState()->GetLastTime({WifiPhyState::TX});
auto reason = WifiIcfDrop::NOT_ENOUGH_TIME_TX;
if (auto lastSwitch = mainPhy->GetState()->GetLastTime({WifiPhyState::SWITCHING});
lastSwitch > lastTime)
{
lastTime = lastSwitch;
reason = WifiIcfDrop::NOT_ENOUGH_TIME_SWITCH;
}
if (auto lastSleep = mainPhy->GetState()->GetLastTime({WifiPhyState::SLEEP});
lastSleep > lastTime)
{
lastTime = lastSleep;
reason = WifiIcfDrop::NOT_ENOUGH_TIME_SLEEP;
}
// ignore RX state for now
if (lastTime > Simulator::Now() - delay)
{
NS_LOG_DEBUG("Drop ICF due to not enough time for the main PHY to switch link");
NS_LOG_DEBUG(
"Drop ICF due to not enough time for the main PHY to switch link; reason = "
<< reason);
m_icfDropCallback(reason, m_linkId);
return true;
}
}

View File

@@ -23,6 +23,47 @@ extern const Time EMLSR_RX_PHY_START_DELAY;
class MgtEmlOmn;
/**
* \ingroup wifi
* Reasons for an EMLSR client to drop an ICF
*/
enum class WifiIcfDrop : uint8_t
{
USING_OTHER_LINK = 0, // another EMLSR link is being used
NOT_ENOUGH_TIME_TX, // not enough time for the main PHY to switch (because in TX state)
NOT_ENOUGH_TIME_RX, // not enough time for the main PHY to switch (because in RX state)
NOT_ENOUGH_TIME_SWITCH, // not enough time for the main PHY to switch (already switching)
NOT_ENOUGH_TIME_SLEEP, // not enough time for the main PHY to switch (because in SLEEP state)
};
/**
* \brief Stream insertion operator.
*
* \param os the stream
* \param reason the reason for dropping the ICF
* \returns a reference to the stream
*/
inline std::ostream&
operator<<(std::ostream& os, WifiIcfDrop reason)
{
switch (reason)
{
case WifiIcfDrop::USING_OTHER_LINK:
return (os << "USING_OTHER_LINK");
case WifiIcfDrop::NOT_ENOUGH_TIME_TX:
return (os << "NOT_ENOUGH_TIME_TX");
case WifiIcfDrop::NOT_ENOUGH_TIME_RX:
return (os << "NOT_ENOUGH_TIME_RX");
case WifiIcfDrop::NOT_ENOUGH_TIME_SWITCH:
return (os << "NOT_ENOUGH_TIME_SWITCH");
case WifiIcfDrop::NOT_ENOUGH_TIME_SLEEP:
return (os << "NOT_ENOUGH_TIME_SLEEP");
default:
NS_FATAL_ERROR("Unknown wifi ICF drop reason");
return (os << "UNKNOWN");
}
}
/**
* \ingroup wifi
*
@@ -120,6 +161,9 @@ class EhtFrameExchangeManager : public HeFrameExchangeManager
*/
EventId& GetOngoingTxopEndEvent();
/// ICF drop reason traced callback (WifiMac exposes this trace source)
TracedCallback<WifiIcfDrop, uint8_t> m_icfDropCallback;
protected:
void DoDispose() override;
void RxStartIndication(WifiTxVector txVector, Time psduDuration) override;

View File

@@ -359,7 +359,14 @@ WifiMac::GetTypeId()
"a SU frame or aggregated to PSDUs in the DL MU PPDU), a Basic Trigger Frame or "
"a BSRP Trigger Frame.",
MakeTraceSourceAccessor(&WifiMac::m_psduMapResponseTimeoutCallback),
"ns3::WifiMac::PsduMapResponseTimeoutCallback");
"ns3::WifiMac::PsduMapResponseTimeoutCallback")
.AddTraceSource("IcfDropReason",
"An ICF is dropped by an EMLSR client for the given reason on the "
"link with the given ID. This trace source is actually fed by the "
"EHT Frame Exchange Manager through the m_icfDropCallback member "
"variable.",
MakeTraceSourceAccessor(&WifiMac::m_icfDropCallback),
"ns3::WifiMac::IcfDropCallback");
return tid;
}
@@ -975,6 +982,11 @@ WifiMac::SetFrameExchangeManagers(const std::vector<Ptr<FrameExchangeManager>>&
MakeCallback(&DroppedMpduTracedCallback::operator(), &m_droppedMpduCallback));
link->feManager->SetAckedMpduCallback(
MakeCallback(&MpduTracedCallback::operator(), &m_ackedMpduCallback));
if (auto ehtFem = DynamicCast<EhtFrameExchangeManager>(link->feManager))
{
ehtFem->m_icfDropCallback.ConnectWithoutContext(
MakeCallback(&IcfDropTracedCallback::operator(), &m_icfDropCallback));
}
}
CompleteConfig();

View File

@@ -47,6 +47,7 @@ class ExtendedCapabilities;
class OriginatorBlockAckAgreement;
class RecipientBlockAckAgreement;
class UniformRandomVariable;
enum class WifiIcfDrop : uint8_t; // opaque enum declaration
/**
* \ingroup wifi
@@ -1334,6 +1335,19 @@ class WifiMac : public Object
* This trace source is fed by a WifiTxTimer object.
*/
PsduMapResponseTimeoutTracedCallback m_psduMapResponseTimeoutCallback;
/**
* TracedCallback signature for ICF drop events.
*
* \param reason the reason why the ICF was dropped by the EMLSR client
* \param linkId the ID of the link on which the ICF was dropped
*/
typedef void (*IcfDropCallback)(WifiIcfDrop reason, uint8_t linkId);
/// TracedCallback for ICF drop events typedef
using IcfDropTracedCallback = TracedCallback<WifiIcfDrop, uint8_t>;
IcfDropTracedCallback m_icfDropCallback; //!< traced callback for ICF drop events
};
} // namespace ns3