wifi: Txop holds per-link backoff information
This commit is contained in:
committed by
Stefano Avallone
parent
8eb407d771
commit
18eb7e47a0
@@ -127,7 +127,7 @@ WaveFrameExchangeManager::StartTransmission (Ptr<Txop> dcf)
|
||||
if (queue->IsEmpty ())
|
||||
{
|
||||
NS_LOG_DEBUG ("Queue empty");
|
||||
m_dcf->NotifyChannelReleased ();
|
||||
m_dcf->NotifyChannelReleased (0);
|
||||
m_dcf = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -610,7 +610,7 @@ CwTrace (std::string context, uint32_t oldVal, uint32_t newVal)
|
||||
}
|
||||
|
||||
void
|
||||
BackoffTrace (std::string context, uint32_t newVal)
|
||||
BackoffTrace (std::string context, uint32_t newVal, uint8_t /* linkId */)
|
||||
{
|
||||
NS_LOG_INFO ("Backoff time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " val=" << newVal);
|
||||
if (tracing)
|
||||
|
||||
@@ -292,7 +292,7 @@ ChannelAccessManager::NeedBackoffUponAccess (Ptr<Txop> txop)
|
||||
* associated with that AC are empty; the medium is busy on the primary channel
|
||||
*/
|
||||
if (!txop->HasFramesToTransmit () && txop->GetAccessStatus () != Txop::GRANTED
|
||||
&& txop->GetBackoffSlots () == 0)
|
||||
&& txop->GetBackoffSlots (m_linkId) == 0)
|
||||
{
|
||||
if (!IsBusy ())
|
||||
{
|
||||
@@ -303,7 +303,7 @@ ChannelAccessManager::NeedBackoffUponAccess (Ptr<Txop> txop)
|
||||
// (performed by the next call to ChannelAccessManager::RequestAccess())
|
||||
Time delay = (txop->IsQosTxop () ? Seconds (0)
|
||||
: GetSifs () + txop->GetAifsn () * GetSlot ());
|
||||
txop->UpdateBackoffSlotsNow (0, Simulator::Now () + delay);
|
||||
txop->UpdateBackoffSlotsNow (0, Simulator::Now () + delay, m_linkId);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -332,14 +332,14 @@ ChannelAccessManager::RequestAccess (Ptr<Txop> txop)
|
||||
*/
|
||||
Time accessGrantStart = GetAccessGrantStart () + (txop->GetAifsn () * GetSlot ());
|
||||
|
||||
if (txop->IsQosTxop () && txop->GetBackoffStart () > accessGrantStart)
|
||||
if (txop->IsQosTxop () && txop->GetBackoffStart (m_linkId) > accessGrantStart)
|
||||
{
|
||||
// The backoff start time reported by the EDCAF is more recent than the last
|
||||
// time the medium was busy plus an AIFS, hence we need to align it to the
|
||||
// next slot boundary.
|
||||
Time diff = txop->GetBackoffStart () - accessGrantStart;
|
||||
Time diff = txop->GetBackoffStart (m_linkId) - accessGrantStart;
|
||||
uint32_t nIntSlots = (diff / GetSlot ()).GetHigh () + 1;
|
||||
txop->UpdateBackoffSlotsNow (0, accessGrantStart + (nIntSlots * GetSlot ()));
|
||||
txop->UpdateBackoffSlotsNow (0, accessGrantStart + (nIntSlots * GetSlot ()), m_linkId);
|
||||
}
|
||||
|
||||
UpdateBackoff ();
|
||||
@@ -365,7 +365,7 @@ ChannelAccessManager::DoGrantDcfAccess (void)
|
||||
* This is the first Txop we find with an expired backoff and which
|
||||
* needs access to the medium. i.e., it has data to send.
|
||||
*/
|
||||
NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. access granted. slots=" << txop->GetBackoffSlots ());
|
||||
NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. access granted. slots=" << txop->GetBackoffSlots (m_linkId));
|
||||
i++; //go to the next item in the list.
|
||||
k++;
|
||||
std::vector<Ptr<Txop> > internalCollisionTxops;
|
||||
@@ -376,7 +376,7 @@ ChannelAccessManager::DoGrantDcfAccess (void)
|
||||
&& GetBackoffEndFor (otherTxop) <= Simulator::Now ())
|
||||
{
|
||||
NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. internal collision. slots=" <<
|
||||
otherTxop->GetBackoffSlots ());
|
||||
otherTxop->GetBackoffSlots (m_linkId));
|
||||
/**
|
||||
* all other Txops with a lower priority whose backoff
|
||||
* has expired and which needed access to the medium
|
||||
@@ -477,7 +477,7 @@ Time
|
||||
ChannelAccessManager::GetBackoffStartFor (Ptr<Txop> txop)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << txop);
|
||||
Time mostRecentEvent = std::max ({txop->GetBackoffStart (),
|
||||
Time mostRecentEvent = std::max ({txop->GetBackoffStart (m_linkId),
|
||||
GetAccessGrantStart () + (txop->GetAifsn () * GetSlot ())});
|
||||
NS_LOG_DEBUG ("Backoff start: " << mostRecentEvent.As (Time::US));
|
||||
|
||||
@@ -488,7 +488,7 @@ Time
|
||||
ChannelAccessManager::GetBackoffEndFor (Ptr<Txop> txop)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << txop);
|
||||
Time backoffEnd = GetBackoffStartFor (txop) + (txop->GetBackoffSlots () * GetSlot ());
|
||||
Time backoffEnd = GetBackoffStartFor (txop) + (txop->GetBackoffSlots (m_linkId) * GetSlot ());
|
||||
NS_LOG_DEBUG ("Backoff end: " << backoffEnd.As (Time::US));
|
||||
|
||||
return backoffEnd;
|
||||
@@ -520,10 +520,10 @@ ChannelAccessManager::UpdateBackoff (void)
|
||||
{
|
||||
nIntSlots++;
|
||||
}
|
||||
uint32_t n = std::min (nIntSlots, txop->GetBackoffSlots ());
|
||||
uint32_t n = std::min (nIntSlots, txop->GetBackoffSlots (m_linkId));
|
||||
NS_LOG_DEBUG ("dcf " << k << " dec backoff slots=" << n);
|
||||
Time backoffUpdateBound = backoffStart + (n * GetSlot ());
|
||||
txop->UpdateBackoffSlotsNow (n, backoffUpdateBound);
|
||||
txop->UpdateBackoffSlotsNow (n, backoffUpdateBound, m_linkId);
|
||||
}
|
||||
++k;
|
||||
}
|
||||
@@ -611,8 +611,8 @@ ChannelAccessManager::DisableEdcaFor (Ptr<Txop> qosTxop, Time duration)
|
||||
UpdateBackoff ();
|
||||
Time resume = Simulator::Now () + duration;
|
||||
NS_LOG_DEBUG ("Backoff will resume at time " << resume << " with "
|
||||
<< qosTxop->GetBackoffSlots () << " remaining slot(s)");
|
||||
qosTxop->UpdateBackoffSlotsNow (0, resume);
|
||||
<< qosTxop->GetBackoffSlots (m_linkId) << " remaining slot(s)");
|
||||
qosTxop->UpdateBackoffSlotsNow (0, resume, m_linkId);
|
||||
DoRestartAccessTimeoutIfNeeded ();
|
||||
}
|
||||
|
||||
@@ -722,11 +722,11 @@ ChannelAccessManager::NotifySwitchingStartNow (Time duration)
|
||||
//Reset backoffs
|
||||
for (auto txop : m_txops)
|
||||
{
|
||||
uint32_t remainingSlots = txop->GetBackoffSlots ();
|
||||
uint32_t remainingSlots = txop->GetBackoffSlots (m_linkId);
|
||||
if (remainingSlots > 0)
|
||||
{
|
||||
txop->UpdateBackoffSlotsNow (remainingSlots, now);
|
||||
NS_ASSERT (txop->GetBackoffSlots () == 0);
|
||||
txop->UpdateBackoffSlotsNow (remainingSlots, now, m_linkId);
|
||||
NS_ASSERT (txop->GetBackoffSlots (m_linkId) == 0);
|
||||
}
|
||||
txop->ResetCw ();
|
||||
txop->m_access = Txop::NOT_REQUESTED;
|
||||
@@ -779,11 +779,11 @@ ChannelAccessManager::NotifyWakeupNow (void)
|
||||
m_sleeping = false;
|
||||
for (auto txop : m_txops)
|
||||
{
|
||||
uint32_t remainingSlots = txop->GetBackoffSlots ();
|
||||
uint32_t remainingSlots = txop->GetBackoffSlots (m_linkId);
|
||||
if (remainingSlots > 0)
|
||||
{
|
||||
txop->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now ());
|
||||
NS_ASSERT (txop->GetBackoffSlots () == 0);
|
||||
txop->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now (), m_linkId);
|
||||
NS_ASSERT (txop->GetBackoffSlots (m_linkId) == 0);
|
||||
}
|
||||
txop->ResetCw ();
|
||||
txop->m_access = Txop::NOT_REQUESTED;
|
||||
@@ -798,11 +798,11 @@ ChannelAccessManager::NotifyOnNow (void)
|
||||
m_off = false;
|
||||
for (auto txop : m_txops)
|
||||
{
|
||||
uint32_t remainingSlots = txop->GetBackoffSlots ();
|
||||
uint32_t remainingSlots = txop->GetBackoffSlots (m_linkId);
|
||||
if (remainingSlots > 0)
|
||||
{
|
||||
txop->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now ());
|
||||
NS_ASSERT (txop->GetBackoffSlots () == 0);
|
||||
txop->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now (), m_linkId);
|
||||
NS_ASSERT (txop->GetBackoffSlots (m_linkId) == 0);
|
||||
}
|
||||
txop->ResetCw ();
|
||||
txop->m_access = Txop::NOT_REQUESTED;
|
||||
|
||||
@@ -287,7 +287,7 @@ FrameExchangeManager::StartTransmission (Ptr<Txop> dcf)
|
||||
if (queue->IsEmpty ())
|
||||
{
|
||||
NS_LOG_DEBUG ("Queue empty");
|
||||
m_dcf->NotifyChannelReleased ();
|
||||
m_dcf->NotifyChannelReleased (m_linkId);
|
||||
m_dcf = 0;
|
||||
return false;
|
||||
}
|
||||
@@ -769,7 +769,7 @@ FrameExchangeManager::TransmissionSucceeded (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dcf->NotifyChannelReleased ();
|
||||
m_dcf->NotifyChannelReleased (m_linkId);
|
||||
m_dcf = 0;
|
||||
}
|
||||
}
|
||||
@@ -779,7 +779,7 @@ FrameExchangeManager::TransmissionFailed (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
// A non-QoS station always releases the channel upon a transmission failure
|
||||
m_dcf->NotifyChannelReleased ();
|
||||
m_dcf->NotifyChannelReleased (m_linkId);
|
||||
m_dcf = 0;
|
||||
}
|
||||
|
||||
@@ -916,7 +916,7 @@ FrameExchangeManager::NotifyInternalCollision (Ptr<Txop> txop)
|
||||
}
|
||||
}
|
||||
|
||||
txop->Txop::NotifyChannelReleased ();
|
||||
txop->Txop::NotifyChannelReleased (m_linkId);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -105,11 +105,11 @@ QosFrameExchangeManager::SendCfEndIfNeeded (void)
|
||||
{
|
||||
NS_LOG_DEBUG ("Send CF-End frame");
|
||||
m_phy->Send (Create<WifiPsdu> (Create<Packet> (), cfEnd), cfEndTxVector);
|
||||
Simulator::Schedule (txDuration, &Txop::NotifyChannelReleased, m_edca);
|
||||
Simulator::Schedule (txDuration, &Txop::NotifyChannelReleased, m_edca, m_linkId);
|
||||
return true;
|
||||
}
|
||||
|
||||
m_edca->NotifyChannelReleased ();
|
||||
m_edca->NotifyChannelReleased (m_linkId);
|
||||
m_edca = 0;
|
||||
return false;
|
||||
}
|
||||
@@ -125,7 +125,7 @@ QosFrameExchangeManager::PifsRecovery (void)
|
||||
if (m_channelAccessManager->GetAccessGrantStart () - m_phy->GetSifs ()
|
||||
> Simulator::Now () - m_phy->GetPifs ())
|
||||
{
|
||||
m_edca->NotifyChannelReleased ();
|
||||
m_edca->NotifyChannelReleased (m_linkId);
|
||||
m_edca = 0;
|
||||
}
|
||||
else
|
||||
@@ -144,7 +144,7 @@ QosFrameExchangeManager::CancelPifsRecovery (void)
|
||||
|
||||
NS_LOG_DEBUG ("Cancel PIFS recovery being attempted by EDCAF " << m_edca);
|
||||
m_pifsRecoveryEvent.Cancel ();
|
||||
m_edca->NotifyChannelReleased ();
|
||||
m_edca->NotifyChannelReleased (m_linkId);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -226,7 +226,7 @@ QosFrameExchangeManager::StartTransmission (Ptr<QosTxop> edca, Time txopDuration
|
||||
|
||||
// TXOP not even started, return false
|
||||
NS_LOG_DEBUG ("No frame transmitted");
|
||||
m_edca->NotifyChannelReleased ();
|
||||
m_edca->NotifyChannelReleased (m_linkId);
|
||||
m_edca = 0;
|
||||
return false;
|
||||
}
|
||||
@@ -253,7 +253,7 @@ QosFrameExchangeManager::StartTransmission (Ptr<QosTxop> edca, Time txopDuration
|
||||
}
|
||||
|
||||
NS_LOG_DEBUG ("No frame transmitted");
|
||||
m_edca->NotifyChannelReleased ();
|
||||
m_edca->NotifyChannelReleased (m_linkId);
|
||||
m_edca = 0;
|
||||
return false;
|
||||
}
|
||||
@@ -557,7 +557,7 @@ QosFrameExchangeManager::TransmissionSucceeded (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_edca->NotifyChannelReleased ();
|
||||
m_edca->NotifyChannelReleased (m_linkId);
|
||||
m_edca = 0;
|
||||
}
|
||||
m_initialFrame = false;
|
||||
@@ -580,7 +580,7 @@ QosFrameExchangeManager::TransmissionFailed (void)
|
||||
// The backoff procedure shall be invoked by an EDCAF when the transmission
|
||||
// of an MPDU in the initial PPDU of a TXOP fails (Sec. 10.22.2.2 of 802.11-2016)
|
||||
NS_LOG_DEBUG ("TX of the initial frame of a TXOP failed: terminate TXOP");
|
||||
m_edca->NotifyChannelReleased ();
|
||||
m_edca->NotifyChannelReleased (m_linkId);
|
||||
m_edca = 0;
|
||||
}
|
||||
else
|
||||
@@ -605,7 +605,7 @@ QosFrameExchangeManager::TransmissionFailed (void)
|
||||
// method of the Txop class, which only generates a new backoff value and
|
||||
// requests channel access if needed,
|
||||
NS_LOG_DEBUG ("TX of a non-initial frame of a TXOP failed: invoke backoff");
|
||||
m_edca->Txop::NotifyChannelReleased ();
|
||||
m_edca->Txop::NotifyChannelReleased (m_linkId);
|
||||
m_edcaBackingOff = m_edca;
|
||||
m_edca = 0;
|
||||
}
|
||||
|
||||
@@ -540,9 +540,9 @@ QosTxop::IsTxopStarted (void) const
|
||||
}
|
||||
|
||||
void
|
||||
QosTxop::NotifyChannelReleased (void)
|
||||
QosTxop::NotifyChannelReleased (uint8_t linkId)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_LOG_FUNCTION (this << +linkId);
|
||||
|
||||
if (m_startTxop.IsStrictlyPositive ())
|
||||
{
|
||||
@@ -550,7 +550,7 @@ QosTxop::NotifyChannelReleased (void)
|
||||
m_txopTrace (m_startTxop, Simulator::Now () - m_startTxop);
|
||||
}
|
||||
m_startTxop = Seconds (0);
|
||||
Txop::NotifyChannelReleased ();
|
||||
Txop::NotifyChannelReleased (linkId);
|
||||
}
|
||||
|
||||
Time
|
||||
@@ -661,14 +661,6 @@ QosTxop::GetBlockAckInactivityTimeout (void) const
|
||||
return m_blockAckInactivityTimeout;
|
||||
}
|
||||
|
||||
void
|
||||
QosTxop::DoInitialize (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
ResetCw ();
|
||||
GenerateBackoff ();
|
||||
}
|
||||
|
||||
void
|
||||
QosTxop::AddBaResponseTimeout (Mac48Address recipient, uint8_t tid)
|
||||
{
|
||||
@@ -678,7 +670,7 @@ QosTxop::AddBaResponseTimeout (Mac48Address recipient, uint8_t tid)
|
||||
{
|
||||
m_baManager->NotifyAgreementNoReply (recipient, tid);
|
||||
Simulator::Schedule (m_failedAddBaTimeout, &QosTxop::ResetBa, this, recipient, tid);
|
||||
GenerateBackoff ();
|
||||
GenerateBackoff (SINGLE_LINK_OP_ID);
|
||||
if (HasFramesToTransmit () && m_access == NOT_REQUESTED)
|
||||
{
|
||||
m_mac->GetChannelAccessManager (SINGLE_LINK_OP_ID)->RequestAccess (this);
|
||||
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
bool IsQosTxop (void) const override;
|
||||
bool HasFramesToTransmit (void) override;
|
||||
void NotifyChannelAccessed (Time txopDuration) override;
|
||||
void NotifyChannelReleased (void) override;
|
||||
void NotifyChannelReleased (uint8_t linkId) override;
|
||||
void SetDroppedMpduCallback (DroppedMpdu callback) override;
|
||||
|
||||
/**
|
||||
@@ -440,8 +440,6 @@ private:
|
||||
/// allow AggregationCapableTransmissionListener class access
|
||||
friend class AggregationCapableTransmissionListener;
|
||||
|
||||
void DoInitialize (void) override;
|
||||
|
||||
/**
|
||||
* Check if the given MPDU is to be considered old according to the current
|
||||
* starting sequence number of the transmit window, provided that a block ack
|
||||
|
||||
@@ -73,7 +73,7 @@ Txop::GetTypeId (void)
|
||||
.AddTraceSource ("BackoffTrace",
|
||||
"Trace source for backoff values",
|
||||
MakeTraceSourceAccessor (&Txop::m_backoffTrace),
|
||||
"ns3::TracedCallback::Uint32Callback")
|
||||
"ns3::Txop::BackoffValueTracedCallback")
|
||||
.AddTraceSource ("CwTrace",
|
||||
"Trace source for contention window values",
|
||||
MakeTraceSourceAccessor (&Txop::m_cwTrace),
|
||||
@@ -92,9 +92,7 @@ Txop::Txop (Ptr<WifiMacQueue> queue)
|
||||
m_cwMin (0),
|
||||
m_cwMax (0),
|
||||
m_cw (0),
|
||||
m_access (NOT_REQUESTED),
|
||||
m_backoffSlots (0),
|
||||
m_backoffStart (Seconds (0.0))
|
||||
m_access (NOT_REQUESTED)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_rng = CreateObject<UniformRandomVariable> ();
|
||||
@@ -224,40 +222,44 @@ Txop::UpdateFailedCw (void)
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Txop::GetBackoffSlots (void) const
|
||||
Txop::GetBackoffSlots (uint8_t linkId) const
|
||||
{
|
||||
return m_backoffSlots;
|
||||
return GetLink (linkId).backoffSlots;
|
||||
}
|
||||
|
||||
Time
|
||||
Txop::GetBackoffStart (void) const
|
||||
Txop::GetBackoffStart (uint8_t linkId) const
|
||||
{
|
||||
return m_backoffStart;
|
||||
return GetLink (linkId).backoffStart;
|
||||
}
|
||||
|
||||
void
|
||||
Txop::UpdateBackoffSlotsNow (uint32_t nSlots, Time backoffUpdateBound)
|
||||
Txop::UpdateBackoffSlotsNow (uint32_t nSlots, Time backoffUpdateBound, uint8_t linkId)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << nSlots << backoffUpdateBound);
|
||||
m_backoffSlots -= nSlots;
|
||||
m_backoffStart = backoffUpdateBound;
|
||||
NS_LOG_DEBUG ("update slots=" << nSlots << " slots, backoff=" << m_backoffSlots);
|
||||
NS_LOG_FUNCTION (this << nSlots << backoffUpdateBound << +linkId);
|
||||
auto& link = GetLink (linkId);
|
||||
|
||||
link.backoffSlots -= nSlots;
|
||||
link.backoffStart = backoffUpdateBound;
|
||||
NS_LOG_DEBUG ("update slots=" << nSlots << " slots, backoff=" << link.backoffSlots);
|
||||
}
|
||||
|
||||
void
|
||||
Txop::StartBackoffNow (uint32_t nSlots)
|
||||
Txop::StartBackoffNow (uint32_t nSlots, uint8_t linkId)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << nSlots);
|
||||
if (m_backoffSlots != 0)
|
||||
NS_LOG_FUNCTION (this << nSlots << +linkId);
|
||||
auto& link = GetLink (linkId);
|
||||
|
||||
if (link.backoffSlots != 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("reset backoff from " << m_backoffSlots << " to " << nSlots << " slots");
|
||||
NS_LOG_DEBUG ("reset backoff from " << link.backoffSlots << " to " << nSlots << " slots");
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("start backoff=" << nSlots << " slots");
|
||||
}
|
||||
m_backoffSlots = nSlots;
|
||||
m_backoffStart = Simulator::Now ();
|
||||
link.backoffSlots = nSlots;
|
||||
link.backoffStart = Simulator::Now ();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -316,7 +318,7 @@ Txop::Queue (Ptr<Packet> packet, const WifiMacHeader &hdr)
|
||||
packet->RemovePacketTag (priorityTag);
|
||||
if (m_mac->GetChannelAccessManager (SINGLE_LINK_OP_ID)->NeedBackoffUponAccess (this))
|
||||
{
|
||||
GenerateBackoff ();
|
||||
GenerateBackoff (SINGLE_LINK_OP_ID);
|
||||
}
|
||||
m_queue->Enqueue (Create<WifiMacQueueItem> (packet, hdr));
|
||||
StartAccessIfNeeded ();
|
||||
@@ -345,7 +347,10 @@ Txop::DoInitialize ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
ResetCw ();
|
||||
GenerateBackoff ();
|
||||
for (uint8_t linkId = 0; linkId < m_links.size (); linkId++)
|
||||
{
|
||||
GenerateBackoff (linkId);
|
||||
}
|
||||
}
|
||||
|
||||
Txop::ChannelAccessStatus
|
||||
@@ -369,11 +374,11 @@ Txop::NotifyChannelAccessed (Time txopDuration)
|
||||
}
|
||||
|
||||
void
|
||||
Txop::NotifyChannelReleased (void)
|
||||
Txop::NotifyChannelReleased (uint8_t linkId)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_LOG_FUNCTION (this << +linkId);
|
||||
m_access = NOT_REQUESTED;
|
||||
GenerateBackoff ();
|
||||
GenerateBackoff (linkId);
|
||||
if (HasFramesToTransmit ())
|
||||
{
|
||||
Simulator::ScheduleNow (&Txop::RequestAccess, this);
|
||||
@@ -390,12 +395,12 @@ Txop::RequestAccess (void)
|
||||
}
|
||||
|
||||
void
|
||||
Txop::GenerateBackoff (void)
|
||||
Txop::GenerateBackoff (uint8_t linkId)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_LOG_FUNCTION (this << +linkId);
|
||||
uint32_t backoff = m_rng->GetInteger (0, GetCw ());
|
||||
m_backoffTrace (backoff);
|
||||
StartBackoffNow (backoff);
|
||||
m_backoffTrace (backoff, linkId);
|
||||
StartBackoffNow (backoff, linkId);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -230,8 +230,10 @@ public:
|
||||
/**
|
||||
* Called by the FrameExchangeManager to notify the completion of the transmissions.
|
||||
* This method generates a new backoff and restarts access if needed.
|
||||
*
|
||||
* \param linkId the ID of the link the FrameExchangeManager is operating on
|
||||
*/
|
||||
virtual void NotifyChannelReleased (void);
|
||||
virtual void NotifyChannelReleased (uint8_t linkId);
|
||||
|
||||
/**
|
||||
* Assign a fixed random variable stream number to the random variables
|
||||
@@ -251,11 +253,12 @@ public:
|
||||
|
||||
/**
|
||||
* \param nSlots the number of slots of the backoff.
|
||||
* \param linkId the ID of the given link
|
||||
*
|
||||
* Start a backoff by initializing the backoff counter to the number of
|
||||
* slots specified.
|
||||
* Start a backoff for the given link by initializing the backoff counter to
|
||||
* the number of slots specified.
|
||||
*/
|
||||
void StartBackoffNow (uint32_t nSlots);
|
||||
void StartBackoffNow (uint32_t nSlots, uint8_t linkId);
|
||||
|
||||
protected:
|
||||
///< ChannelAccessManager associated class
|
||||
@@ -276,9 +279,11 @@ protected:
|
||||
*/
|
||||
virtual bool HasFramesToTransmit (void);
|
||||
/**
|
||||
* Generate a new backoff now.
|
||||
* Generate a new backoff for the given link now.
|
||||
*
|
||||
* \param linkId the ID of the given link
|
||||
*/
|
||||
virtual void GenerateBackoff (void);
|
||||
virtual void GenerateBackoff (uint8_t linkId);
|
||||
/**
|
||||
* Request access from Txop if needed.
|
||||
*/
|
||||
@@ -294,24 +299,27 @@ protected:
|
||||
*/
|
||||
uint32_t GetCw (void) const;
|
||||
/**
|
||||
* Return the current number of backoff slots.
|
||||
* Return the current number of backoff slots on the given link.
|
||||
*
|
||||
* \param linkId the ID of the given link
|
||||
* \return the current number of backoff slots
|
||||
*/
|
||||
uint32_t GetBackoffSlots (void) const;
|
||||
uint32_t GetBackoffSlots (uint8_t linkId) const;
|
||||
/**
|
||||
* Return the time when the backoff procedure started.
|
||||
* Return the time when the backoff procedure started on the given link.
|
||||
*
|
||||
* \param linkId the ID of the given link
|
||||
* \return the time when the backoff procedure started
|
||||
*/
|
||||
Time GetBackoffStart (void) const;
|
||||
Time GetBackoffStart (uint8_t linkId) const;
|
||||
/**
|
||||
* Update backoff slots that nSlots has passed.
|
||||
* Update backoff slots for the given link that nSlots has passed.
|
||||
*
|
||||
* \param nSlots the number of slots to decrement
|
||||
* \param backoffUpdateBound the time at which backoff should start
|
||||
* \param linkId the ID of the given link
|
||||
*/
|
||||
void UpdateBackoffSlotsNow (uint32_t nSlots, Time backoffUpdateBound);
|
||||
void UpdateBackoffSlotsNow (uint32_t nSlots, Time backoffUpdateBound, uint8_t linkId);
|
||||
|
||||
/**
|
||||
* Structure holding information specific to a single link. Here, the meaning of
|
||||
@@ -324,6 +332,11 @@ protected:
|
||||
virtual ~LinkEntity () = default;
|
||||
|
||||
uint8_t id {0}; //!< Link ID (starting at 0)
|
||||
uint32_t backoffSlots {0}; //!< the number of backoff slots
|
||||
Time backoffStart {0}; /**< the backoffStart variable is used to keep
|
||||
track of the time at which a backoff was
|
||||
started or the time at which the backoff
|
||||
counter was last updated */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -350,18 +363,14 @@ protected:
|
||||
uint32_t m_cwMax; //!< the maximum contention window
|
||||
uint32_t m_cw; //!< the current contention window
|
||||
ChannelAccessStatus m_access; //!< channel access status
|
||||
uint32_t m_backoffSlots; //!< the number of backoff slots
|
||||
/**
|
||||
* the backoffStart variable is used to keep track of the
|
||||
* time at which a backoff was started or the time at which
|
||||
* the backoff counter was last updated.
|
||||
*/
|
||||
Time m_backoffStart;
|
||||
|
||||
uint8_t m_aifsn; //!< the AIFSN
|
||||
Time m_txopLimit; //!< the TXOP limit time
|
||||
|
||||
TracedCallback<uint32_t> m_backoffTrace; //!< backoff trace value
|
||||
/// TracedCallback for backoff trace value typedef
|
||||
typedef TracedCallback<uint32_t /* value */, uint8_t /* linkId */> BackoffValueTracedCallback;
|
||||
|
||||
BackoffValueTracedCallback m_backoffTrace; //!< backoff trace value
|
||||
TracedValue<uint32_t> m_cwTrace; //!< CW trace value
|
||||
|
||||
private:
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "ns3/frame-exchange-manager.h"
|
||||
#include "ns3/qos-txop.h"
|
||||
#include "ns3/spectrum-wifi-phy.h"
|
||||
#include "ns3/adhoc-wifi-mac.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
@@ -72,7 +73,7 @@ private:
|
||||
/// \copydoc ns3::Txop::NotifyWakeUp
|
||||
void NotifyWakeUp (void) override;
|
||||
/// \copydoc ns3::Txop::GenerateBackoff
|
||||
void GenerateBackoff (void) override;
|
||||
void GenerateBackoff (uint8_t linkId) override;
|
||||
|
||||
typedef std::pair<uint64_t,uint64_t> ExpectedGrant; //!< the expected grant typedef
|
||||
typedef std::list<ExpectedGrant> ExpectedGrants; //!< the collection of expected grants typedef
|
||||
@@ -427,7 +428,7 @@ TxopTest<TxopType>::NotifyChannelAccessed (Time txopDuration)
|
||||
|
||||
template <typename TxopType>
|
||||
void
|
||||
TxopTest<TxopType>::GenerateBackoff (void)
|
||||
TxopTest<TxopType>::GenerateBackoff (uint8_t linkId)
|
||||
{
|
||||
m_test->GenerateBackoff (m_i);
|
||||
}
|
||||
@@ -492,7 +493,7 @@ ChannelAccessManagerTest<TxopType>::NotifyInternalCollision (Ptr<TxopTest<TxopTy
|
||||
struct TxopTest<TxopType>::ExpectedBackoff expected = state->m_expectedInternalCollision.front ();
|
||||
state->m_expectedInternalCollision.pop_front ();
|
||||
NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.at), "Expected internal collision time is now");
|
||||
state->StartBackoffNow (expected.nSlots);
|
||||
state->StartBackoffNow (expected.nSlots, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -507,7 +508,7 @@ ChannelAccessManagerTest<TxopType>::GenerateBackoff (uint32_t i)
|
||||
struct TxopTest<TxopType>::ExpectedBackoff expected = state->m_expectedBackoff.front ();
|
||||
state->m_expectedBackoff.pop_front ();
|
||||
NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.at), "Expected backoff is now");
|
||||
state->StartBackoffNow (expected.nSlots);
|
||||
state->StartBackoffNow (expected.nSlots, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -594,6 +595,10 @@ ChannelAccessManagerTest<TxopType>::AddTxop (uint32_t aifsn)
|
||||
txop->SetAifsn (aifsn);
|
||||
m_txop.push_back (txop);
|
||||
m_ChannelAccessManager->Add (txop);
|
||||
// the following causes the creation of a link for the txop object
|
||||
auto mac = CreateObject<AdhocWifiMac> ();
|
||||
mac->SetWifiPhys ({nullptr});
|
||||
txop->SetWifiMac (mac);
|
||||
}
|
||||
|
||||
template <typename TxopType>
|
||||
@@ -730,7 +735,7 @@ ChannelAccessManagerTest<TxopType>::DoAccessRequest (uint64_t txTime, uint64_t e
|
||||
{
|
||||
if (m_ChannelAccessManager->NeedBackoffUponAccess (state))
|
||||
{
|
||||
state->GenerateBackoff ();
|
||||
state->GenerateBackoff (0);
|
||||
}
|
||||
state->QueueTx (txTime, expectedGrantTime);
|
||||
m_ChannelAccessManager->RequestAccess (state);
|
||||
|
||||
Reference in New Issue
Block a user