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;
68 bool HasFramesToTransmit (
void)
override;
72 void NotifySleep (
void)
override;
74 void NotifyWakeUp (
void)
override;
138 m_eifsNoDifs = eifsNoDifs;
194 template <
typename TxopType>
205 void NotifyAccessGranted (uint32_t i);
210 void NotifyInternalCollision (uint32_t i);
215 void GenerateBackoff (uint32_t i);
220 void NotifyChannelSwitching (uint32_t i);
231 void StartTest (uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue = 20);
236 void AddTxop (uint32_t aifsn);
245 void ExpectInternalCollision (uint64_t time, uint32_t nSlots, uint32_t from);
252 void ExpectBackoff (uint64_t time, uint32_t nSlots, uint32_t from);
258 void ExpectBusy (uint64_t time,
bool busy);
263 void DoCheckBusy (
bool busy);
269 void AddRxOkEvt (uint64_t at, uint64_t duration);
275 void AddRxErrorEvt (uint64_t at, uint64_t duration);
282 void AddRxErrorEvt (uint64_t at, uint64_t duration, uint64_t timeUntilError);
288 void AddRxInsideSifsEvt (uint64_t at, uint64_t duration);
294 void AddTxEvt (uint64_t at, uint64_t duration);
300 void AddNavReset (uint64_t at, uint64_t duration);
306 void AddNavStart (uint64_t at, uint64_t duration);
311 void AddAckTimeoutReset (uint64_t at);
319 void AddAccessRequest (uint64_t at, uint64_t txTime,
320 uint64_t expectedGrantTime, uint32_t from);
328 void AddAccessRequestWithAckTimeout (uint64_t at, uint64_t txTime,
329 uint64_t expectedGrantTime, uint32_t from);
338 void AddAccessRequestWithSuccessfullAck (uint64_t at, uint64_t txTime,
339 uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from);
352 void AddCcaBusyEvt (uint64_t at, uint64_t duration);
358 void AddSwitchingEvt (uint64_t at, uint64_t duration);
364 void AddRxStartEvt (uint64_t at, uint64_t duration);
374 template <
typename TxopType>
378 m_expectedGrants.push_back (std::make_pair (txTime, expectedGrantTime));
381 template <
typename TxopType>
388 template <
typename TxopType>
393 TxopType::DoDispose ();
396 template <
typename TxopType>
400 Txop::m_access = Txop::NOT_REQUESTED;
401 m_test->NotifyAccessGranted (m_i);
404 template <
typename TxopType>
408 m_test->NotifyInternalCollision (m_i);
411 template <
typename TxopType>
415 m_test->GenerateBackoff (m_i);
418 template <
typename TxopType>
422 return !m_expectedGrants.empty ();
425 template <
typename TxopType>
429 m_test->NotifyChannelSwitching (m_i);
432 template <
typename TxopType>
438 template <
typename TxopType>
444 template <
typename TxopType>
450 template <
typename TxopType>
456 if (!state->m_expectedGrants.empty ())
458 std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front ();
459 state->m_expectedGrants.pop_front ();
461 m_ChannelAccessManager->NotifyTxStartNow (
MicroSeconds (expected.first));
462 m_ChannelAccessManager->NotifyAckTimeoutStartNow (
MicroSeconds (m_ackTimeoutValue + expected.first));
466 template <
typename TxopType>
471 &ChannelAccessManager::NotifyTxStartNow, m_ChannelAccessManager,
475 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>
510 if (!state->m_expectedGrants.empty ())
512 std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front ();
513 state->m_expectedGrants.pop_front ();
516 state->Txop::m_access = Txop::NOT_REQUESTED;
519 template <
typename TxopType>
524 struct TxopTest<TxopType>::ExpectedBackoff col;
530 template <typename TxopType>
535 struct TxopTest<TxopType>::ExpectedBackoff backoff;
537 backoff.nSlots = nSlots;
541 template <typename TxopType>
549 template <
typename TxopType>
556 template <
typename TxopType>
560 m_ChannelAccessManager = CreateObject<ChannelAccessManagerStub> ();
561 m_feManager = CreateObject<FrameExchangeManagerStub> ();
562 m_ChannelAccessManager->SetupFrameExchangeManager (m_feManager);
563 m_ChannelAccessManager->SetSlot (
MicroSeconds (slotTime));
565 m_ChannelAccessManager->SetEifsNoDifs (
MicroSeconds (eifsNoDifsNoSifs + sifs));
566 m_ackTimeoutValue = ackTimeoutValue;
569 template <
typename TxopType>
574 txop->SetAifsn (aifsn);
575 m_txop.push_back (txop);
576 txop->SetChannelAccessManager (m_ChannelAccessManager);
579 template <
typename TxopType>
585 for (
typename TxopTests::const_iterator i = m_txop.begin (); i != m_txop.end (); i++)
589 NS_TEST_EXPECT_MSG_EQ (state->m_expectedInternalCollision.empty (),
true,
"Have no internal collisions");
596 m_ChannelAccessManager->Dispose ();
597 m_ChannelAccessManager = 0;
599 Simulator::Destroy ();
602 template <
typename TxopType>
607 &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
610 &ChannelAccessManager::NotifyRxEndOkNow, m_ChannelAccessManager);
613 template <
typename TxopType>
618 &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
622 template <
typename TxopType>
627 &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
630 &ChannelAccessManager::NotifyRxEndErrorNow, m_ChannelAccessManager);
633 template <
typename TxopType>
638 &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
641 &ChannelAccessManager::NotifyRxEndErrorNow, m_ChannelAccessManager);
645 template <
typename TxopType>
650 &ChannelAccessManager::NotifyNavResetNow, m_ChannelAccessManager,
654 template <
typename TxopType>
659 &ChannelAccessManager::NotifyNavStartNow, m_ChannelAccessManager,
663 template <
typename TxopType>
668 &ChannelAccessManager::NotifyAckTimeoutResetNow, m_ChannelAccessManager);
671 template <
typename TxopType>
674 uint64_t expectedGrantTime, uint32_t from)
676 AddAccessRequestWithSuccessfullAck (at, txTime, expectedGrantTime, 0, from);
679 template <
typename TxopType>
682 uint64_t expectedGrantTime, uint32_t from)
686 txTime, expectedGrantTime, m_txop[from]);
689 template <
typename TxopType>
692 uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from)
694 NS_ASSERT (ackDelay < m_ackTimeoutValue);
697 txTime, expectedGrantTime, m_txop[from]);
698 AddAckTimeoutReset (expectedGrantTime + txTime + ackDelay);
701 template <
typename TxopType>
706 if (m_ChannelAccessManager->NeedBackoffUponAccess (state))
708 state->GenerateBackoff ();
710 state->QueueTx (txTime, expectedGrantTime);
711 m_ChannelAccessManager->RequestAccess (state);
714 template <
typename TxopType>
719 &ChannelAccessManager::NotifyMaybeCcaBusyStartNow, m_ChannelAccessManager,
723 template <
typename TxopType>
728 &ChannelAccessManager::NotifySwitchingStartNow, m_ChannelAccessManager,
732 template <
typename TxopType>
737 &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
752 StartTest (1, 3, 10);
754 AddAccessRequest (1, 1, 5, 0);
755 AddAccessRequest (8, 2, 12, 0);
764 StartTest (1, 3, 10);
766 AddAccessRequest (1, 1, 5, 0);
767 AddRxInsideSifsEvt (7, 10);
769 AddAccessRequest (14, 2, 18, 0);
781 StartTest (4, 6, 10);
785 AddAccessRequest (30, 2, 118, 0);
786 ExpectBackoff (30, 4, 0);
795 StartTest (4, 6, 10);
798 AddAccessRequest (30, 2, 70, 0);
799 ExpectBackoff (30, 0, 0);
808 StartTest (4, 6, 10);
812 AddAccessRequest (30, 2, 110, 0);
813 ExpectBackoff (30, 0, 0);
821 StartTest (4, 6, 10);
824 AddAccessRequest (62, 2, 72, 0);
832 StartTest (4, 6, 10);
835 AddAccessRequest (70, 2, 80, 0);
844 StartTest (4, 6, 10);
846 AddRxErrorEvt (20, 40);
847 AddAccessRequest (30, 2, 102, 0);
848 ExpectBackoff (30, 4, 0);
858 StartTest (4, 6, 10);
860 AddRxErrorEvt (20, 40);
861 AddAccessRequest (70, 2, 86, 0);
870 StartTest (4, 6, 10);
872 AddRxErrorEvt (20, 40, 20);
873 ExpectBusy (41,
true);
874 ExpectBusy (59,
true);
875 ExpectBusy (61,
false);
884 StartTest (4, 6, 10);
886 AddRxErrorEvt (20, 40);
887 AddAccessRequest (30, 2, 101, 0);
888 ExpectBackoff (30, 4, 0);
899 StartTest (4, 6, 10);
903 AddAccessRequest (30, 10, 78, 0);
904 ExpectBackoff (30, 2, 0);
905 AddAccessRequest (40, 2, 110, 1);
906 ExpectBackoff (40, 0, 1);
907 ExpectInternalCollision (78, 1, 1);
917 StartTest (4, 6, 10);
920 AddAccessRequestWithAckTimeout (20, 20, 34, 1);
921 AddAccessRequest (64, 10, 80, 0);
933 StartTest (4, 6, 10);
936 AddAccessRequestWithSuccessfullAck (20, 20, 34, 2, 1);
937 AddAccessRequest (55, 10, 62, 0);
944 StartTest (4, 6, 10);
946 AddAccessRequest (20, 20, 34, 0);
948 AddAccessRequest (61, 10, 80, 0);
949 ExpectBackoff (61, 1, 0);
955 StartTest (4, 6, 10);
958 AddNavStart (60, 15);
961 AddAccessRequest (30, 10, 93, 0);
962 ExpectBackoff (30, 2, 0);
968 StartTest (4, 6, 10);
971 AddNavStart (60, 15);
974 AddAccessRequest (30, 10, 91, 0);
975 ExpectBackoff (30, 2, 0);
982 StartTest (4, 6, 10);
985 AddAccessRequest (80, 10, 94, 0);
989 StartTest (4, 6, 10);
993 AddAccessRequest (30, 50, 108, 0);
994 ExpectBackoff (30, 3, 0);
1003 StartTest (1, 3, 10);
1005 AddSwitchingEvt (0, 20);
1006 AddAccessRequest (21, 1, 25, 0);
1014 StartTest (1, 3, 10);
1016 AddSwitchingEvt (20,20);
1017 AddCcaBusyEvt (30,20);
1018 ExpectBackoff (45, 2, 0);
1019 AddAccessRequest (45, 1, 56, 0);
1026 StartTest (1, 3, 10);
1028 AddRxStartEvt (20, 40);
1029 AddSwitchingEvt (30, 20);
1030 AddAccessRequest (51, 1, 55, 0);
1037 StartTest (1, 3, 10);
1039 AddCcaBusyEvt (20, 40);
1040 AddSwitchingEvt (30, 20);
1041 AddAccessRequest (51, 1, 55, 0);
1048 StartTest (1, 3, 10);
1050 AddNavStart (20,40);
1051 AddSwitchingEvt (30,20);
1052 AddAccessRequest (51, 1, 55, 0);
1060 StartTest (1, 3, 10);
1062 AddAccessRequestWithAckTimeout (20, 20, 24, 0);
1063 AddAccessRequest (49, 1, 54, 0);
1064 AddSwitchingEvt (54, 5);
1065 AddAccessRequest (60, 1, 64, 0);
1073 StartTest (4, 6, 10);
1076 AddAccessRequest (30, 2, 80, 0);
1077 ExpectBackoff (30, 4, 0);
1078 AddSwitchingEvt (80,20);
1079 AddAccessRequest (101, 2, 111, 0);
1095 StartTest (4, 6, 10);
1097 AddRxOkEvt (20, 30);
1098 AddAccessRequest (52, 20, 60, 0);
1106 StartTest (4, 6, 10);
1108 AddRxOkEvt (20, 30);
1109 AddAccessRequest (58, 20, 60, 0);
1117 StartTest (4, 6, 10);
1119 AddRxOkEvt (20, 30);
1120 AddAccessRequest (62, 20, 64, 0);
1129 StartTest (4, 6, 10);
1131 AddRxErrorEvt (20, 30);
1132 AddAccessRequest (55, 20, 76, 0);
1141 StartTest (4, 6, 10);
1143 AddRxErrorEvt (20, 30);
1144 AddAccessRequest (70, 20, 76, 0);
1153 StartTest (4, 6, 10);
1155 AddRxErrorEvt (20, 30);
1156 AddAccessRequest (82, 20, 84, 0);
1165 StartTest (4, 6, 10);
1167 AddRxOkEvt (20, 30);
1168 AddAccessRequest (30, 20, 76, 0);
1169 ExpectBackoff (30, 4, 0);
1178 StartTest (4, 6, 10);
1180 AddRxOkEvt (20, 30);
1181 AddRxOkEvt (61, 10);
1182 AddRxOkEvt (87, 10);
1183 AddAccessRequest (30, 20, 107, 0);
1184 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.
Ptr< FrameExchangeManagerStub > m_feManager
the Frame Exchange Manager stubbed
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 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.
void NotifyChannelSwitching(uint32_t i)
Notify channel switching function.
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 NotifyInternalCollision(uint32_t i)
Notify 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.
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.
bool StartTransmission(Ptr< Txop > dcf) override
Request the FrameExchangeManager to start a frame exchange sequence.
FrameExchangeManagerStub()
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 NotifyChannelSwitching(void) override
When a channel switching occurs, enqueued packets are removed.
void NotifyInternalCollision(void) override
Notify the Txop that internal collision has occurred.
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.
ExpectedBackoff structure.
uint32_t nSlots
number of slots