wifi: Possibly invoke backoff when no transmission is made in a TXOP
This commit is contained in:
committed by
Stefano Avallone
parent
1dde39c87c
commit
8cbcd0cb96
@@ -19,6 +19,7 @@ Changes from ns-3.40 to ns-3-dev
|
||||
### New API
|
||||
|
||||
* (spectrum) `SpectrumSignalParameters` is extended to include two new members called: `spectrumChannelMatrix` and `precodingMatrix` which are the key information needed to support MIMO simulations.
|
||||
* (wifi) Added new attribute `ChannelAccessManager:GenerateBackoffIfTxopWithoutTx` to invoke the backoff procedure when an AC gains the right to start a TXOP but it does not transmit any frame, provided that the queue is not actually empty. No transmission may occur,e.g., due to constraints associated with EMLSR operations. This possibility is specified by the current draft revision of the IEEE 802.11 standard.
|
||||
|
||||
### Changes to existing API
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -907,6 +907,8 @@ one and only one of the following functions:
|
||||
|
||||
* Decrement the backoff timer.
|
||||
* Initiate the transmission of a frame exchange sequence.
|
||||
* Invoke the backoff procedure due to choosing not to transmit (to be included
|
||||
in the version of the standard following IEEE 802.11-2020)
|
||||
* Invoke the backoff procedure due to an internal collision.
|
||||
* Do nothing.
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ namespace ns3
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE("ChannelAccessManager");
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED(ChannelAccessManager);
|
||||
|
||||
/**
|
||||
* Listener for PHY events. Forwards to ChannelAccessManager.
|
||||
* The ChannelAccessManager may handle multiple PHY listeners connected to distinct PHYs,
|
||||
@@ -168,6 +170,26 @@ class PhyListener : public ns3::WifiPhyListener
|
||||
* Implement the channel access manager of all Txop holders
|
||||
****************************************************************/
|
||||
|
||||
TypeId
|
||||
ChannelAccessManager::GetTypeId()
|
||||
{
|
||||
static TypeId tid =
|
||||
TypeId("ns3::ChannelAccessManager")
|
||||
.SetParent<ns3::Object>()
|
||||
.SetGroupName("Wifi")
|
||||
.AddConstructor<ChannelAccessManager>()
|
||||
.AddAttribute("GenerateBackoffIfTxopWithoutTx",
|
||||
"Specify whether the backoff should be invoked when the AC gains the "
|
||||
"right to start a TXOP but it does not transmit any frame "
|
||||
"(e.g., due to constraints associated with EMLSR operations), "
|
||||
"provided that the queue is not actually empty.",
|
||||
BooleanValue(false),
|
||||
MakeBooleanAccessor(&ChannelAccessManager::SetGenerateBackoffOnNoTx,
|
||||
&ChannelAccessManager::GetGenerateBackoffOnNoTx),
|
||||
MakeBooleanChecker());
|
||||
return tid;
|
||||
}
|
||||
|
||||
ChannelAccessManager::ChannelAccessManager()
|
||||
: m_lastAckTimeoutEnd(0),
|
||||
m_lastCtsTimeoutEnd(0),
|
||||
@@ -453,7 +475,7 @@ void
|
||||
ChannelAccessManager::RequestAccess(Ptr<Txop> txop)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << txop);
|
||||
if (m_phy)
|
||||
if (m_phy && txop->HasFramesToTransmit(m_linkId))
|
||||
{
|
||||
m_phy->NotifyChannelAccessRequested();
|
||||
}
|
||||
@@ -558,6 +580,9 @@ ChannelAccessManager::DoGrantDcfAccess()
|
||||
}
|
||||
else
|
||||
{
|
||||
// this TXOP did not transmit anything, make sure that backoff counter starts
|
||||
// decreasing in a slot again
|
||||
txop->UpdateBackoffSlotsNow(0, now, m_linkId);
|
||||
// reset the current state to the EDCAF that won the contention
|
||||
// but did not transmit anything
|
||||
i--;
|
||||
@@ -801,6 +826,19 @@ ChannelAccessManager::DisableEdcaFor(Ptr<Txop> qosTxop, Time duration)
|
||||
DoRestartAccessTimeoutIfNeeded();
|
||||
}
|
||||
|
||||
void
|
||||
ChannelAccessManager::SetGenerateBackoffOnNoTx(bool enable)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << enable);
|
||||
m_generateBackoffOnNoTx = enable;
|
||||
}
|
||||
|
||||
bool
|
||||
ChannelAccessManager::GetGenerateBackoffOnNoTx() const
|
||||
{
|
||||
return m_generateBackoffOnNoTx;
|
||||
}
|
||||
|
||||
void
|
||||
ChannelAccessManager::NotifyRxStartNow(Time duration)
|
||||
{
|
||||
|
||||
@@ -62,6 +62,12 @@ class ChannelAccessManager : public Object
|
||||
ChannelAccessManager();
|
||||
~ChannelAccessManager() override;
|
||||
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId();
|
||||
|
||||
/**
|
||||
* Set up (or reactivate) listener for PHY events on the given PHY. The new (or reactivated)
|
||||
* listener becomes the active listener and the previous active listener attached to another
|
||||
@@ -157,6 +163,22 @@ class ChannelAccessManager : public Object
|
||||
*/
|
||||
void DisableEdcaFor(Ptr<Txop> qosTxop, Time duration);
|
||||
|
||||
/**
|
||||
* Set the member variable indicating whether the backoff should be invoked when an AC gains
|
||||
* the right to start a TXOP but it does not transmit any frame (e.g., due to constraints
|
||||
* associated with EMLSR operations), provided that the queue is not actually empty.
|
||||
*
|
||||
* \param enable whether to enable backoff generation when no TX is performed in a TXOP
|
||||
*/
|
||||
void SetGenerateBackoffOnNoTx(bool enable);
|
||||
|
||||
/**
|
||||
* \return whether the backoff should be invoked when an AC gains the right to start a TXOP
|
||||
* but it does not transmit any frame (e.g., due to constraints associated with EMLSR
|
||||
* operations), provided that the queue is not actually empty
|
||||
*/
|
||||
bool GetGenerateBackoffOnNoTx() const;
|
||||
|
||||
/**
|
||||
* Return the width of the largest primary channel that has been idle for the
|
||||
* given time interval before the given time, if any primary channel has been
|
||||
@@ -431,6 +453,10 @@ class ChannelAccessManager : public Object
|
||||
bool m_off; //!< flag whether it is in off state
|
||||
Time m_eifsNoDifs; //!< EIFS no DIFS time
|
||||
EventId m_accessTimeout; //!< the access timeout ID
|
||||
bool m_generateBackoffOnNoTx; //!< whether the backoff should be invoked when the AC gains the
|
||||
//!< right to start a TXOP but it does not transmit any frame
|
||||
//!< (e.g., due to constraints associated with EMLSR operations),
|
||||
//!< provided that the queue is not actually empty
|
||||
|
||||
/// Information associated with each PHY that is going to operate on another EMLSR link
|
||||
struct EmlsrLinkSwitchInfo
|
||||
|
||||
@@ -593,8 +593,27 @@ QosTxop::NotifyChannelReleased(uint8_t linkId)
|
||||
NS_LOG_DEBUG("Terminating TXOP. Duration = " << Simulator::Now() - *link.startTxop);
|
||||
m_txopTrace(*link.startTxop, Simulator::Now() - *link.startTxop, linkId);
|
||||
}
|
||||
|
||||
// generate a new backoff value if either the TXOP duration is not null (i.e., some frames
|
||||
// were transmitted) or no frame was transmitted but the queue actually contains frame to
|
||||
// transmit and the user indicated that a backoff value should be generated in this situation.
|
||||
// This behavior reflects the following specs text (Sec. 35.3.16.4 of 802.11be D4.0):
|
||||
// An AP or non-AP STA affiliated with an MLD that has gained the right to initiate the
|
||||
// transmission of a frame as described in 10.23.2.4 (Obtaining an EDCA TXOP) for an AC but
|
||||
// does not transmit any frame corresponding to that AC for the reasons stated above may:
|
||||
// - invoke a backoff for the EDCAF associated with that AC as allowed per h) of 10.23.2.2
|
||||
// (EDCA backoff procedure).
|
||||
auto hasTransmitted = link.startTxop.has_value() && Simulator::Now() > *link.startTxop;
|
||||
|
||||
m_queue->WipeAllExpiredMpdus();
|
||||
if ((hasTransmitted) ||
|
||||
(!m_queue->IsEmpty() && m_mac->GetChannelAccessManager(linkId)->GetGenerateBackoffOnNoTx()))
|
||||
{
|
||||
GenerateBackoff(linkId);
|
||||
Simulator::ScheduleNow(&QosTxop::RequestAccess, this, linkId);
|
||||
}
|
||||
link.startTxop.reset();
|
||||
Txop::NotifyChannelReleased(linkId);
|
||||
GetLink(linkId).access = NOT_REQUESTED;
|
||||
}
|
||||
|
||||
Time
|
||||
|
||||
Reference in New Issue
Block a user