From 816bdb8d5bbcaa82ccafef538799ee2dfbce2b32 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Mon, 28 Dec 2020 16:53:05 +0100 Subject: [PATCH] wifi: Add trace sources for MAC timeout events --- src/wifi/model/frame-exchange-manager.cc | 6 ++ src/wifi/model/frame-exchange-manager.h | 7 ++ src/wifi/model/regular-wifi-mac.cc | 18 +++++ src/wifi/model/regular-wifi-mac.h | 40 ++++++++++ src/wifi/model/wifi-tx-timer.cc | 37 +++++++++ src/wifi/model/wifi-tx-timer.h | 99 +++++++++++++++++++++++- 6 files changed, 205 insertions(+), 2 deletions(-) diff --git a/src/wifi/model/frame-exchange-manager.cc b/src/wifi/model/frame-exchange-manager.cc index 73e3ca758..1b34af7c5 100644 --- a/src/wifi/model/frame-exchange-manager.cc +++ b/src/wifi/model/frame-exchange-manager.cc @@ -202,6 +202,12 @@ FrameExchangeManager::IsPromisc (void) const return m_promisc; } +const WifiTxTimer& +FrameExchangeManager::GetWifiTxTimer (void) const +{ + return m_txTimer; +} + void FrameExchangeManager::NotifyPacketDiscarded (Ptr mpdu) { diff --git a/src/wifi/model/frame-exchange-manager.h b/src/wifi/model/frame-exchange-manager.h index 9eba4c67d..f4c879b8d 100644 --- a/src/wifi/model/frame-exchange-manager.h +++ b/src/wifi/model/frame-exchange-manager.h @@ -150,6 +150,13 @@ public: */ bool IsPromisc (void) const; + /** + * Get a const reference to the WifiTxTimer object. + * + * \return a const reference to the WifiTxTimer object + */ + const WifiTxTimer& GetWifiTxTimer (void) const; + /** * Get the Protection Manager used by this node. * diff --git a/src/wifi/model/regular-wifi-mac.cc b/src/wifi/model/regular-wifi-mac.cc index b7f9b7430..93c0896d6 100644 --- a/src/wifi/model/regular-wifi-mac.cc +++ b/src/wifi/model/regular-wifi-mac.cc @@ -152,6 +152,10 @@ RegularWifiMac::SetupFrameExchangeManager (void) m_feManager->SetMacRxMiddle (m_rxMiddle); m_feManager->SetAddress (GetAddress ()); m_feManager->SetBssid (GetBssid ()); + m_feManager->GetWifiTxTimer ().SetMpduResponseTimeoutCallback (MakeCallback (&MpduResponseTimeoutTracedCallback::operator(), + &m_mpduResponseTimeoutCallback)); + m_feManager->GetWifiTxTimer ().SetPsduResponseTimeoutCallback (MakeCallback (&PsduResponseTimeoutTracedCallback::operator(), + &m_psduResponseTimeoutCallback)); m_channelAccessManager->SetupFrameExchangeManager (m_feManager); if (GetQosSupported ()) { @@ -1085,6 +1089,20 @@ RegularWifiMac::GetTypeId (void) "The header of unsuccessfully transmitted packet.", MakeTraceSourceAccessor (&RegularWifiMac::m_txErrCallback), "ns3::WifiMacHeader::TracedCallback") + .AddTraceSource ("MpduResponseTimeout", + "An MPDU whose response was not received before the timeout, along with " + "an identifier of the type of timeout (see WifiTxTimer::Reason) and the " + "TXVECTOR used to transmit the MPDU. This trace source is fired when a " + "CTS is missing after an RTS or a Normal Ack is missing after an MPDU.", + MakeTraceSourceAccessor (&RegularWifiMac::m_mpduResponseTimeoutCallback), + "ns3::RegularWifiMac::MpduResponseTimeoutCallback") + .AddTraceSource ("PsduResponseTimeout", + "A PSDU whose response was not received before the timeout, along with " + "an identifier of the type of timeout (see WifiTxTimer::Reason) and the " + "TXVECTOR used to transmit the PSDU. This trace source is fired when a " + "BlockAck is missing after an A-MPDU or a BlockAckReq.", + MakeTraceSourceAccessor (&RegularWifiMac::m_psduResponseTimeoutCallback), + "ns3::RegularWifiMac::PsduResponseTimeoutCallback") ; return tid; } diff --git a/src/wifi/model/regular-wifi-mac.h b/src/wifi/model/regular-wifi-mac.h index 334e9ffff..0bb1c7778 100644 --- a/src/wifi/model/regular-wifi-mac.h +++ b/src/wifi/model/regular-wifi-mac.h @@ -32,6 +32,8 @@ class MacTxMiddle; class ChannelAccessManager; class ExtendedCapabilities; class FrameExchangeManager; +class WifiPsdu; +enum WifiTxTimerReason : uint8_t; /** * \brief base class for all MAC-level wifi objects. @@ -464,6 +466,44 @@ private: TracedCallback m_txOkCallback; ///< transmit OK callback TracedCallback m_txErrCallback; ///< transmit error callback + /** + * TracedCallback signature for MPDU response timeout events. + * + * \param reason the reason why the timer was started + * \param mpdu the MPDU whose response was not received before the timeout + * \param txVector the TXVECTOR used to transmit the MPDU + */ + typedef void (* MpduResponseTimeoutCallback)(uint8_t reason, Ptr mpdu, + const WifiTxVector& txVector); + + /// TracedCallback for MPDU response timeout events typedef + typedef TracedCallback, const WifiTxVector&> MpduResponseTimeoutTracedCallback; + + /** + * MPDU response timeout traced callback. + * This trace source is fed by a WifiTxTimer object. + */ + MpduResponseTimeoutTracedCallback m_mpduResponseTimeoutCallback; + + /** + * TracedCallback signature for PSDU response timeout events. + * + * \param reason the reason why the timer was started + * \param psdu the PSDU whose response was not received before the timeout + * \param txVector the TXVECTOR used to transmit the PSDU + */ + typedef void (* PsduResponseTimeoutCallback)(uint8_t reason, Ptr psdu, + const WifiTxVector& txVector); + + /// TracedCallback for PSDU response timeout events typedef + typedef TracedCallback, const WifiTxVector&> PsduResponseTimeoutTracedCallback; + + /** + * PSDU response timeout traced callback. + * This trace source is fed by a WifiTxTimer object. + */ + PsduResponseTimeoutTracedCallback m_psduResponseTimeoutCallback; + bool m_shortSlotTimeSupported; ///< flag whether short slot time is supported bool m_ctsToSelfSupported; ///< flag indicating whether CTS-To-Self is supported }; diff --git a/src/wifi/model/wifi-tx-timer.cc b/src/wifi/model/wifi-tx-timer.cc index f4824482e..f91caebda 100644 --- a/src/wifi/model/wifi-tx-timer.cc +++ b/src/wifi/model/wifi-tx-timer.cc @@ -20,6 +20,9 @@ #include "ns3/log.h" #include "wifi-tx-timer.h" +#include "wifi-mac-queue-item.h" +#include "wifi-tx-vector.h" +#include "wifi-psdu.h" namespace ns3 { @@ -102,4 +105,38 @@ WifiTxTimer::GetDelayLeft (void) const return Simulator::GetDelayLeft (m_timeoutEvent); } +void +WifiTxTimer::SetMpduResponseTimeoutCallback (MpduResponseTimeout callback) const +{ + m_mpduResponseTimeoutCallback = callback; +} + +template<> +void +WifiTxTimer::FeedTraceSource, WifiTxVector> (Ptr item, + WifiTxVector txVector) +{ + if (!m_mpduResponseTimeoutCallback.IsNull ()) + { + m_mpduResponseTimeoutCallback (m_reason, item, txVector); + } +} + +void +WifiTxTimer::SetPsduResponseTimeoutCallback (PsduResponseTimeout callback) const +{ + m_psduResponseTimeoutCallback = callback; +} + +template<> +void +WifiTxTimer::FeedTraceSource, WifiTxVector> (Ptr psdu, + WifiTxVector txVector) +{ + if (!m_psduResponseTimeoutCallback.IsNull ()) + { + m_psduResponseTimeoutCallback (m_reason, psdu, txVector); + } +} + } //namespace ns3 diff --git a/src/wifi/model/wifi-tx-timer.h b/src/wifi/model/wifi-tx-timer.h index 4a5951fdf..3e42d4f27 100644 --- a/src/wifi/model/wifi-tx-timer.h +++ b/src/wifi/model/wifi-tx-timer.h @@ -24,9 +24,15 @@ #include "ns3/event-id.h" #include "ns3/nstime.h" #include "ns3/simulator.h" +#include "ns3/traced-callback.h" +#include namespace ns3 { +class WifiMacQueueItem; +class WifiPsdu; +class WifiTxVector; + /** * \ingroup wifi * @@ -41,7 +47,7 @@ public: * \enum Reason * \brief The reason why the timer was started */ - enum Reason + enum Reason : uint8_t { NOT_RUNNING = 0, WAIT_CTS, @@ -116,6 +122,32 @@ public: */ Time GetDelayLeft (void) const; + /** + * MPDU response timeout callback typedef + */ + typedef Callback, const WifiTxVector&> MpduResponseTimeout; + + /** + * PSDU response timeout callback typedef + */ + typedef Callback, const WifiTxVector&> PsduResponseTimeout; + + /** + * Set the callback to invoke when the TX timer following the transmission of an MPDU expires. + * + * \param callback the callback to invoke when the TX timer following the transmission + * of an MPDU expires + */ + void SetMpduResponseTimeoutCallback (MpduResponseTimeout callback) const; + + /** + * Set the callback to invoke when the TX timer following the transmission of a PSDU expires. + * + * \param callback the callback to invoke when the TX timer following the transmission + * of a PSDU expires + */ + void SetPsduResponseTimeoutCallback (PsduResponseTimeout callback) const; + private: /** * This method is called when the timer expires. It invokes the callbacks @@ -131,12 +163,67 @@ private: template void Timeout (MEM mem_ptr, OBJ obj, Args... args); + /** + * This method is called when the timer expires to feed the trace sources + * reporting timeout events. This method does nothing, while its specializations + * actually do the job of feeding the trace sources. + * + * \tparam Args \deduced Type template parameter pack + * \param args The arguments to pass to the trace sources + */ + template + void FeedTraceSource (Args... args); + EventId m_timeoutEvent; //!< the timeout event after a missing response Reason m_reason; //!< the reason why the timer was started Ptr m_endRxEvent; //!< event to schedule upon RXSTART.indication bool m_rescheduled; //!< whether the timer has been already rescheduled + + //!< the MPDU response timeout callback + mutable MpduResponseTimeout m_mpduResponseTimeoutCallback; + //!< the PSDU response timeout callback + mutable PsduResponseTimeout m_psduResponseTimeoutCallback; }; +} // namespace ns3 + + +/*************************************************************** + * Declaration of member function template specialization. + ***************************************************************/ + +namespace ns3 { + +/** + * Explicit specialization of the FeedTraceSource member function template + * that feeds the MPDU response timeout callback. + * + * \param item the MPDU followed by no response + * \param txVector the TXVECTOR used to transmit the MPDU + */ +template<> +void WifiTxTimer::FeedTraceSource, WifiTxVector> (Ptr item, + WifiTxVector txVector); + +/** + * Explicit specialization of the FeedTraceSource member function template + * that feeds the PSDU response timeout callback. + * + * \param psdu the PSDU followed by no response + * \param txVector the TXVECTOR used to transmit the PSDU + */ +template<> +void WifiTxTimer::FeedTraceSource, WifiTxVector> (Ptr psdu, + WifiTxVector txVector); + +} // namespace ns3 + + +/*************************************************************** + * Implementation of the templates declared above. + ***************************************************************/ + +namespace ns3 { template void @@ -157,8 +244,16 @@ template void WifiTxTimer::Timeout (MEM mem_ptr, OBJ obj, Args... args) { + FeedTraceSource (std::forward (args)...); + // Invoke the method set by the user - ((*obj).*mem_ptr)(args...); + ((*obj).*mem_ptr)(std::forward (args)...); +} + +template +void +WifiTxTimer::FeedTraceSource (Args... args) +{ } } //namespace ns3