diff --git a/src/wifi/model/frame-exchange-manager.cc b/src/wifi/model/frame-exchange-manager.cc index 1b34af7c5..b3ea7b987 100644 --- a/src/wifi/model/frame-exchange-manager.cc +++ b/src/wifi/model/frame-exchange-manager.cc @@ -190,6 +190,13 @@ FrameExchangeManager::SetBssid (Mac48Address bssid) m_bssid = bssid; } +void +FrameExchangeManager::SetDroppedMpduCallback (DroppedMpdu callback) +{ + NS_LOG_FUNCTION (this << &callback); + m_droppedMpduCallback = callback; +} + void FrameExchangeManager::SetPromisc (void) { @@ -211,7 +218,10 @@ FrameExchangeManager::GetWifiTxTimer (void) const void FrameExchangeManager::NotifyPacketDiscarded (Ptr mpdu) { - m_mac->NotifyTxDrop (mpdu->GetPacket ()); + if (!m_droppedMpduCallback.IsNull ()) + { + m_droppedMpduCallback (WIFI_MAC_DROP_REACHED_RETRY_LIMIT, mpdu); + } } void diff --git a/src/wifi/model/frame-exchange-manager.h b/src/wifi/model/frame-exchange-manager.h index f4c879b8d..58b0c68b5 100644 --- a/src/wifi/model/frame-exchange-manager.h +++ b/src/wifi/model/frame-exchange-manager.h @@ -57,6 +57,11 @@ public: FrameExchangeManager (); virtual ~FrameExchangeManager (); + /** + * typedef for a callback to invoke when an MPDU is dropped. + */ + typedef Callback > DroppedMpdu; + /** * Request the FrameExchangeManager to start a frame exchange sequence. * @@ -138,6 +143,12 @@ public: * \param bssid the BSSID */ virtual void SetBssid (Mac48Address bssid); + /** + * Set the callback to invoke when an MPDU is dropped. + * + * \param callback the callback to invoke when an MPDU is dropped + */ + virtual void SetDroppedMpduCallback (DroppedMpdu callback); /** * Enable promiscuous mode. */ @@ -306,8 +317,8 @@ protected: virtual void RetransmitMpduAfterMissedCts (Ptr mpdu) const; /** - * Pass the packet included in the given MPDU to the - * packet dropped callback. + * Pass the given MPDU, discarded because of the max retry limit was reached, + * to the MPDU dropped callback. * * \param mpdu the discarded MPDU */ @@ -357,6 +368,7 @@ protected: Mac48Address m_bssid; //!< BSSID address (Mac48Address) Time m_navEnd; //!< NAV expiration time bool m_promisc; //!< Flag if the device is operating in promiscuous mode + DroppedMpdu m_droppedMpduCallback; //!< the dropped MPDU callback /** * Forward an MPDU down to the PHY layer. diff --git a/src/wifi/model/qos-txop.cc b/src/wifi/model/qos-txop.cc index 9e771a83e..42b6fce26 100644 --- a/src/wifi/model/qos-txop.cc +++ b/src/wifi/model/qos-txop.cc @@ -144,6 +144,16 @@ QosTxop::SetQosFrameExchangeManager (const Ptr qosFem) m_qosFem = qosFem; } +void +QosTxop::SetDroppedMpduCallback (DroppedMpdu callback) +{ + NS_LOG_FUNCTION (this << &callback); + Txop::SetDroppedMpduCallback (callback); + m_baManager->GetRetransmitQueue ()->TraceConnectWithoutContext ("Expired", + m_droppedMpduCallback + .Bind (WIFI_MAC_DROP_EXPIRED_LIFETIME)); +} + Ptr QosTxop::GetBaManager (void) { @@ -507,9 +517,9 @@ QosTxop::NotifyInternalCollision (void) { NS_LOG_DEBUG ("reset DCF"); m_stationManager->ReportFinalDataFailed (mpdu); - if (!m_txDroppedCallback.IsNull ()) + if (!m_droppedMpduCallback.IsNull ()) { - m_txDroppedCallback (mpdu->GetPacket ()); + m_droppedMpduCallback (WIFI_MAC_DROP_REACHED_RETRY_LIMIT, mpdu); } ResetCw (); // We have to discard mpdu, but first we have to determine whether mpdu diff --git a/src/wifi/model/qos-txop.h b/src/wifi/model/qos-txop.h index 4ca31a5e7..907f99703 100644 --- a/src/wifi/model/qos-txop.h +++ b/src/wifi/model/qos-txop.h @@ -105,6 +105,7 @@ public: void NotifyInternalCollision (void); virtual void NotifyChannelAccessed (Time txopDuration); void NotifyChannelReleased (void); + void SetDroppedMpduCallback (DroppedMpdu callback); /** * Set type of station with the given type. diff --git a/src/wifi/model/regular-wifi-mac.cc b/src/wifi/model/regular-wifi-mac.cc index 93c0896d6..0a5f62684 100644 --- a/src/wifi/model/regular-wifi-mac.cc +++ b/src/wifi/model/regular-wifi-mac.cc @@ -62,7 +62,8 @@ RegularWifiMac::RegularWifiMac () m_txop->SetTxMiddle (m_txMiddle); m_txop->SetTxOkCallback (MakeCallback (&RegularWifiMac::TxOk, this)); m_txop->SetTxFailedCallback (MakeCallback (&RegularWifiMac::TxFailed, this)); - m_txop->SetTxDroppedCallback (MakeCallback (&RegularWifiMac::NotifyTxDrop, this)); + m_txop->SetDroppedMpduCallback (MakeCallback (&DroppedMpduTracedCallback::operator(), + &m_droppedMpduCallback)); //Construct the EDCAFs. The ordering is important - highest //priority (Table 9-1 UP-to-AC mapping; IEEE 802.11-2012) must be created @@ -156,6 +157,8 @@ RegularWifiMac::SetupFrameExchangeManager (void) &m_mpduResponseTimeoutCallback)); m_feManager->GetWifiTxTimer ().SetPsduResponseTimeoutCallback (MakeCallback (&PsduResponseTimeoutTracedCallback::operator(), &m_psduResponseTimeoutCallback)); + m_feManager->SetDroppedMpduCallback (MakeCallback (&DroppedMpduTracedCallback::operator(), + &m_droppedMpduCallback)); m_channelAccessManager->SetupFrameExchangeManager (m_feManager); if (GetQosSupported ()) { @@ -467,7 +470,8 @@ RegularWifiMac::SetupEdcaQueue (AcIndex ac) edca->SetTxMiddle (m_txMiddle); edca->SetTxOkCallback (MakeCallback (&RegularWifiMac::TxOk, this)); edca->SetTxFailedCallback (MakeCallback (&RegularWifiMac::TxFailed, this)); - edca->SetTxDroppedCallback (MakeCallback (&RegularWifiMac::NotifyTxDrop, this)); + edca->SetDroppedMpduCallback (MakeCallback (&DroppedMpduTracedCallback::operator(), + &m_droppedMpduCallback)); edca->SetAccessCategory (ac); edca->CompleteConfig (); @@ -1089,6 +1093,10 @@ RegularWifiMac::GetTypeId (void) "The header of unsuccessfully transmitted packet.", MakeTraceSourceAccessor (&RegularWifiMac::m_txErrCallback), "ns3::WifiMacHeader::TracedCallback") + .AddTraceSource ("DroppedMpdu", + "An MPDU that was dropped for the given reason (see WifiMacDropReason).", + MakeTraceSourceAccessor (&RegularWifiMac::m_droppedMpduCallback), + "ns3::RegularWifiMac::DroppedMpduCallback") .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 " diff --git a/src/wifi/model/regular-wifi-mac.h b/src/wifi/model/regular-wifi-mac.h index 0bb1c7778..07b742e20 100644 --- a/src/wifi/model/regular-wifi-mac.h +++ b/src/wifi/model/regular-wifi-mac.h @@ -466,6 +466,22 @@ private: TracedCallback m_txOkCallback; ///< transmit OK callback TracedCallback m_txErrCallback; ///< transmit error callback + /** + * TracedCallback signature for MPDU drop events. + * + * \param reason the reason why the MPDU was dropped (\see WifiMacDropReason) + * \param mpdu the dropped MPDU + */ + typedef void (* DroppedMpduCallback)(WifiMacDropReason reason, Ptr mpdu); + + /// TracedCallback for MPDU drop events typedef + typedef TracedCallback> DroppedMpduTracedCallback; + + /** + * This trace indicates that an MPDU was dropped for the given reason. + */ + DroppedMpduTracedCallback m_droppedMpduCallback; + /** * TracedCallback signature for MPDU response timeout events. * diff --git a/src/wifi/model/txop.cc b/src/wifi/model/txop.cc index d1ed9cc92..887991ef1 100644 --- a/src/wifi/model/txop.cc +++ b/src/wifi/model/txop.cc @@ -150,20 +150,14 @@ Txop::SetTxFailedCallback (TxFailed callback) } void -Txop::SetTxDroppedCallback (TxDropped callback) +Txop::SetDroppedMpduCallback (DroppedMpdu callback) { NS_LOG_FUNCTION (this << &callback); - m_txDroppedCallback = callback; - m_queue->TraceConnectWithoutContext ("Drop", MakeCallback (&Txop::TxDroppedPacket, this)); -} - -void -Txop::TxDroppedPacket (Ptr item) -{ - if (!m_txDroppedCallback.IsNull ()) - { - m_txDroppedCallback (item->GetPacket ()); - } + m_droppedMpduCallback = callback; + m_queue->TraceConnectWithoutContext ("DropBeforeEnqueue", + m_droppedMpduCallback.Bind (WIFI_MAC_DROP_FAILED_ENQUEUE)); + m_queue->TraceConnectWithoutContext ("Expired", + m_droppedMpduCallback.Bind (WIFI_MAC_DROP_EXPIRED_LIFETIME)); } Ptr diff --git a/src/wifi/model/txop.h b/src/wifi/model/txop.h index 8cca022af..37daa648b 100644 --- a/src/wifi/model/txop.h +++ b/src/wifi/model/txop.h @@ -35,6 +35,7 @@ class WifiMacQueueItem; class UniformRandomVariable; class CtrlBAckResponseHeader; class WifiRemoteStationManager; +enum WifiMacDropReason : uint8_t; // opaque enum declaration /** * \brief Handle packet fragmentation and retransmissions @@ -86,10 +87,9 @@ public: */ typedef Callback TxFailed; /** - * typedef for a callback to invoke when a - * packet is dropped. + * typedef for a callback to invoke when an MPDU is dropped. */ - typedef Callback > TxDropped; + typedef Callback > DroppedMpdu; /** * Enumeration for channel access status @@ -138,10 +138,9 @@ public: */ void SetTxFailedCallback (TxFailed callback); /** - * \param callback the callback to invoke when a - * packet is dropped. + * \param callback the callback to invoke when an MPDU is dropped */ - void SetTxDroppedCallback (TxDropped callback); + virtual void SetDroppedMpduCallback (DroppedMpdu callback); /** * Return the packet queue associated with this Txop. @@ -342,19 +341,10 @@ protected: */ void UpdateBackoffSlotsNow (uint32_t nSlots, Time backoffUpdateBound); - /** - * - * Pass the packet included in the wifi MAC queue item to the - * packet dropped callback. - * - * \param item the wifi MAC queue item. - */ - void TxDroppedPacket (Ptr item); - Ptr m_channelAccessManager; //!< the channel access manager TxOk m_txOkCallback; //!< the transmit OK callback TxFailed m_txFailedCallback; //!< the transmit failed callback - TxDropped m_txDroppedCallback; //!< the packet dropped callback + DroppedMpdu m_droppedMpduCallback; //!< the dropped MPDU callback Ptr m_queue; //!< the wifi MAC queue Ptr m_txMiddle; //!< the MacTxMiddle Ptr m_stationManager; //!< the wifi remote station manager diff --git a/src/wifi/model/wifi-mac.cc b/src/wifi/model/wifi-mac.cc index ca9522f08..ea7de2e13 100644 --- a/src/wifi/model/wifi-mac.cc +++ b/src/wifi/model/wifi-mac.cc @@ -51,7 +51,10 @@ WifiMac::GetTypeId (void) MakeTraceSourceAccessor (&WifiMac::m_macTxTrace), "ns3::Packet::TracedCallback") .AddTraceSource ("MacTxDrop", - "A packet has been dropped in the MAC layer before transmission.", + "A packet has been dropped in the MAC layer before being queued for transmission. " + "This trace source is fired, e.g., when an AP's MAC receives from the upper layer " + "a packet destined to a station that is not associated with the AP or a STA's MAC " + "receives a packet from the upper layer while it is not associated with any AP.", MakeTraceSourceAccessor (&WifiMac::m_macTxDropTrace), "ns3::Packet::TracedCallback") .AddTraceSource ("MacPromiscRx", diff --git a/src/wifi/model/wifi-mac.h b/src/wifi/model/wifi-mac.h index 5dfee9c90..648024d14 100644 --- a/src/wifi/model/wifi-mac.h +++ b/src/wifi/model/wifi-mac.h @@ -34,6 +34,18 @@ class HtConfiguration; class VhtConfiguration; class HeConfiguration; +/** + * \ingroup wifi + * \enum WifiMacDropReason + * \brief The reason why an MPDU was dropped + */ +enum WifiMacDropReason : uint8_t +{ + WIFI_MAC_DROP_FAILED_ENQUEUE = 0, + WIFI_MAC_DROP_EXPIRED_LIFETIME, + WIFI_MAC_DROP_REACHED_RETRY_LIMIT +}; + /** * \brief base class for all MAC-level wifi objects. * \ingroup wifi @@ -186,9 +198,9 @@ public: /** * \param packet the packet being dropped * - * Public method used to fire a MacTxDrop trace. Implemented for encapsulation purposes. - * This trace indicates that the packet was dropped before it was transmitted - * (e.g. when a STA is not associated with an AP). + * Public method used to fire a MacTxDrop trace. + * This trace indicates that the packet was dropped before it was queued for + * transmission (e.g. when a STA is not associated with an AP). */ void NotifyTxDrop (Ptr packet); /** @@ -258,7 +270,7 @@ private: TracedCallback > m_macTxTrace; /** * The trace source fired when packets coming into the "top" of the device - * are dropped at the MAC layer during transmission. + * are dropped at the MAC layer before being queued for transmission. * * \see class CallBackTraceSource */ diff --git a/src/wifi/test/wifi-aggregation-test.cc b/src/wifi/test/wifi-aggregation-test.cc index 66fd27674..57e9c8549 100644 --- a/src/wifi/test/wifi-aggregation-test.cc +++ b/src/wifi/test/wifi-aggregation-test.cc @@ -59,12 +59,13 @@ public: AmpduAggregationTest (); private: - /* - * Fired when the MAC discards a packet. + /** + * Fired when the MAC discards an MPDU. * - * \param packet the discarded packet + * \param reason the reason why the MPDU was discarded + * \param mpdu the discarded MPDU */ - void PacketDiscarded (Ptr packet); + void MpduDiscarded (WifiMacDropReason reason, Ptr mpdu); virtual void DoRun (void); Ptr m_device; /// packet) +AmpduAggregationTest::MpduDiscarded (WifiMacDropReason, Ptr) { m_discarded = true; } @@ -295,7 +296,7 @@ AmpduAggregationTest::DoRun (void) NS_TEST_EXPECT_MSG_EQ (mpduList.empty (), true, "no MPDU aggregation should be performed if there is no agreement"); m_manager->SetMaxSsrc (0); //set to 0 in order to fake that the maximum number of retries has been reached - m_mac->TraceConnectWithoutContext ("MacTxDrop", MakeCallback (&AmpduAggregationTest::PacketDiscarded, this)); + m_mac->TraceConnectWithoutContext ("DroppedMpdu", MakeCallback (&AmpduAggregationTest::MpduDiscarded, this)); htFem->m_dcf = m_mac->GetBEQueue (); htFem->NormalAckTimeout (item, txParams.m_txVector);