wifi: Enable ChannelAccessManager to send alerts before backoff expiration

This commit is contained in:
Stefano Avallone
2024-04-15 17:16:36 +02:00
parent e08ae6eaa9
commit b7e2cb8e07
2 changed files with 59 additions and 10 deletions

View File

@@ -185,7 +185,20 @@ ChannelAccessManager::GetTypeId()
"and subsequently the medium becomes busy.",
BooleanValue(false),
MakeBooleanAccessor(&ChannelAccessManager::m_proactiveBackoff),
MakeBooleanChecker());
MakeBooleanChecker())
.AddAttribute("NSlotsLeft",
"Fire the NSlotsLeftAlert trace source when the backoff counter with "
"the minimum value among all ACs reaches this value or it is started "
"with a value less than this attribute. If this value is zero, the "
"trace source is never fired.",
UintegerValue(0),
MakeUintegerAccessor(&ChannelAccessManager::m_nSlotsLeft),
MakeUintegerChecker<uint8_t>())
.AddTraceSource("NSlotsLeftAlert",
"The backoff counter of the AC with the given index reached the "
"threshold set through the NSlotsLeft attribute.",
MakeTraceSourceAccessor(&ChannelAccessManager::m_nSlotsLeftCallback),
"ns3::ChannelAccessManager::NSlotsLeftCallback");
return tid;
}
@@ -754,26 +767,43 @@ ChannelAccessManager::DoRestartAccessTimeoutIfNeeded()
* Is there a Txop which needs to access the medium, and,
* if there is one, how many slots for AIFS+backoff does it require ?
*/
bool accessTimeoutNeeded = false;
Ptr<Txop> nextTxop;
auto expectedBackoffEnd = Simulator::GetMaximumSimulationTime();
const auto accessGrantStart = GetAccessGrantStart();
const auto now = Simulator::Now();
for (auto txop : m_txops)
{
if (txop->GetAccessStatus(m_linkId) == Txop::REQUESTED)
{
Time tmp = GetBackoffEndFor(txop, accessGrantStart);
if (tmp > Simulator::Now())
if (auto backoffEnd = GetBackoffEndFor(txop, accessGrantStart);
backoffEnd > now && backoffEnd < expectedBackoffEnd)
{
accessTimeoutNeeded = true;
expectedBackoffEnd = std::min(expectedBackoffEnd, tmp);
expectedBackoffEnd = backoffEnd;
nextTxop = txop;
}
}
}
NS_LOG_DEBUG("Access timeout needed: " << accessTimeoutNeeded);
if (accessTimeoutNeeded)
NS_LOG_DEBUG("Access timeout needed: " << (nextTxop != nullptr));
if (nextTxop)
{
NS_LOG_DEBUG("expected backoff end=" << expectedBackoffEnd);
Time expectedBackoffDelay = expectedBackoffEnd - Simulator::Now();
const auto aci = nextTxop->GetWifiMacQueue()->GetAc();
NS_LOG_DEBUG("expected backoff end=" << expectedBackoffEnd << " by " << aci);
auto expectedBackoffDelay = expectedBackoffEnd - now;
if (m_nSlotsLeft > 0)
{
if (const auto slots = m_nSlotsLeft * GetSlot(); expectedBackoffDelay > slots)
{
// make the timer expire when the specified number of slots are left
expectedBackoffDelay -= slots;
}
else
{
// notify that a number of slots less than or equal to the specified value are left
m_nSlotsLeftCallback(m_linkId, aci, expectedBackoffDelay);
}
}
if (m_accessTimeout.IsPending() &&
Simulator::GetDelayLeft(m_accessTimeout) > expectedBackoffDelay)
{

View File

@@ -15,6 +15,7 @@
#include "ns3/event-id.h"
#include "ns3/nstime.h"
#include "ns3/object.h"
#include "ns3/traced-callback.h"
#include <algorithm>
#include <map>
@@ -32,6 +33,7 @@ class WifiPhy;
class PhyListener;
class Txop;
class FrameExchangeManager;
enum AcIndex : uint8_t; // opaque enum declaration
/**
* \brief Manage a set of ns3::Txop
@@ -501,6 +503,23 @@ class ChannelAccessManager : public Object
Ptr<WifiPhy> m_phy; //!< pointer to the unique active PHY
Ptr<FrameExchangeManager> m_feManager; //!< pointer to the Frame Exchange Manager
uint8_t m_linkId; //!< the ID of the link this object is associated with
uint8_t m_nSlotsLeft; //!< fire the NSlotsLeftAlert trace source when the
//!< backoff counter with the minimum value among all
//!< ACs reaches this value
/**
* TracedCallback signature for NSlotsLeft alerts.
*
* \param linkId the ID of this link
* \param aci the index of the AC that triggered the NSlotsLeft alert
* \param backoffDelay delay until backoff counts down to zero
*/
typedef void (*NSlotsLeftCallback)(uint8_t linkId, AcIndex aci, const Time& backoffDelay);
/// TracedCallback for NSlotsLeft alerts typedef
using NSlotsLeftTracedCallback = TracedCallback<uint8_t, AcIndex, const Time&>;
NSlotsLeftTracedCallback m_nSlotsLeftCallback; //!< traced callback for NSlotsLeft alerts
};
} // namespace ns3