20#include "ns3/adhoc-wifi-mac.h"
21#include "ns3/channel-access-manager.h"
22#include "ns3/frame-exchange-manager.h"
23#include "ns3/interference-helper.h"
24#include "ns3/multi-model-spectrum-channel.h"
25#include "ns3/qos-txop.h"
26#include "ns3/simulator.h"
27#include "ns3/spectrum-wifi-phy.h"
35template <
typename TxopType>
44template <
typename TxopType>
61 void QueueTx(uint64_t txTime, uint64_t expectedGrantTime);
175template <
typename TxopType>
199 dcf->NotifyChannelAccessed(0);
212 m_test->NotifyChannelSwitching();
225template <
typename TxopType>
263 uint64_t eifsNoDifsNoSifs,
265 uint16_t chWidth = 20);
303 void AddRxOkEvt(uint64_t at, uint64_t duration);
316 void AddRxErrorEvt(uint64_t at, uint64_t duration, uint64_t timeUntilError);
328 void AddTxEvt(uint64_t at, uint64_t duration);
363 uint64_t expectedGrantTime,
375 uint64_t expectedGrantTime,
385 uint64_t expectedGrantTime,
397 const std::vector<Time>& per20MhzDurations = {});
420template <
typename TxopType>
424 m_expectedGrants.emplace_back(txTime, expectedGrantTime);
427template <
typename TxopType>
434template <
typename TxopType>
439 TxopType::DoDispose();
442template <
typename TxopType>
447 m_test->NotifyAccessGranted(m_i);
450template <
typename TxopType>
454 m_test->GenerateBackoff(m_i);
457template <
typename TxopType>
461 return !m_expectedGrants.empty();
464template <
typename TxopType>
470template <
typename TxopType>
476template <
typename TxopType>
482template <
typename TxopType>
488 if (!state->m_expectedGrants.empty())
490 std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front();
491 state->m_expectedGrants.pop_front();
494 "Expected access grant is now");
495 m_ChannelAccessManager->NotifyTxStartNow(
MicroSeconds(expected.first));
496 m_ChannelAccessManager->NotifyAckTimeoutStartNow(
501template <
typename TxopType>
507 m_ChannelAccessManager,
511template <
typename TxopType>
517 "Have expected internal collisions");
518 if (!state->m_expectedInternalCollision.empty())
524 MicroSeconds(expected.at),
525 "Expected internal collision time is now");
526 state->StartBackoffNow(expected.nSlots, 0);
530template <typename TxopType>
536 if (!state->m_expectedBackoff.empty())
541 MicroSeconds(expected.at),
542 "Expected backoff is now");
543 state->StartBackoffNow(expected.nSlots, 0);
547template <typename TxopType>
551 for (
auto& state : m_txop)
553 if (!state->m_expectedGrants.empty())
555 std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front();
556 state->m_expectedGrants.pop_front();
559 "Expected grant is now");
565template <
typename TxopType>
578template <typename TxopType>
585 backoff.nSlots = nSlots;
589template <typename TxopType>
599template <
typename TxopType>
606template <
typename TxopType>
610 uint64_t eifsNoDifsNoSifs,
614 m_ChannelAccessManager = CreateObject<ChannelAccessManagerStub>();
615 m_feManager = CreateObject<FrameExchangeManagerStub<TxopType>>(
this);
616 m_ChannelAccessManager->SetupFrameExchangeManager(m_feManager);
617 m_ChannelAccessManager->SetSlot(
MicroSeconds(slotTime));
619 m_ChannelAccessManager->SetEifsNoDifs(
MicroSeconds(eifsNoDifsNoSifs + sifs));
620 m_ackTimeoutValue = ackTimeoutValue;
625 m_phy = CreateObject<SpectrumWifiPhy>();
626 m_phy->SetInterferenceHelper(CreateObject<InterferenceHelper>());
627 m_phy->AddChannel(CreateObject<MultiModelSpectrumChannel>());
630 m_ChannelAccessManager->SetupPhyListener(m_phy);
633template <
typename TxopType>
638 m_txop.push_back(txop);
639 m_ChannelAccessManager->Add(txop);
641 auto mac = CreateObject<AdhocWifiMac>();
642 mac->SetWifiPhys({
nullptr});
643 txop->SetWifiMac(mac);
644 txop->SetAifsn(aifsn);
647template <
typename TxopType>
653 for (
typename TxopTests::const_iterator i = m_txop.begin(); i != m_txop.end(); i++)
659 "Have no internal collisions");
666 m_ChannelAccessManager->RemovePhyListener(m_phy);
668 m_ChannelAccessManager->Dispose();
669 m_ChannelAccessManager =
nullptr;
670 m_feManager =
nullptr;
674template <
typename TxopType>
680 m_ChannelAccessManager,
684 m_ChannelAccessManager);
687template <
typename TxopType>
693 m_ChannelAccessManager,
697template <
typename TxopType>
703 m_ChannelAccessManager,
707 m_ChannelAccessManager);
710template <
typename TxopType>
714 uint64_t timeUntilError)
718 m_ChannelAccessManager,
722 m_ChannelAccessManager);
725 m_ChannelAccessManager,
728 std::vector<Time>{});
731template <
typename TxopType>
737 m_ChannelAccessManager,
741template <
typename TxopType>
747 m_ChannelAccessManager,
751template <
typename TxopType>
757 m_ChannelAccessManager);
760template <
typename TxopType>
764 uint64_t expectedGrantTime,
767 AddAccessRequestWithSuccessfulAck(at, txTime, expectedGrantTime, 0, from);
770template <
typename TxopType>
774 uint64_t expectedGrantTime,
785template <
typename TxopType>
789 uint64_t expectedGrantTime,
800 AddAckTimeoutReset(expectedGrantTime + txTime + ackDelay);
803template <
typename TxopType>
806 uint64_t expectedGrantTime,
809 if (m_ChannelAccessManager->NeedBackoffUponAccess(state))
811 state->GenerateBackoff(0);
813 state->QueueTx(txTime, expectedGrantTime);
814 m_ChannelAccessManager->RequestAccess(state);
817template <
typename TxopType>
822 const std::vector<Time>& per20MhzDurations)
826 m_ChannelAccessManager,
832template <
typename TxopType>
838 m_ChannelAccessManager,
842template <
typename TxopType>
848 m_ChannelAccessManager,
865 AddAccessRequest(1, 1, 5, 0);
866 AddAccessRequest(8, 2, 12, 0);
877 AddAccessRequest(1, 1, 5, 0);
878 AddRxInsideSifsEvt(7, 10);
880 AddAccessRequest(14, 2, 18, 0);
898 AddAccessRequest(30, 2, 118, 0);
899 ExpectBackoff(30, 4, 0);
911 AddAccessRequest(30, 2, 70, 0);
912 ExpectBackoff(30, 0, 0);
925 AddAccessRequest(30, 2, 110, 0);
926 ExpectBackoff(30, 0, 0);
937 AddAccessRequest(62, 2, 72, 0);
948 AddAccessRequest(70, 2, 80, 0);
959 AddRxErrorEvt(20, 40);
960 AddAccessRequest(30, 2, 102, 0);
961 ExpectBackoff(30, 4, 0);
973 AddRxErrorEvt(20, 40);
974 AddAccessRequest(70, 2, 86, 0);
985 AddRxErrorEvt(20, 40, 20);
986 ExpectBusy(41,
true);
987 ExpectBusy(59,
true);
988 ExpectBusy(61,
false);
999 AddRxErrorEvt(20, 40);
1000 AddAccessRequest(30, 2, 101, 0);
1001 ExpectBackoff(30, 4, 0);
1014 StartTest(4, 6, 10);
1018 AddAccessRequest(30, 10, 78, 0);
1019 ExpectBackoff(30, 2, 0);
1020 AddAccessRequest(40, 2, 110, 1);
1021 ExpectBackoff(40, 0, 1);
1022 ExpectInternalCollision(78, 1, 1);
1032 StartTest(4, 6, 10);
1035 AddAccessRequestWithAckTimeout(20, 20, 34, 1);
1036 AddAccessRequest(64, 10, 80, 0);
1048 StartTest(4, 6, 10);
1051 AddAccessRequestWithSuccessfulAck(20, 20, 34, 2, 1);
1052 AddAccessRequest(55, 10, 62, 0);
1059 StartTest(4, 6, 10);
1061 AddAccessRequest(20, 20, 34, 0);
1063 AddAccessRequest(61, 10, 80, 0);
1064 ExpectBackoff(61, 1, 0);
1070 StartTest(4, 6, 10);
1073 AddNavStart(60, 15);
1076 AddAccessRequest(30, 10, 93, 0);
1077 ExpectBackoff(30, 2, 0);
1083 StartTest(4, 6, 10);
1086 AddNavStart(60, 15);
1089 AddAccessRequest(30, 10, 91, 0);
1090 ExpectBackoff(30, 2, 0);
1096 StartTest(4, 6, 10);
1099 AddAccessRequest(80, 10, 94, 0);
1102 StartTest(4, 6, 10);
1106 AddAccessRequest(30, 50, 108, 0);
1107 ExpectBackoff(30, 3, 0);
1115 StartTest(1, 3, 10);
1117 AddSwitchingEvt(0, 20);
1118 AddAccessRequest(21, 1, 25, 0);
1126 StartTest(1, 3, 10);
1128 AddSwitchingEvt(20, 20);
1129 AddCcaBusyEvt(30, 20);
1130 ExpectBackoff(45, 2, 0);
1131 AddAccessRequest(45, 1, 56, 0);
1138 StartTest(1, 3, 10);
1140 AddRxStartEvt(20, 40);
1141 AddSwitchingEvt(30, 20);
1142 AddAccessRequest(51, 1, 55, 0);
1149 StartTest(1, 3, 10);
1151 AddCcaBusyEvt(20, 40);
1152 AddSwitchingEvt(30, 20);
1153 AddAccessRequest(51, 1, 55, 0);
1160 StartTest(1, 3, 10);
1162 AddNavStart(20, 40);
1163 AddSwitchingEvt(30, 20);
1164 AddAccessRequest(51, 1, 55, 0);
1172 StartTest(1, 3, 10);
1174 AddAccessRequestWithAckTimeout(20, 20, 24, 0);
1175 AddAccessRequest(49, 1, 54, 0);
1176 AddSwitchingEvt(54, 5);
1177 AddAccessRequest(60, 1, 64, 0);
1185 StartTest(4, 6, 10);
1188 AddAccessRequest(30, 2, 80, 0);
1189 ExpectBackoff(30, 4, 0);
1190 AddSwitchingEvt(80, 20);
1191 AddAccessRequest(101, 2, 111, 0);
1209 StartTest(4, 6, 10, 20, 40);
1213 AddAccessRequest(52, 20, 60, 0);
1223 StartTest(4, 6, 10, 20, 80);
1227 AddAccessRequest(58, 20, 60, 0);
1237 StartTest(4, 6, 10, 20, 80);
1241 AddAccessRequest(62, 20, 64, 0);
1252 StartTest(4, 6, 10, 20, 160);
1254 AddRxErrorEvt(20, 30);
1256 AddAccessRequest(55, 20, 76, 0);
1267 StartTest(4, 6, 10, 20, 160);
1269 AddRxErrorEvt(20, 30);
1271 AddAccessRequest(70, 20, 76, 0);
1282 StartTest(4, 6, 10, 20, 160);
1284 AddRxErrorEvt(20, 30);
1286 AddAccessRequest(82, 20, 84, 0);
1295 StartTest(4, 6, 10);
1298 AddAccessRequest(30, 20, 76, 0);
1299 ExpectBackoff(30, 4, 0);
1310 StartTest(4, 6, 10);
1315 AddAccessRequest(30, 20, 107, 0);
1316 ExpectBackoff(30, 3, 0);
1339 void DoRun()
override;
1354 :
TestCase(
"Check calculation of the largest idle primary channel")
1389 std::vector<Time>(chWidth == 20 ? 0 : chWidth / 20,
Seconds(0)));
1394 uint16_t idleWidth = (busyChannel == WifiChannelListType::WIFI_CHANLIST_PRIMARY)
1396 : ((1 << (busyChannel - 1)) * 20);
1398 Time checkTime1 = start + ccaBusyStartDelay + ccaBusyDuration / 2;
1400 Time interval1 = (ccaBusyStartDelay + ccaBusyDuration) / 2;
1403 "Incorrect width of the idle channel in an interval "
1404 <<
"ending within CCA_BUSY (channel width: " << chWidth
1405 <<
" MHz, busy channel: " << busyChannel <<
")");
1411 Time checkTime2 = start + ccaBusyStartDelay + ccaBusyDuration + ccaBusyRxInterval / 2;
1413 Time interval2 = (ccaBusyDuration + ccaBusyRxInterval) / 2;
1416 "Incorrect width of the idle channel in an interval "
1417 <<
"starting within CCA_BUSY (channel width: " << chWidth
1418 <<
" MHz, busy channel: " << busyChannel <<
")");
1430 Time checkTime3 = start + ccaBusyStartDelay + ccaBusyDuration + ccaBusyRxInterval + rxDuration;
1432 Time interval3 = ccaBusyDuration / 2 + ccaBusyRxInterval;
1433 Time end3 = checkTime3 - rxDuration;
1436 "Incorrect width of the idle channel in an interval "
1437 <<
"preceding RX start and overlapping CCA_BUSY "
1438 <<
"(channel width: " << chWidth
1439 <<
" MHz, busy channel: " << busyChannel <<
")");
1444 const Time& checkTime4 = checkTime3;
1446 const Time& interval4 = ccaBusyRxInterval;
1447 Time end4 = checkTime4 - rxDuration;
1450 "Incorrect width of the idle channel in the interval "
1451 <<
"following CCA_BUSY and preceding RX start (channel "
1452 <<
"width: " << chWidth <<
" MHz, busy channel: " << busyChannel
1459 Time checkTime5 = checkTime4 + interval5;
1463 "Incorrect width of the idle channel in an interval "
1464 <<
"following RX end (channel width: " << chWidth
1465 <<
" MHz, busy channel: " << busyChannel <<
")");
1469 const Time& checkTime6 = checkTime5;
1471 Time interval6 = interval5 + rxDuration / 2;
1474 "Incorrect width of the idle channel in an interval "
1475 <<
"overlapping RX (channel width: " << chWidth
1476 <<
" MHz, busy channel: " << busyChannel <<
")");
1483 m_cam = CreateObject<ChannelAccessManager>();
1485 uint8_t channel = 0;
1486 std::list<WifiChannelListType> busyChannels;
1488 for (uint16_t chWidth : {20, 40, 80, 160})
1492 for (
const auto busyChannel : busyChannels)
1502 m_phy = CreateObject<SpectrumWifiPhy>();
1512 RunOne(chWidth, busyChannel);
1579 :
TestSuite(
"wifi-channel-access-manager", UNIT)
static ChannelAccessManagerTestSuite g_camTestSuite
static TxopTestSuite g_dcfTestSuite
static QosTxopTestSuite g_edcaTestSuite
ChannelAccessManager Stub.
ChannelAccessManagerStub()
Time GetEifsNoDifs() const override
Return the EIFS duration minus a DIFS.
void SetEifsNoDifs(Time eifsNoDifs)
Set the duration of EIFS - DIFS.
void SetSlot(Time slot)
Set the slot duration.
Time GetSlot() const override
Return the slot duration for this PHY.
Time m_sifs
SIFS duration.
Time GetSifs() const override
Return the Short Interframe Space (SIFS) for this PHY.
void SetSifs(Time sifs)
Set the Short Interframe Space (SIFS).
Time m_eifsNoDifs
EIFS duration minus a DIFS.
Channel Access Manager Test.
void AddAccessRequestWithSuccessfulAck(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from)
Add access request with successful ack.
void AddAckTimeoutReset(uint64_t at)
Add Ack timeout reset function.
void NotifyInternalCollision(Ptr< TxopTest< TxopType > > state)
Notify internal collision 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.
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 StartTest(uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue=20, uint16_t chWidth=20)
Start test function.
void ExpectBackoff(uint64_t time, uint32_t nSlots, uint32_t from)
Expect generate backoff function.
void DoRun() override
Implementation to actually run this TestCase.
void AddTxop(uint32_t aifsn)
Add Txop function.
Ptr< SpectrumWifiPhy > m_phy
the PHY object
void DoAccessRequest(uint64_t txTime, uint64_t expectedGrantTime, Ptr< TxopTest< TxopType > > state)
Add access request with successful Ack.
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.
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 ExpectBusy(uint64_t time, bool busy)
Schedule a check that the channel access manager is busy or idle.
void EndTest()
End test function.
void AddCcaBusyEvt(uint64_t at, uint64_t duration, WifiChannelListType channelType=WIFI_CHANLIST_PRIMARY, const std::vector< Time > &per20MhzDurations={})
Add CCA busy event function.
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 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 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.
void NotifyChannelSwitching()
Notify channel switching function.
ChannelAccessManager Test Suite.
ChannelAccessManagerTestSuite()
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, uint16_t allowedWidth) override
Request the FrameExchangeManager to start a frame exchange sequence.
Test the calculation of the largest idle primary channel performed by ChannelAccessManager::GetLarges...
Ptr< SpectrumWifiPhy > m_phy
PHY object.
LargestIdlePrimaryChannelTest()
void RunOne(uint16_t chWidth, WifiChannelListType busyChannel)
Test a specific combination of operating channel width and busy channel type.
~LargestIdlePrimaryChannelTest() override=default
void DoRun() override
Implementation to actually run this TestCase.
Ptr< ChannelAccessManager > m_cam
channel access manager
ExpectedBackoffs m_expectedInternalCollision
expected backoff due to an internal collision
void DoDispose() override
Destructor implementation.
void GenerateBackoff(uint8_t linkId) override
Generate a new backoff for the given link now.
uint32_t m_i
the index of the Txop
void NotifyChannelAccessed(uint8_t linkId, Time txopDuration=Seconds(0)) override
Called by the FrameExchangeManager to notify that channel access has been granted on the given link f...
void QueueTx(uint64_t txTime, uint64_t expectedGrantTime)
Queue transmit function.
ExpectedBackoffs m_expectedBackoff
expected backoff (not due to an internal collision)
std::list< ExpectedGrant > ExpectedGrants
the collection of expected grants typedef
void NotifySleep(uint8_t linkId) override
Notify that the given link switched to sleep mode.
ChannelAccessManagerTest< TxopType > * m_test
Check if the Txop has frames to transmit.
ExpectedGrants m_expectedGrants
expected grants
std::list< ExpectedBackoff > ExpectedBackoffs
expected backoffs typedef
void NotifyWakeUp(uint8_t linkId) override
When wake up operation occurs on a link, channel access on that link will be restarted.
bool HasFramesToTransmit(uint8_t linkId) override
Check if the Txop has frames to transmit over the given link.
TxopTest(ChannelAccessManagerTest< TxopType > *test, uint32_t i)
Constructor.
std::pair< uint64_t, uint64_t > ExpectedGrant
the expected grant typedef
Manage a set of ns3::Txop.
uint16_t GetLargestIdlePrimaryChannel(Time interval, Time end)
Return the width of the largest primary channel that has been idle for the given time interval before...
void NotifyRxEndErrorNow()
Notify the Txop that a packet reception was just completed unsuccessfuly.
void NotifyRxStartNow(Time duration)
void NotifyAckTimeoutResetNow()
Notify that ack timer has reset.
void NotifyTxStartNow(Time duration)
void NotifyRxEndOkNow()
Notify the Txop that a packet reception was just completed successfully.
void NotifyCcaBusyStartNow(Time duration, WifiChannelListType channelType, const std::vector< Time > &per20MhzDurations)
void RemovePhyListener(Ptr< WifiPhy > phy)
Remove current registered listener for PHY events.
void SetupPhyListener(Ptr< WifiPhy > phy)
Set up listener for PHY events.
void NotifySwitchingStartNow(Time duration)
void NotifyNavResetNow(Time duration)
void NotifyNavStartNow(Time duration)
FrameExchangeManager is a base class handling the basic frame exchange sequences for non-QoS stations...
void Dispose()
Dispose of this Object.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
static Time Now()
Return the current simulation virtual time.
static void Run()
Run the simulation.
void AddChannel(const Ptr< SpectrumChannel > channel, const FrequencyRange &freqRange=WHOLE_WIFI_SPECTRUM)
Attach a SpectrumChannel to use for a given frequency range.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Simulation virtual time values and global simulation resolution.
LinkEntity & GetLink(uint8_t linkId) const
Get a reference to the link associated with the given ID.
virtual void SetInterferenceHelper(const Ptr< InterferenceHelper > helper)
Sets the interference helper.
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
void SetOperatingChannel(const ChannelTuple &channelTuple)
If the standard for this object has not been set yet, store the given channel settings.
std::tuple< uint8_t, uint16_t, int, uint8_t > ChannelTuple
Tuple identifying an operating channel.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Time Now()
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.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
WifiChannelListType
Enumeration of the possible channel-list parameter elements defined in Table 8-5 of IEEE 802....
@ WIFI_PHY_BAND_UNSPECIFIED
Unspecified.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
@ WIFI_CHANLIST_SECONDARY40
@ WIFI_CHANLIST_SECONDARY
@ WIFI_CHANLIST_SECONDARY80
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
-ns3 Test suite for the ns3 wrapper script
ExpectedBackoff structure.
uint32_t nSlots
number of slots
ChannelAccessStatus access
channel access status