wifi: Add test cases to check backoff after sleep/off period

This commit is contained in:
Stefano Avallone
2025-09-02 13:20:55 +02:00
parent 1ae62e6def
commit de2c14ae08

View File

@@ -76,10 +76,6 @@ class TxopTest : public TxopType
void NotifyChannelAccessed(uint8_t linkId, Time txopDuration = Seconds(0)) override;
/// @copydoc ns3::Txop::HasFramesToTransmit
bool HasFramesToTransmit(uint8_t linkId) override;
/// @copydoc ns3::Txop::NotifySleep
void NotifySleep(uint8_t linkId) override;
/// @copydoc ns3::Txop::NotifyWakeUp
void NotifyWakeUp(uint8_t linkId) override;
/// @copydoc ns3::Txop::GenerateBackoff
void GenerateBackoff(uint8_t linkId) override;
@@ -117,8 +113,18 @@ class TxopTest : public TxopType
class ChannelAccessManagerStub : public ChannelAccessManager
{
public:
ChannelAccessManagerStub()
/**
* @brief Get the type ID.
* @return the object TypeId
*/
static TypeId GetTypeId()
{
static TypeId tid = TypeId("ns3::ChannelAccessManagerStub")
.SetParent<ns3::ChannelAccessManager>()
.SetGroupName("Wifi")
.AddConstructor<ChannelAccessManagerStub>()
.HideFromDocumentation();
return tid;
}
/**
@@ -240,6 +246,7 @@ class ChannelAccessManagerTest : public TestCase
uint64_t eifsNoDifsNoSifs{10}; ///< the EIFS no DIFS no SIFS in microseconds
uint32_t ackTimeoutValue{20}; ///< the Ack timeout value in microseconds
MHz_u chWidth{20}; ///< the channel width
uint64_t resetBackoffThr{}; ///< reset backoff threshold
};
ChannelAccessManagerTest();
@@ -420,10 +427,9 @@ class ChannelAccessManagerTest : public TestCase
*
* @param at the event time
* @param duration the duration of the interval during which no PHY is connected
* @param threshold the value for the ResetBackoffThreshold attribute
* @param from the index of the Txop that has to request channel access when PHY is reconnected
*/
void AddPhyDisconnectEvt(uint64_t at, uint64_t duration, uint64_t threshold, uint32_t from);
void AddPhyDisconnectEvt(uint64_t at, uint64_t duration, uint32_t from);
/**
* Add a PHY reconnect event consisting in another PHY operating on the link for the given time.
@@ -433,6 +439,22 @@ class ChannelAccessManagerTest : public TestCase
*/
void AddPhyReconnectEvt(uint64_t at, uint64_t duration);
/**
* Add PHY sleep/resume events.
*
* @param at the event time
* @param duration the duration of the interval during which the PHY is in sleep state
*/
void AddPhySleepEvt(uint64_t at, uint64_t duration);
/**
* Add PHY off/on events.
*
* @param at the event time
* @param duration the duration of the interval during which the PHY is in off state
*/
void AddPhyOffEvt(uint64_t at, uint64_t duration);
typedef std::vector<Ptr<TxopTest<TxopType>>> TxopTests; //!< the TXOP tests typedef
Ptr<FrameExchangeManagerStub<TxopType>> m_feManager; //!< the Frame Exchange Manager stubbed
@@ -486,18 +508,6 @@ TxopTest<TxopType>::HasFramesToTransmit(uint8_t linkId)
return !m_expectedGrants.empty();
}
template <typename TxopType>
void
TxopTest<TxopType>::NotifySleep(uint8_t linkId)
{
}
template <typename TxopType>
void
TxopTest<TxopType>::NotifyWakeUp(uint8_t linkId)
{
}
template <typename TxopType>
ChannelAccessManagerTest<TxopType>::ChannelAccessManagerTest()
: TestCase("ChannelAccessManager")
@@ -632,7 +642,9 @@ template <typename TxopType>
void
ChannelAccessManagerTest<TxopType>::StartTest(const Params& params)
{
m_ChannelAccessManager = CreateObject<ChannelAccessManagerStub>();
m_ChannelAccessManager = CreateObjectWithAttributes<ChannelAccessManagerStub>(
"ResetBackoffThreshold",
TimeValue(MicroSeconds(params.resetBackoffThr)));
m_feManager = CreateObject<FrameExchangeManagerStub<TxopType>>(this);
m_ChannelAccessManager->SetupFrameExchangeManager(m_feManager);
m_ChannelAccessManager->SetSlot(MicroSeconds(params.slotTime));
@@ -662,7 +674,8 @@ ChannelAccessManagerTest<TxopType>::AddTxop(uint32_t aifsn)
auto mac = CreateObjectWithAttributes<AdhocWifiMac>(
"Txop",
PointerValue(CreateObjectWithAttributes<Txop>("AcIndex", StringValue("AC_BE_NQOS"))));
mac->SetWifiPhys({nullptr});
mac->SetWifiPhys({m_phy});
mac->SetChannelAccessManagers({m_ChannelAccessManager});
txop->SetWifiMac(mac);
txop->SetAifsn(aifsn);
}
@@ -908,11 +921,10 @@ template <typename TxopType>
void
ChannelAccessManagerTest<TxopType>::AddPhyDisconnectEvt(uint64_t at,
uint64_t duration,
uint64_t threshold,
uint32_t from)
{
m_ChannelAccessManager->SetAttribute("ResetBackoffThreshold",
TimeValue(MicroSeconds(threshold)));
TimeValue threshold;
m_ChannelAccessManager->GetAttribute("ResetBackoffThreshold", threshold);
Simulator::Schedule(MicroSeconds(at) - Now(),
&ChannelAccessManager::RemovePhyListener,
@@ -923,7 +935,7 @@ ChannelAccessManagerTest<TxopType>::AddPhyDisconnectEvt(uint64_t at,
auto txop = m_txop[from];
auto hadFramesToTransmit = txop->HasFramesToTransmit(SINGLE_LINK_OP_ID);
m_ChannelAccessManager->SetupPhyListener(m_phy);
if (duration > threshold)
if (MicroSeconds(duration) > threshold.Get())
{
// request channel access again because all backoffs have been reset
if (m_ChannelAccessManager->NeedBackoffUponAccess(txop, hadFramesToTransmit, true))
@@ -958,6 +970,22 @@ ChannelAccessManagerTest<TxopType>::AddPhyReconnectEvt(uint64_t at, uint64_t dur
});
}
template <typename TxopType>
void
ChannelAccessManagerTest<TxopType>::AddPhySleepEvt(uint64_t at, uint64_t duration)
{
Simulator::Schedule(MicroSeconds(at) - Now(), &WifiPhy::SetSleepMode, m_phy, false);
Simulator::Schedule(MicroSeconds(at + duration) - Now(), &WifiPhy::ResumeFromSleep, m_phy);
}
template <typename TxopType>
void
ChannelAccessManagerTest<TxopType>::AddPhyOffEvt(uint64_t at, uint64_t duration)
{
Simulator::Schedule(MicroSeconds(at) - Now(), &WifiPhy::SetOffMode, m_phy);
Simulator::Schedule(MicroSeconds(at + duration) - Now(), &WifiPhy::ResumeFromOff, m_phy);
}
/*
* Specialization of DoRun () method for DCF
*/
@@ -1489,12 +1517,12 @@ ChannelAccessManagerTest<QosTxop>::DoRun()
// | | |
// 30 request access. decrement reset
// backoff slots: 3 slots: 2 backoff
StartTest({.slotTime = 4, .sifs = 6});
StartTest({.slotTime = 4, .sifs = 6, .resetBackoffThr = 5});
AddTxop(1);
AddRxOkEvt(20, 30);
AddAccessRequest(30, 20, 81, 0);
ExpectBackoff(30, 3, 0);
AddPhyDisconnectEvt(61, 10, 0, 0);
AddPhyDisconnectEvt(61, 10, 0);
EndTest();
// Check backoff freeze while no PHY operates on a link for less than the threshold.
@@ -1503,12 +1531,12 @@ ChannelAccessManagerTest<QosTxop>::DoRun()
// | | | | |
// 30 request access. decrement resume decrement decrement
// backoff slots: 3 slots: 2 backoff slots: 1 slots: 0
StartTest({.slotTime = 4, .sifs = 6});
StartTest({.slotTime = 4, .sifs = 6, .resetBackoffThr = 20});
AddTxop(1);
AddRxOkEvt(20, 30);
AddAccessRequest(30, 20, 89, 0);
ExpectBackoff(30, 3, 0);
AddPhyDisconnectEvt(61, 10, 20, 0);
AddPhyDisconnectEvt(61, 10, 0);
EndTest();
// Check backoff left unmodified when previous PHY is reconnected to the link
@@ -1525,6 +1553,66 @@ ChannelAccessManagerTest<QosTxop>::DoRun()
ExpectBackoff(30, 4, 0);
AddPhyReconnectEvt(61, 10);
EndTest();
// Check reset of backoff and generation of new backoff value after that PHY is put to sleep for
// more than the threshold.
// 20 50 56 60 63 73 79 83 87 91 95 115
// | rx | sifs | aifsn | idle | phy sleep | sifs | aifsn | idle | idle | idle | tx |
// | | | | | |
// 30 request access. decrement reset backoff decrement decrement decrement
// backoff slots: 3 slots: 2 backoff slots: 3 slots: 2 slots: 1 slots: 0
StartTest({.slotTime = 4, .sifs = 6, .resetBackoffThr = 5});
AddTxop(1);
AddRxOkEvt(20, 30);
AddAccessRequest(30, 20, 95, 0);
ExpectBackoff(30, 3, 0);
AddPhySleepEvt(63, 10);
ExpectBackoff(73, 3, 0);
EndTest();
// Check backoff freeze while PHY is put to sleep for less than the threshold.
// 20 50 56 60 61 71 77 81 85 89 109
// | rx | sifs | aifsn | idle | phy sleep | sifs | aifsn | idle | idle | tx |
// | | | | |
// 30 request access. decrement resume decrement decrement
// backoff slots: 3 slots: 2 backoff slots: 1 slots: 0
StartTest({.slotTime = 4, .sifs = 6, .resetBackoffThr = 20});
AddTxop(1);
AddRxOkEvt(20, 30);
AddAccessRequest(30, 20, 89, 0);
ExpectBackoff(30, 3, 0);
AddPhySleepEvt(61, 10);
EndTest();
// Check reset of backoff and generation of new backoff value after that PHY is put to off for
// more than the threshold.
// 20 50 56 60 61 71 77 81 85 89 93 113
// | rx | sifs | aifsn | idle | phy off | sifs | aifsn | idle | idle | idle | tx |
// | | | | | |
// 30 request access. decrement reset backoff decrement decrement decrement
// backoff slots: 3 slots: 2 backoff slots: 3 slots: 2 slots: 1 slots: 0
StartTest({.slotTime = 4, .sifs = 6, .resetBackoffThr = 5});
AddTxop(1);
AddRxOkEvt(20, 30);
AddAccessRequest(30, 20, 93, 0);
ExpectBackoff(30, 3, 0);
AddPhyOffEvt(61, 10);
ExpectBackoff(71, 3, 0);
EndTest();
// Check backoff freeze while PHY is put to off for less than the threshold.
// 20 50 56 60 63 73 79 83 87 91 111
// | rx | sifs | aifsn | idle | phy off | sifs | aifsn | idle | idle | tx |
// | | | | |
// 30 request access. decrement resume decrement decrement
// backoff slots: 3 slots: 2 backoff slots: 1 slots: 0
StartTest({.slotTime = 4, .sifs = 6, .resetBackoffThr = 20});
AddTxop(1);
AddRxOkEvt(20, 30);
AddAccessRequest(30, 20, 91, 0);
ExpectBackoff(30, 3, 0);
AddPhyOffEvt(63, 10);
EndTest();
}
/**