22 #include "ns3/simulator.h"
23 #include "ns3/channel-access-manager.h"
24 #include "ns3/frame-exchange-manager.h"
25 #include "ns3/qos-txop.h"
29 template <
typename TxopType>
38 template <
typename TxopType>
55 void QueueTx (uint64_t txTime, uint64_t expectedGrantTime);
62 void DoDispose (
void)
override;
64 void NotifyChannelAccessed (
Time txopDuration =
Seconds (0))
override;
66 bool HasFramesToTransmit (
void)
override;
68 void NotifySleep (
void)
override;
70 void NotifyWakeUp (
void)
override;
134 m_eifsNoDifs = eifsNoDifs;
164 template <
typename TxopType>
197 m_test->NotifyChannelSwitching ();
210 template <
typename TxopType>
221 void NotifyAccessGranted (uint32_t i);
231 void GenerateBackoff (uint32_t i);
235 void NotifyChannelSwitching (
void);
246 void StartTest (uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue = 20);
251 void AddTxop (uint32_t aifsn);
260 void ExpectInternalCollision (uint64_t time, uint32_t nSlots, uint32_t from);
267 void ExpectBackoff (uint64_t time, uint32_t nSlots, uint32_t from);
273 void ExpectBusy (uint64_t time,
bool busy);
278 void DoCheckBusy (
bool busy);
284 void AddRxOkEvt (uint64_t at, uint64_t duration);
290 void AddRxErrorEvt (uint64_t at, uint64_t duration);
297 void AddRxErrorEvt (uint64_t at, uint64_t duration, uint64_t timeUntilError);
303 void AddRxInsideSifsEvt (uint64_t at, uint64_t duration);
309 void AddTxEvt (uint64_t at, uint64_t duration);
315 void AddNavReset (uint64_t at, uint64_t duration);
321 void AddNavStart (uint64_t at, uint64_t duration);
326 void AddAckTimeoutReset (uint64_t at);
334 void AddAccessRequest (uint64_t at, uint64_t txTime,
335 uint64_t expectedGrantTime, uint32_t from);
343 void AddAccessRequestWithAckTimeout (uint64_t at, uint64_t txTime,
344 uint64_t expectedGrantTime, uint32_t from);
353 void AddAccessRequestWithSuccessfullAck (uint64_t at, uint64_t txTime,
354 uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from);
367 void AddCcaBusyEvt (uint64_t at, uint64_t duration);
373 void AddSwitchingEvt (uint64_t at, uint64_t duration);
379 void AddRxStartEvt (uint64_t at, uint64_t duration);
389 template <
typename TxopType>
393 m_expectedGrants.push_back (std::make_pair (txTime, expectedGrantTime));
396 template <
typename TxopType>
403 template <
typename TxopType>
408 TxopType::DoDispose ();
411 template <
typename TxopType>
415 Txop::m_access = Txop::NOT_REQUESTED;
416 m_test->NotifyAccessGranted (m_i);
419 template <
typename TxopType>
423 m_test->GenerateBackoff (m_i);
426 template <
typename TxopType>
430 return !m_expectedGrants.empty ();
433 template <
typename TxopType>
439 template <
typename TxopType>
445 template <
typename TxopType>
451 template <
typename TxopType>
457 if (!state->m_expectedGrants.empty ())
459 std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front ();
460 state->m_expectedGrants.pop_front ();
462 m_ChannelAccessManager->NotifyTxStartNow (
MicroSeconds (expected.first));
463 m_ChannelAccessManager->NotifyAckTimeoutStartNow (
MicroSeconds (m_ackTimeoutValue + expected.first));
467 template <
typename TxopType>
472 &ChannelAccessManager::NotifyTxStartNow, m_ChannelAccessManager,
476 template <
typename TxopType>
480 NS_TEST_EXPECT_MSG_EQ (state->m_expectedInternalCollision.empty (),
false,
"Have expected internal collisions");
481 if (!state->m_expectedInternalCollision.empty ())
485 NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.at), "Expected internal collision time is now");
486 state->StartBackoffNow (expected.nSlots);
490 template <typename TxopType>
496 if (!state->m_expectedBackoff.empty ())
501 state->StartBackoffNow (expected.nSlots);
505 template <typename TxopType>
509 for (
auto& state : m_txop)
511 if (!state->m_expectedGrants.empty ())
513 std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front ();
514 state->m_expectedGrants.pop_front ();
517 state->Txop::m_access = Txop::NOT_REQUESTED;
521 template <
typename TxopType>
532 template <typename TxopType>
539 backoff.nSlots = nSlots;
543 template <typename TxopType>
551 template <
typename TxopType>
558 template <
typename TxopType>
562 m_ChannelAccessManager = CreateObject<ChannelAccessManagerStub> ();
563 m_feManager = CreateObject<FrameExchangeManagerStub<TxopType>> (
this);
564 m_ChannelAccessManager->SetupFrameExchangeManager (m_feManager);
565 m_ChannelAccessManager->SetSlot (
MicroSeconds (slotTime));
567 m_ChannelAccessManager->SetEifsNoDifs (
MicroSeconds (eifsNoDifsNoSifs + sifs));
568 m_ackTimeoutValue = ackTimeoutValue;
571 template <
typename TxopType>
576 txop->SetAifsn (aifsn);
577 m_txop.push_back (txop);
578 txop->SetChannelAccessManager (m_ChannelAccessManager);
581 template <
typename TxopType>
587 for (
typename TxopTests::const_iterator i = m_txop.begin (); i != m_txop.end (); i++)
591 NS_TEST_EXPECT_MSG_EQ (state->m_expectedInternalCollision.empty (),
true,
"Have no internal collisions");
598 m_ChannelAccessManager->Dispose ();
599 m_ChannelAccessManager = 0;
601 Simulator::Destroy ();
604 template <
typename TxopType>
609 &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
612 &ChannelAccessManager::NotifyRxEndOkNow, m_ChannelAccessManager);
615 template <
typename TxopType>
620 &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
624 template <
typename TxopType>
629 &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
632 &ChannelAccessManager::NotifyRxEndErrorNow, m_ChannelAccessManager);
635 template <
typename TxopType>
640 &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
643 &ChannelAccessManager::NotifyRxEndErrorNow, m_ChannelAccessManager);
647 template <
typename TxopType>
652 &ChannelAccessManager::NotifyNavResetNow, m_ChannelAccessManager,
656 template <
typename TxopType>
661 &ChannelAccessManager::NotifyNavStartNow, m_ChannelAccessManager,
665 template <
typename TxopType>
670 &ChannelAccessManager::NotifyAckTimeoutResetNow, m_ChannelAccessManager);
673 template <
typename TxopType>
676 uint64_t expectedGrantTime, uint32_t from)
678 AddAccessRequestWithSuccessfullAck (at, txTime, expectedGrantTime, 0, from);
681 template <
typename TxopType>
684 uint64_t expectedGrantTime, uint32_t from)
688 txTime, expectedGrantTime, m_txop[from]);
691 template <
typename TxopType>
694 uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from)
696 NS_ASSERT (ackDelay < m_ackTimeoutValue);
699 txTime, expectedGrantTime, m_txop[from]);
700 AddAckTimeoutReset (expectedGrantTime + txTime + ackDelay);
703 template <
typename TxopType>
708 if (m_ChannelAccessManager->NeedBackoffUponAccess (state))
710 state->GenerateBackoff ();
712 state->QueueTx (txTime, expectedGrantTime);
713 m_ChannelAccessManager->RequestAccess (state);
716 template <
typename TxopType>
721 &ChannelAccessManager::NotifyMaybeCcaBusyStartNow, m_ChannelAccessManager,
725 template <
typename TxopType>
730 &ChannelAccessManager::NotifySwitchingStartNow, m_ChannelAccessManager,
734 template <
typename TxopType>
739 &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
754 StartTest (1, 3, 10);
756 AddAccessRequest (1, 1, 5, 0);
757 AddAccessRequest (8, 2, 12, 0);
766 StartTest (1, 3, 10);
768 AddAccessRequest (1, 1, 5, 0);
769 AddRxInsideSifsEvt (7, 10);
771 AddAccessRequest (14, 2, 18, 0);
783 StartTest (4, 6, 10);
787 AddAccessRequest (30, 2, 118, 0);
788 ExpectBackoff (30, 4, 0);
797 StartTest (4, 6, 10);
800 AddAccessRequest (30, 2, 70, 0);
801 ExpectBackoff (30, 0, 0);
810 StartTest (4, 6, 10);
814 AddAccessRequest (30, 2, 110, 0);
815 ExpectBackoff (30, 0, 0);
823 StartTest (4, 6, 10);
826 AddAccessRequest (62, 2, 72, 0);
834 StartTest (4, 6, 10);
837 AddAccessRequest (70, 2, 80, 0);
846 StartTest (4, 6, 10);
848 AddRxErrorEvt (20, 40);
849 AddAccessRequest (30, 2, 102, 0);
850 ExpectBackoff (30, 4, 0);
860 StartTest (4, 6, 10);
862 AddRxErrorEvt (20, 40);
863 AddAccessRequest (70, 2, 86, 0);
872 StartTest (4, 6, 10);
874 AddRxErrorEvt (20, 40, 20);
875 ExpectBusy (41,
true);
876 ExpectBusy (59,
true);
877 ExpectBusy (61,
false);
886 StartTest (4, 6, 10);
888 AddRxErrorEvt (20, 40);
889 AddAccessRequest (30, 2, 101, 0);
890 ExpectBackoff (30, 4, 0);
901 StartTest (4, 6, 10);
905 AddAccessRequest (30, 10, 78, 0);
906 ExpectBackoff (30, 2, 0);
907 AddAccessRequest (40, 2, 110, 1);
908 ExpectBackoff (40, 0, 1);
909 ExpectInternalCollision (78, 1, 1);
919 StartTest (4, 6, 10);
922 AddAccessRequestWithAckTimeout (20, 20, 34, 1);
923 AddAccessRequest (64, 10, 80, 0);
935 StartTest (4, 6, 10);
938 AddAccessRequestWithSuccessfullAck (20, 20, 34, 2, 1);
939 AddAccessRequest (55, 10, 62, 0);
946 StartTest (4, 6, 10);
948 AddAccessRequest (20, 20, 34, 0);
950 AddAccessRequest (61, 10, 80, 0);
951 ExpectBackoff (61, 1, 0);
957 StartTest (4, 6, 10);
960 AddNavStart (60, 15);
963 AddAccessRequest (30, 10, 93, 0);
964 ExpectBackoff (30, 2, 0);
970 StartTest (4, 6, 10);
973 AddNavStart (60, 15);
976 AddAccessRequest (30, 10, 91, 0);
977 ExpectBackoff (30, 2, 0);
984 StartTest (4, 6, 10);
987 AddAccessRequest (80, 10, 94, 0);
991 StartTest (4, 6, 10);
995 AddAccessRequest (30, 50, 108, 0);
996 ExpectBackoff (30, 3, 0);
1005 StartTest (1, 3, 10);
1007 AddSwitchingEvt (0, 20);
1008 AddAccessRequest (21, 1, 25, 0);
1016 StartTest (1, 3, 10);
1018 AddSwitchingEvt (20,20);
1019 AddCcaBusyEvt (30,20);
1020 ExpectBackoff (45, 2, 0);
1021 AddAccessRequest (45, 1, 56, 0);
1028 StartTest (1, 3, 10);
1030 AddRxStartEvt (20, 40);
1031 AddSwitchingEvt (30, 20);
1032 AddAccessRequest (51, 1, 55, 0);
1039 StartTest (1, 3, 10);
1041 AddCcaBusyEvt (20, 40);
1042 AddSwitchingEvt (30, 20);
1043 AddAccessRequest (51, 1, 55, 0);
1050 StartTest (1, 3, 10);
1052 AddNavStart (20,40);
1053 AddSwitchingEvt (30,20);
1054 AddAccessRequest (51, 1, 55, 0);
1062 StartTest (1, 3, 10);
1064 AddAccessRequestWithAckTimeout (20, 20, 24, 0);
1065 AddAccessRequest (49, 1, 54, 0);
1066 AddSwitchingEvt (54, 5);
1067 AddAccessRequest (60, 1, 64, 0);
1075 StartTest (4, 6, 10);
1078 AddAccessRequest (30, 2, 80, 0);
1079 ExpectBackoff (30, 4, 0);
1080 AddSwitchingEvt (80,20);
1081 AddAccessRequest (101, 2, 111, 0);
1097 StartTest (4, 6, 10);
1099 AddRxOkEvt (20, 30);
1100 AddAccessRequest (52, 20, 60, 0);
1108 StartTest (4, 6, 10);
1110 AddRxOkEvt (20, 30);
1111 AddAccessRequest (58, 20, 60, 0);
1119 StartTest (4, 6, 10);
1121 AddRxOkEvt (20, 30);
1122 AddAccessRequest (62, 20, 64, 0);
1131 StartTest (4, 6, 10);
1133 AddRxErrorEvt (20, 30);
1134 AddAccessRequest (55, 20, 76, 0);
1143 StartTest (4, 6, 10);
1145 AddRxErrorEvt (20, 30);
1146 AddAccessRequest (70, 20, 76, 0);
1155 StartTest (4, 6, 10);
1157 AddRxErrorEvt (20, 30);
1158 AddAccessRequest (82, 20, 84, 0);
1167 StartTest (4, 6, 10);
1169 AddRxOkEvt (20, 30);
1170 AddAccessRequest (30, 20, 76, 0);
1171 ExpectBackoff (30, 4, 0);
1180 StartTest (4, 6, 10);
1182 AddRxOkEvt (20, 30);
1183 AddRxOkEvt (61, 10);
1184 AddRxOkEvt (87, 10);
1185 AddAccessRequest (30, 20, 107, 0);
1186 ExpectBackoff (30, 3, 0);
static TxopTestSuite g_dcfTestSuite
static QosTxopTestSuite g_edcaTestSuite
ChannelAccessManager Stub.
ChannelAccessManagerStub()
Time GetSifs(void) const override
Return the Short Interframe Space (SIFS) for this PHY.
void SetEifsNoDifs(Time eifsNoDifs)
Set the duration of EIFS - DIFS.
void SetSlot(Time slot)
Set the slot duration.
Time GetSlot(void) const override
Return the slot duration for this PHY.
Time m_sifs
SIFS duration.
void SetSifs(Time sifs)
Set the Short Interframe Space (SIFS).
Time GetEifsNoDifs(void) const override
Return the EIFS duration minus a DIFS.
Time m_eifsNoDifs
EIFS duration minus a DIFS.
Channel Access Manager Test.
void AddAckTimeoutReset(uint64_t at)
Add Ack timeout reset function.
void AddRxOkEvt(uint64_t at, uint64_t duration)
Add receive OK event function.
void AddRxStartEvt(uint64_t at, uint64_t duration)
Add receive start event function.
void DoRun(void) override
Implementation to actually run this TestCase.
uint32_t m_ackTimeoutValue
the Ack timeout value
void AddAccessRequestWithAckTimeout(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t from)
Add access request with Ack timeout.
ChannelAccessManagerTest()
void GenerateBackoff(uint32_t i)
Generate backoff function.
void NotifyAccessGranted(uint32_t i)
Notify access granted function.
std::vector< Ptr< TxopTest< TxopType > > > TxopTests
the TXOP tests typedef
void NotifyInternalCollision(Ptr< TxopTest< TxopType >> state)
Notify internal collision function.
void AddTxop(uint32_t aifsn)
Add Txop function.
void AddAccessRequest(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t from)
Add access function.
void AddSwitchingEvt(uint64_t at, uint64_t duration)
Add switching event function.
void DoAccessRequest(uint64_t txTime, uint64_t expectedGrantTime, Ptr< TxopTest< TxopType >> state)
Add access request with successful Ack.
Ptr< ChannelAccessManagerStub > m_ChannelAccessManager
the channel access manager
void AddRxErrorEvt(uint64_t at, uint64_t duration)
Add receive error event function for error at end of frame.
void EndTest(void)
End test function.
void AddAccessRequestWithSuccessfullAck(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from)
Add access request with successful ack.
TxopTests m_txop
the vector of Txop test instances
void ExpectInternalCollision(uint64_t time, uint32_t nSlots, uint32_t from)
Expect internal collision function.
void AddCcaBusyEvt(uint64_t at, uint64_t duration)
Add CCA busy event function.
void AddNavStart(uint64_t at, uint64_t duration)
Add NAV start function.
void AddRxInsideSifsEvt(uint64_t at, uint64_t duration)
Add receive inside SIFS event function.
Ptr< FrameExchangeManagerStub< TxopType > > m_feManager
the Frame Exchange Manager stubbed
void StartTest(uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue=20)
Start test function.
void DoCheckBusy(bool busy)
Perform check that channel access manager is busy or idle.
void AddNavReset(uint64_t at, uint64_t duration)
Add NAV reset function.
void AddTxEvt(uint64_t at, uint64_t duration)
Add transmit event function.
Frame Exchange Manager Stub.
void NotifySwitchingStartNow(Time duration) override
void NotifyInternalCollision(Ptr< Txop > txop) override
Notify that an internal collision has occurred for the given Txop.
ChannelAccessManagerTest< TxopType > * m_test
the test DCF/EDCA manager
FrameExchangeManagerStub(ChannelAccessManagerTest< TxopType > *test)
Constructor.
bool StartTransmission(Ptr< Txop > dcf) override
Request the FrameExchangeManager to start a frame exchange sequence.
ExpectedBackoffs m_expectedInternalCollision
expected backoff due to an internal collision
void NotifyWakeUp(void) override
When wake up operation occurs, channel access will be restarted.
bool HasFramesToTransmit(void) override
Check if the Txop has frames to transmit.
uint32_t m_i
the index of the Txop
void NotifySleep(void) override
When sleep operation occurs, if there is a pending packet transmission, it will be reinserted to the ...
void QueueTx(uint64_t txTime, uint64_t expectedGrantTime)
Queue transmit function.
ExpectedBackoffs m_expectedBackoff
expected backoff (not due to an internal collision)
void GenerateBackoff(void) override
Generate a new backoff now.
std::list< ExpectedGrant > ExpectedGrants
the collection of expected grants typedef
ChannelAccessManagerTest< TxopType > * m_test
Check if the Txop has frames to transmit.
ExpectedGrants m_expectedGrants
expected grants
std::pair< uint64_t, uint64_t > ExpectedGrant
the expected grant typedef
void DoDispose(void) override
Destructor implementation.
void NotifyChannelAccessed(Time txopDuration=Seconds(0)) override
Called by the FrameExchangeManager to notify that channel access has been granted for the given amoun...
TxopTest(ChannelAccessManagerTest< TxopType > *test, uint32_t i)
Constructor.
std::list< struct ExpectedBackoff > ExpectedBackoffs
expected backoffs typedef
Manage a set of ns3::Txop.
FrameExchangeManager is a base class handling the basic frame exchange sequences for non-QoS stations...
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Simulation virtual time values and global simulation resolution.
virtual void NotifyChannelAccessed(Time txopDuration=Seconds(0))
Called by the FrameExchangeManager to notify that channel access has been granted for the given amoun...
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time Seconds(double value)
Construct a Time in the indicated unit.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(Ptr< T2 > const &p)
Cast a Ptr.
ExpectedBackoff structure.
uint32_t nSlots
number of slots