22 #include "ns3/simulator.h" 23 #include "ns3/channel-access-manager.h" 24 #include "ns3/qos-txop.h" 25 #include "ns3/mac-low.h" 29 template <
typename TxopType>
38 template <
typename TxopType>
55 void QueueTx (uint64_t txTime, uint64_t expectedGrantTime);
62 void DoDispose (
void);
82 bool IsAccessRequested (
void)
const;
86 void NotifyAccessRequested (
void);
90 void NotifyAccessGranted (
void);
94 void NotifyInternalCollision (
void);
98 void GenerateBackoff (
void);
103 bool HasFramesToTransmit (
void);
107 void NotifyChannelSwitching (
void);
112 void NotifySleep (
void);
116 void NotifyWakeUp (
void);
153 template <
typename TxopType>
158 virtual void DoRun (
void);
164 void NotifyAccessGranted (uint32_t i);
169 void NotifyInternalCollision (uint32_t i);
174 void GenerateBackoff (uint32_t i);
179 void NotifyChannelSwitching (uint32_t i);
190 void StartTest (uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue = 20);
195 void AddTxop (uint32_t aifsn);
204 void ExpectInternalCollision (uint64_t time, uint32_t nSlots, uint32_t from);
211 void ExpectBackoff (uint64_t time, uint32_t nSlots, uint32_t from);
217 void ExpectBusy (uint64_t time,
bool busy);
222 void DoCheckBusy (
bool busy);
228 void AddRxOkEvt (uint64_t at, uint64_t duration);
234 void AddRxErrorEvt (uint64_t at, uint64_t duration);
241 void AddRxErrorEvt (uint64_t at, uint64_t duration, uint64_t timeUntilError);
247 void AddRxInsideSifsEvt (uint64_t at, uint64_t duration);
253 void AddTxEvt (uint64_t at, uint64_t duration);
259 void AddNavReset (uint64_t at, uint64_t duration);
265 void AddNavStart (uint64_t at, uint64_t duration);
270 void AddAckTimeoutReset (uint64_t at);
278 void AddAccessRequest (uint64_t at, uint64_t txTime,
279 uint64_t expectedGrantTime, uint32_t from);
287 void AddAccessRequestWithAckTimeout (uint64_t at, uint64_t txTime,
288 uint64_t expectedGrantTime, uint32_t from);
297 void AddAccessRequestWithSuccessfullAck (uint64_t at, uint64_t txTime,
298 uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from);
311 void AddCcaBusyEvt (uint64_t at, uint64_t duration);
317 void AddSwitchingEvt (uint64_t at, uint64_t duration);
323 void AddRxStartEvt (uint64_t at, uint64_t duration);
333 template <
typename TxopType>
337 m_expectedGrants.push_back (std::make_pair (txTime, expectedGrantTime));
340 template <
typename TxopType>
344 m_accessRequested (false)
348 template <
typename TxopType>
356 template <
typename TxopType>
360 return m_accessRequested;
363 template <
typename TxopType>
367 m_accessRequested =
true;
370 template <
typename TxopType>
374 m_accessRequested =
false;
375 m_test->NotifyAccessGranted (m_i);
378 template <
typename TxopType>
382 m_test->NotifyInternalCollision (m_i);
385 template <
typename TxopType>
389 m_test->GenerateBackoff (m_i);
392 template <
typename TxopType>
396 return !m_expectedGrants.empty ();
399 template <
typename TxopType>
403 m_test->NotifyChannelSwitching (m_i);
406 template <
typename TxopType>
412 template <
typename TxopType>
418 template <
typename TxopType>
424 template <
typename TxopType>
430 if (!state->m_expectedGrants.empty ())
432 std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front ();
433 state->m_expectedGrants.pop_front ();
435 m_ChannelAccessManager->NotifyTxStartNow (
MicroSeconds (expected.first));
436 m_ChannelAccessManager->NotifyAckTimeoutStartNow (
MicroSeconds (m_ackTimeoutValue + expected.first));
440 template <
typename TxopType>
445 &ChannelAccessManager::NotifyTxStartNow, m_ChannelAccessManager,
449 template <
typename TxopType>
454 NS_TEST_EXPECT_MSG_EQ (state->m_expectedInternalCollision.empty (),
false,
"Have expected internal collisions");
455 if (!state->m_expectedInternalCollision.empty ())
459 NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.at), "Expected internal collision time is now");
460 state->StartBackoffNow (expected.nSlots);
464 template <typename TxopType>
470 if (!state->m_expectedBackoff.empty ())
475 state->StartBackoffNow (expected.nSlots);
479 template <typename TxopType>
484 if (!state->m_expectedGrants.empty ())
486 std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front ();
487 state->m_expectedGrants.pop_front ();
490 state->m_accessRequested =
false;
493 template <
typename TxopType>
498 struct TxopTest<TxopType>::ExpectedBackoff col;
504 template <typename TxopType>
509 struct TxopTest<TxopType>::ExpectedBackoff backoff;
511 backoff.nSlots = nSlots;
515 template <typename TxopType>
523 template <
typename TxopType>
530 template <
typename TxopType>
534 m_ChannelAccessManager = CreateObject<ChannelAccessManager> ();
535 m_low = CreateObject<MacLowStub> ();
538 m_ChannelAccessManager->SetupLow (m_low);
539 m_ChannelAccessManager->SetSlot (
MicroSeconds (slotTime));
541 m_ChannelAccessManager->SetEifsNoDifs (
MicroSeconds (eifsNoDifsNoSifs + sifs));
542 m_ackTimeoutValue = ackTimeoutValue;
545 template <
typename TxopType>
550 txop->SetAifsn (aifsn);
551 m_txop.push_back (txop);
552 txop->SetChannelAccessManager (m_ChannelAccessManager);
553 txop->SetMacLow (m_low);
556 template <
typename TxopType>
561 Simulator::Destroy ();
563 for (
typename TxopTests::const_iterator i = m_txop.begin (); i != m_txop.end (); i++)
567 NS_TEST_EXPECT_MSG_EQ (state->m_expectedInternalCollision.empty (),
true,
"Have no internal collisions");
574 m_ChannelAccessManager = 0;
578 template <
typename TxopType>
583 &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
586 &ChannelAccessManager::NotifyRxEndOkNow, m_ChannelAccessManager);
589 template <
typename TxopType>
594 &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
598 template <
typename TxopType>
603 &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
606 &ChannelAccessManager::NotifyRxEndErrorNow, m_ChannelAccessManager);
609 template <
typename TxopType>
614 &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
617 &ChannelAccessManager::NotifyRxEndErrorNow, m_ChannelAccessManager);
621 template <
typename TxopType>
626 &ChannelAccessManager::NotifyNavResetNow, m_ChannelAccessManager,
630 template <
typename TxopType>
635 &ChannelAccessManager::NotifyNavStartNow, m_ChannelAccessManager,
639 template <
typename TxopType>
644 &ChannelAccessManager::NotifyAckTimeoutResetNow, m_ChannelAccessManager);
647 template <
typename TxopType>
650 uint64_t expectedGrantTime, uint32_t from)
652 AddAccessRequestWithSuccessfullAck (at, txTime, expectedGrantTime, 0, from);
655 template <
typename TxopType>
658 uint64_t expectedGrantTime, uint32_t from)
662 txTime, expectedGrantTime, m_txop[from]);
665 template <
typename TxopType>
668 uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from)
670 NS_ASSERT (ackDelay < m_ackTimeoutValue);
673 txTime, expectedGrantTime, m_txop[from]);
674 AddAckTimeoutReset (expectedGrantTime + txTime + ackDelay);
677 template <
typename TxopType>
682 if (m_ChannelAccessManager->NeedBackoffUponAccess (state))
684 state->GenerateBackoff ();
686 state->QueueTx (txTime, expectedGrantTime);
687 m_ChannelAccessManager->RequestAccess (state);
690 template <
typename TxopType>
695 &ChannelAccessManager::NotifyMaybeCcaBusyStartNow, m_ChannelAccessManager,
699 template <
typename TxopType>
704 &ChannelAccessManager::NotifySwitchingStartNow, m_ChannelAccessManager,
708 template <
typename TxopType>
713 &ChannelAccessManager::NotifyRxStartNow, m_ChannelAccessManager,
728 StartTest (1, 3, 10);
730 AddAccessRequest (1, 1, 5, 0);
731 AddAccessRequest (8, 2, 12, 0);
740 StartTest (1, 3, 10);
742 AddAccessRequest (1, 1, 5, 0);
743 AddRxInsideSifsEvt (7, 10);
745 AddAccessRequest (14, 2, 18, 0);
757 StartTest (4, 6, 10);
761 AddAccessRequest (30, 2, 118, 0);
762 ExpectBackoff (30, 4, 0);
771 StartTest (4, 6, 10);
774 AddAccessRequest (30, 2, 70, 0);
775 ExpectBackoff (30, 0, 0);
784 StartTest (4, 6, 10);
788 AddAccessRequest (30, 2, 110, 0);
789 ExpectBackoff (30, 0, 0);
797 StartTest (4, 6, 10);
800 AddAccessRequest (62, 2, 72, 0);
808 StartTest (4, 6, 10);
811 AddAccessRequest (70, 2, 80, 0);
820 StartTest (4, 6, 10);
822 AddRxErrorEvt (20, 40);
823 AddAccessRequest (30, 2, 102, 0);
824 ExpectBackoff (30, 4, 0);
834 StartTest (4, 6, 10);
836 AddRxErrorEvt (20, 40);
837 AddAccessRequest (70, 2, 86, 0);
846 StartTest (4, 6, 10);
848 AddRxErrorEvt (20, 40, 20);
849 ExpectBusy (41,
true);
850 ExpectBusy (59,
true);
851 ExpectBusy (61,
false);
860 StartTest (4, 6, 10);
862 AddRxErrorEvt (20, 40);
863 AddAccessRequest (30, 2, 101, 0);
864 ExpectBackoff (30, 4, 0);
875 StartTest (4, 6, 10);
879 AddAccessRequest (30, 10, 78, 0);
880 ExpectBackoff (30, 2, 0);
881 AddAccessRequest (40, 2, 110, 1);
882 ExpectBackoff (40, 0, 1);
883 ExpectInternalCollision (78, 1, 1);
893 StartTest (4, 6, 10);
896 AddAccessRequestWithAckTimeout (20, 20, 34, 1);
897 AddAccessRequest (64, 10, 80, 0);
909 StartTest (4, 6, 10);
912 AddAccessRequestWithSuccessfullAck (20, 20, 34, 2, 1);
913 AddAccessRequest (55, 10, 62, 0);
920 StartTest (4, 6, 10);
922 AddAccessRequest (20, 20, 34, 0);
924 AddAccessRequest (61, 10, 80, 0);
925 ExpectBackoff (61, 1, 0);
931 StartTest (4, 6, 10);
934 AddNavStart (60, 15);
937 AddAccessRequest (30, 10, 93, 0);
938 ExpectBackoff (30, 2, 0);
944 StartTest (4, 6, 10);
947 AddNavStart (60, 15);
950 AddAccessRequest (30, 10, 91, 0);
951 ExpectBackoff (30, 2, 0);
958 StartTest (4, 6, 10);
961 AddAccessRequest (80, 10, 94, 0);
965 StartTest (4, 6, 10);
969 AddAccessRequest (30, 50, 108, 0);
970 ExpectBackoff (30, 3, 0);
979 StartTest (1, 3, 10);
981 AddSwitchingEvt (0, 20);
982 AddAccessRequest (21, 1, 25, 0);
990 StartTest (1, 3, 10);
992 AddSwitchingEvt (20,20);
993 AddCcaBusyEvt (30,20);
994 ExpectBackoff (45, 2, 0);
995 AddAccessRequest (45, 1, 56, 0);
1002 StartTest (1, 3, 10);
1004 AddRxStartEvt (20, 40);
1005 AddSwitchingEvt (30, 20);
1006 AddAccessRequest (51, 1, 55, 0);
1013 StartTest (1, 3, 10);
1015 AddCcaBusyEvt (20, 40);
1016 AddSwitchingEvt (30, 20);
1017 AddAccessRequest (51, 1, 55, 0);
1024 StartTest (1, 3, 10);
1026 AddNavStart (20,40);
1027 AddSwitchingEvt (30,20);
1028 AddAccessRequest (51, 1, 55, 0);
1036 StartTest (1, 3, 10);
1038 AddAccessRequestWithAckTimeout (20, 20, 24, 0);
1039 AddAccessRequest (49, 1, 54, 0);
1040 AddSwitchingEvt (54, 5);
1041 AddAccessRequest (60, 1, 64, 0);
1049 StartTest (4, 6, 10);
1052 AddAccessRequest (30, 2, 80, 0);
1053 ExpectBackoff (30, 4, 0);
1054 AddSwitchingEvt (80,20);
1055 AddAccessRequest (101, 2, 111, 0);
1071 StartTest (4, 6, 10);
1073 AddRxOkEvt (20, 30);
1074 AddAccessRequest (52, 20, 60, 0);
1082 StartTest (4, 6, 10);
1084 AddRxOkEvt (20, 30);
1085 AddAccessRequest (52, 20, 60, 0);
1093 StartTest (4, 6, 10);
1095 AddRxOkEvt (20, 30);
1096 AddAccessRequest (62, 20, 64, 0);
1105 StartTest (4, 6, 10);
1107 AddRxErrorEvt (20, 30);
1108 AddAccessRequest (55, 20, 76, 0);
1117 StartTest (4, 6, 10);
1119 AddRxErrorEvt (20, 30);
1120 AddAccessRequest (70, 20, 76, 0);
1129 StartTest (4, 6, 10);
1131 AddRxErrorEvt (20, 30);
1132 AddAccessRequest (82, 20, 84, 0);
1141 StartTest (4, 6, 10);
1143 AddRxOkEvt (20, 30);
1144 AddAccessRequest (30, 20, 76, 0);
1145 ExpectBackoff (30, 4, 0);
1154 StartTest (4, 6, 10);
1156 AddRxOkEvt (20, 30);
1157 AddRxOkEvt (61, 10);
1158 AddRxOkEvt (87, 10);
1159 AddAccessRequest (30, 20, 107, 0);
1160 ExpectBackoff (30, 3, 0);
Ptr< ChannelAccessManager > m_ChannelAccessManager
the channel access manager
Smart pointer class similar to boost::intrusive_ptr.
ExpectedBackoffs m_expectedBackoff
expected backoff (not due to an internal collision)
TxopTest(ChannelAccessManagerTest< TxopType > *test, uint32_t i)
Constructor.
void AddSwitchingEvt(uint64_t at, uint64_t duration)
Add switching event function.
void AddRxOkEvt(uint64_t at, uint64_t duration)
Add receive OK event function.
std::list< struct ExpectedBackoff > ExpectedBackoffs
expected backoffs typedef
void AddNavStart(uint64_t at, uint64_t duration)
Add NAV start function.
std::list< ExpectedGrant > ExpectedGrants
the collection of expected grants typedef
bool IsCfPeriod(void) const
This function indicates whether Simulator::Now is in the CF period.
void AddAccessRequestWithSuccessfullAck(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from)
Add access request with successful ack.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
void QueueTx(uint64_t txTime, uint64_t expectedGrantTime)
Queue transmit function.
void DoAccessRequest(uint64_t txTime, uint64_t expectedGrantTime, Ptr< TxopTest< TxopType >> state)
Add access request with successful Ack.
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
void DoDispose(void)
Inherited.
static TxopTestSuite g_dcfTestSuite
TxopTests m_txop
the vector of Txop test instances
ExpectedGrants m_expectedGrants
expected grants
void AddTxop(uint32_t aifsn)
Add Txop function.
ExpectedBackoff structure.
bool IsAccessRequested(void) const
void NotifyAccessRequested(void)
Notify that access request has been received.
void NotifyChannelSwitching(void)
When a channel switching occurs, enqueued packets are removed.
bool m_accessRequested
true if access requested
void AddCcaBusyEvt(uint64_t at, uint64_t duration)
Add CCA busy event function.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
static QosTxopTestSuite g_edcaTestSuite
std::vector< Ptr< TxopTest< TxopType > > > TxopTests
the TXOP tests typedef
uint32_t nSlots
number of slots
Channel Access Manager Test.
void AddRxStartEvt(uint64_t at, uint64_t duration)
Add receive start event function.
uint32_t m_ackTimeoutValue
the Ack timeout value
virtual void DoRun(void)
Implementation to actually run this TestCase.
void AddAckTimeoutReset(uint64_t at)
Add Ack timeout reset function.
void NotifyAccessGranted(uint32_t i)
Notify access granted function.
void AddTxEvt(uint64_t at, uint64_t duration)
Add transmit event function.
void EndTest(void)
End test function.
std::pair< uint64_t, uint64_t > ExpectedGrant
the expected grant typedef
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void NotifyInternalCollision(void)
Notify the Txop that internal collision has occurred.
void NotifyAccessGranted(void)
Notify the Txop that access has been granted.
handle RTS/CTS/Data/Ack transactions.
void AddRxInsideSifsEvt(uint64_t at, uint64_t duration)
Add receive inside SIFS event function.
void NotifyWakeUp(void)
When wake up operation occurs, channel access will be restarted.
void AddRxErrorEvt(uint64_t at, uint64_t duration)
Add receive error event function for error at end of frame.
uint32_t m_i
the index of the Txop
void ExpectInternalCollision(uint64_t time, uint32_t nSlots, uint32_t from)
Expect internal collision function.
Ptr< MacLowStub > m_low
the MAC low stubbed
void NotifySleep(void)
When sleep operation occurs, if there is a pending packet transmission, it will be reinserted to the ...
void DoCheckBusy(bool busy)
Perform check that channel access manager is busy or idle.
ChannelAccessManagerTest()
void NotifyInternalCollision(uint32_t i)
Notify internal collision function.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
void GenerateBackoff(void)
Generate a new backoff now.
void AddAccessRequestWithAckTimeout(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t from)
Add access request with Ack timeout.
ExpectedBackoffs m_expectedInternalCollision
expected backoff due to an internal collision
void AddAccessRequest(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t from)
Add access function.
void StartTest(uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue=20)
Start test function.
ChannelAccessManagerTest< TxopType > * m_test
the test DCF/EDCA manager
void AddNavReset(uint64_t at, uint64_t duration)
Add NAV reset function.
bool HasFramesToTransmit(void)
Check if the Txop has frames to transmit.