diff --git a/src/wifi/model/block-ack-manager.cc b/src/wifi/model/block-ack-manager.cc index 47b53da91..d274f534e 100644 --- a/src/wifi/model/block-ack-manager.cc +++ b/src/wifi/model/block-ack-manager.cc @@ -63,6 +63,10 @@ BlockAckManager::GetTypeId (void) .SetParent () .SetGroupName ("Wifi") .AddConstructor () + .AddTraceSource ("AgreementState", + "The state of the ADDBA handshake", + MakeTraceSourceAccessor (&BlockAckManager::m_agreementState), + "ns3::BlockAckManager::AgreementStateTracedCallback") ; return tid; } @@ -91,7 +95,6 @@ bool BlockAckManager::ExistsAgreementInState (Mac48Address recipient, uint8_t tid, OriginatorBlockAckAgreement::State state) const { - NS_LOG_FUNCTION (this << recipient << +tid << state); AgreementsCI it; it = m_agreements.find (std::make_pair (recipient, tid)); if (it != m_agreements.end ()) @@ -140,12 +143,14 @@ BlockAckManager::CreateAgreement (const MgtAddBaRequestHeader *reqHdr, Mac48Addr agreement.SetDelayedBlockAck (); } agreement.SetState (OriginatorBlockAckAgreement::PENDING); + uint8_t tid = reqHdr->GetTid (); + m_agreementState (Simulator::Now (), recipient, tid, OriginatorBlockAckAgreement::PENDING); PacketQueue queue; std::pair value (agreement, queue); - if (ExistsAgreement (recipient, reqHdr->GetTid ())) + if (ExistsAgreement (recipient, tid)) { // Delete agreement if it exists and in RESET state - NS_ASSERT (ExistsAgreementInState (recipient, reqHdr->GetTid (), OriginatorBlockAckAgreement::RESET)); + NS_ASSERT (ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::RESET)); m_agreements.erase (key); } m_agreements.insert (std::make_pair (key, value)); @@ -206,6 +211,10 @@ BlockAckManager::UpdateAgreement (const MgtAddBaResponseHeader *respHdr, Mac48Ad { agreement.SetDelayedBlockAck (); } + if (!it->second.first.IsEstablished ()) + { + m_agreementState (Simulator::Now (), recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED); + } agreement.SetState (OriginatorBlockAckAgreement::ESTABLISHED); if (agreement.GetTimeout () != 0) { @@ -704,6 +713,10 @@ BlockAckManager::NotifyAgreementEstablished (Mac48Address recipient, uint8_t tid NS_LOG_FUNCTION (this << recipient << +tid << startingSeq); AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); NS_ASSERT (it != m_agreements.end ()); + if (!it->second.first.IsEstablished ()) + { + m_agreementState (Simulator::Now (), recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED); + } it->second.first.SetState (OriginatorBlockAckAgreement::ESTABLISHED); it->second.first.SetStartingSequence (startingSeq); } @@ -714,6 +727,7 @@ BlockAckManager::NotifyAgreementRejected (Mac48Address recipient, uint8_t tid) NS_LOG_FUNCTION (this << recipient << +tid); AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); NS_ASSERT (it != m_agreements.end ()); + m_agreementState (Simulator::Now (), recipient, tid, OriginatorBlockAckAgreement::REJECTED); it->second.first.SetState (OriginatorBlockAckAgreement::REJECTED); } @@ -723,6 +737,7 @@ BlockAckManager::NotifyAgreementNoReply (Mac48Address recipient, uint8_t tid) NS_LOG_FUNCTION (this << recipient << +tid); AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); NS_ASSERT (it != m_agreements.end ()); + m_agreementState (Simulator::Now (), recipient, tid, OriginatorBlockAckAgreement::NO_REPLY); it->second.first.SetState (OriginatorBlockAckAgreement::NO_REPLY); m_unblockPackets (recipient, tid); } @@ -733,6 +748,7 @@ BlockAckManager::NotifyAgreementReset (Mac48Address recipient, uint8_t tid) NS_LOG_FUNCTION (this << recipient << +tid); AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); NS_ASSERT (it != m_agreements.end ()); + m_agreementState (Simulator::Now (), recipient, tid, OriginatorBlockAckAgreement::RESET); it->second.first.SetState (OriginatorBlockAckAgreement::RESET); } diff --git a/src/wifi/model/block-ack-manager.h b/src/wifi/model/block-ack-manager.h index 774c6b313..3453ed05e 100644 --- a/src/wifi/model/block-ack-manager.h +++ b/src/wifi/model/block-ack-manager.h @@ -23,6 +23,7 @@ #include #include "ns3/nstime.h" +#include "ns3/traced-callback.h" #include "wifi-mac-header.h" #include "originator-block-ack-agreement.h" #include "block-ack-type.h" @@ -408,6 +409,16 @@ public: */ void SetTxFailedCallback (TxFailed callback); + /** + * TracedCallback signature for state changes. + * + * \param [in] now Time when the \p state changed. + * \param [in] recipient MAC address of the recipient. + * \param [in] tid the TID. + * \param [in] state The state. + */ + typedef void (* AgreementStateTracedCallback)(Time now, Mac48Address recipient, uint8_t tid, OriginatorBlockAckAgreement::State state); + private: /** @@ -529,6 +540,11 @@ private: TxOk m_txOkCallback; ///< transmit ok callback TxFailed m_txFailedCallback; ///< transmit failed callback Ptr m_stationManager; ///< the station manager + + /** + * The trace source fired when a state transition occured. + */ + TracedCallback m_agreementState; }; } //namespace ns3 diff --git a/src/wifi/model/qos-txop.cc b/src/wifi/model/qos-txop.cc index 82b12bcbe..4d0cedbb9 100644 --- a/src/wifi/model/qos-txop.cc +++ b/src/wifi/model/qos-txop.cc @@ -21,6 +21,7 @@ */ #include "ns3/log.h" +#include "ns3/pointer.h" #include "ns3/simulator.h" #include "ns3/random-variable-stream.h" #include "qos-txop.h" @@ -68,6 +69,11 @@ QosTxop::GetTypeId (void) MakeTimeAccessor (&QosTxop::SetFailedAddBaTimeout, &QosTxop::GetFailedAddBaTimeout), MakeTimeChecker ()) + .AddAttribute ("BlockAckManager", + "The BlockAckManager object.", + PointerValue (), + MakePointerAccessor (&QosTxop::m_baManager), + MakePointerChecker ()) .AddTraceSource ("BackoffTrace", "Trace source for backoff values", MakeTraceSourceAccessor (&QosTxop::m_backoffTrace), diff --git a/src/wifi/test/wifi-test.cc b/src/wifi/test/wifi-test.cc index 024eaa891..6c66bbb21 100644 --- a/src/wifi/test/wifi-test.cc +++ b/src/wifi/test/wifi-test.cc @@ -1735,6 +1735,15 @@ public: virtual void DoRun (void); private: + /** + * Callback when ADDBA state changed + * \param context node context + * \param t the time the state changed + * \param recipient the MAC address of the recipient + * \param tid the TID + * \param state the state + */ + void AddbaStateChangedCallback (std::string context, Time t, Mac48Address recipient, uint8_t tid, OriginatorBlockAckAgreement::State state); /** * Callback when packet is received * \param context node context @@ -1768,13 +1777,25 @@ private: uint8_t m_receivedNormalMpduCount; ///< Count received normal MPDU packets on STA uint8_t m_receivedAmpduCount; ///< Count received A-MPDU packets on STA uint8_t m_droppedActionCount; ///< Count dropped ADDBA request/response + uint8_t m_addbaInactiveCount; ///< Count number of times ADDBA state machine is in inactive state + uint8_t m_addbaEstablishedCount; ///< Count number of times ADDBA state machine is in established state + uint8_t m_addbaPendingCount; ///< Count number of times ADDBA state machine is in pending state + uint8_t m_addbaRejectedCount; ///< Count number of times ADDBA state machine is in rejected state + uint8_t m_addbaNoReplyCount; ///< Count number of times ADDBA state machine is in no_reply state + uint8_t m_addbaResetCount; ///< Count number of times ADDBA state machine is in reset state }; Bug2470TestCase::Bug2470TestCase () : TestCase ("Test case for Bug 2470"), m_receivedNormalMpduCount (0), m_receivedAmpduCount (0), - m_droppedActionCount (0) + m_droppedActionCount (0), + m_addbaInactiveCount (0), + m_addbaEstablishedCount (0), + m_addbaPendingCount (0), + m_addbaRejectedCount (0), + m_addbaNoReplyCount (0), + m_addbaResetCount (0) { } @@ -1782,6 +1803,32 @@ Bug2470TestCase::~Bug2470TestCase () { } +void +Bug2470TestCase::AddbaStateChangedCallback (std::string context, Time t, Mac48Address recipient, uint8_t tid, OriginatorBlockAckAgreement::State state) +{ + switch (state) + { + case OriginatorBlockAckAgreement::INACTIVE: + m_addbaInactiveCount++; + break; + case OriginatorBlockAckAgreement::ESTABLISHED: + m_addbaEstablishedCount++; + break; + case OriginatorBlockAckAgreement::PENDING: + m_addbaPendingCount++; + break; + case OriginatorBlockAckAgreement::REJECTED: + m_addbaRejectedCount++; + break; + case OriginatorBlockAckAgreement::NO_REPLY: + m_addbaNoReplyCount++; + break; + case OriginatorBlockAckAgreement::RESET: + m_addbaResetCount++; + break; + } +} + void Bug2470TestCase::RxCallback (std::string context, Ptr p, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise) { @@ -1867,6 +1914,7 @@ Bug2470TestCase::RunSubtest (PointerValue apErrorModel, PointerValue staErrorMod Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/MonitorSnifferRx", MakeCallback (&Bug2470TestCase::RxCallback, this)); Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxDrop", MakeCallback (&Bug2470TestCase::RxDropCallback, this)); + Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::RegularWifiMac/BE_Txop/BlockAckManager/AgreementState", MakeCallback (&Bug2470TestCase::AddbaStateChangedCallback, this)); Simulator::Schedule (Seconds (0.5), &Bug2470TestCase::SendPacketBurst, this, 5, apDevice.Get (0), staDevice.Get (0)->GetAddress ()); Simulator::Schedule (Seconds (0.8), &Bug2470TestCase::SendPacketBurst, this, 5, apDevice.Get (0), staDevice.Get (0)->GetAddress ()); @@ -1903,11 +1951,25 @@ Bug2470TestCase::DoRun (void) // 8 A-MPDU packets. NS_TEST_ASSERT_MSG_EQ (m_receivedNormalMpduCount, 2, "Receiving incorrect number of normal MPDU packet on subtest 1"); NS_TEST_ASSERT_MSG_EQ (m_receivedAmpduCount, 8, "Receiving incorrect number of A-MPDU packet on subtest 1"); + + NS_TEST_ASSERT_MSG_EQ (m_addbaInactiveCount, 0, "Incorrect number of times the ADDBA state machine was in inactive state on subtest 1"); + NS_TEST_ASSERT_MSG_EQ (m_addbaEstablishedCount, 1, "Incorrect number of times the ADDBA state machine was in established state on subtest 1"); + NS_TEST_ASSERT_MSG_EQ (m_addbaPendingCount, 1, "Incorrect number of times the ADDBA state machine was in pending state on subtest 1"); + NS_TEST_ASSERT_MSG_EQ (m_addbaRejectedCount, 0, "Incorrect number of times the ADDBA state machine was in rejected state on subtest 1"); + NS_TEST_ASSERT_MSG_EQ (m_addbaNoReplyCount, 0, "Incorrect number of times the ADDBA state machine was in no_reply state on subtest 1"); + NS_TEST_ASSERT_MSG_EQ (m_addbaResetCount, 0, "Incorrect number of times the ADDBA state machine was in reset state on subtest 1"); } m_receivedNormalMpduCount = 0; m_receivedAmpduCount = 0; m_droppedActionCount = 0; + m_addbaInactiveCount = 0; + m_addbaEstablishedCount = 0; + m_addbaPendingCount = 0; + m_addbaRejectedCount = 0; + m_addbaNoReplyCount = 0; + m_addbaResetCount = 0; + Ptr apPem = CreateObject (); blackList.clear (); // Block ADDBA request 3 times (== maximum number of MAC frame transmissions in the addba response timeout interval) @@ -1922,6 +1984,13 @@ Bug2470TestCase::DoRun (void) // Similar to subtest 1, we also expect to receive 6 normal MPDU packets and 4 A-MPDU packets. NS_TEST_ASSERT_MSG_EQ (m_receivedNormalMpduCount, 6, "Receiving incorrect number of normal MPDU packet on subtest 2"); NS_TEST_ASSERT_MSG_EQ (m_receivedAmpduCount, 4, "Receiving incorrect number of A-MPDU packet on subtest 2"); + + NS_TEST_ASSERT_MSG_EQ (m_addbaInactiveCount, 0, "Incorrect number of times the ADDBA state machine was in inactive state on subtest 2"); + NS_TEST_ASSERT_MSG_EQ (m_addbaEstablishedCount, 1, "Incorrect number of times the ADDBA state machine was in established state on subtest 2"); + NS_TEST_ASSERT_MSG_EQ (m_addbaPendingCount, 2, "Incorrect number of times the ADDBA state machine was in pending state on subtest 2"); + NS_TEST_ASSERT_MSG_EQ (m_addbaRejectedCount, 0, "Incorrect number of times the ADDBA state machine was in rejected state on subtest 2"); + NS_TEST_ASSERT_MSG_EQ (m_addbaNoReplyCount, 1, "Incorrect number of times the ADDBA state machine was in no_reply state on subtest 2"); + NS_TEST_ASSERT_MSG_EQ (m_addbaResetCount, 1, "Incorrect number of times the ADDBA state machine was in reset state on subtest 2"); } }