wifi: Schedule a BAR transmission subject to the availability of data frames
This commit is contained in:
@@ -48,7 +48,7 @@ cpp_examples = [
|
||||
("wifi-he-network --simulationTime=0.3 --frequency=5 --useRts=1 --minExpectedThroughput=6 --maxExpectedThroughput=745", "True", "True"),
|
||||
("wifi-he-network --simulationTime=0.25 --frequency=2.4 --useRts=0 --minExpectedThroughput=6 --maxExpectedThroughput=238", "True", "True"),
|
||||
("wifi-he-network --simulationTime=0.3 --frequency=2.4 --useRts=1 --minExpectedThroughput=6 --maxExpectedThroughput=223", "True", "True"),
|
||||
("wifi-simple-ht-hidden-stations --simulationTime=1.5 --enableRts=0 --nMpdus=32 --minExpectedThroughput=52 --maxExpectedThroughput=53", "True", "True"),
|
||||
("wifi-simple-ht-hidden-stations --simulationTime=1.5 --enableRts=0 --nMpdus=32 --minExpectedThroughput=50 --maxExpectedThroughput=51", "True", "True"),
|
||||
("wifi-simple-ht-hidden-stations --simulationTime=1 --enableRts=1 --nMpdus=32 --minExpectedThroughput=57 --maxExpectedThroughput=58", "True", "True"),
|
||||
("wifi-mixed-network --simulationTime=1", "True", "True"),
|
||||
("wifi-aggregation --simulationTime=1 --verifyResults=1", "True", "True"),
|
||||
|
||||
@@ -37,11 +37,12 @@ Bar::Bar ()
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
Bar::Bar (Ptr<const WifiMacQueueItem> bar, uint8_t tid)
|
||||
Bar::Bar (Ptr<const WifiMacQueueItem> bar, uint8_t tid, bool skipIfNoDataQueued)
|
||||
: bar (bar),
|
||||
tid (tid)
|
||||
tid (tid),
|
||||
skipIfNoDataQueued (skipIfNoDataQueued)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *bar << +tid);
|
||||
NS_LOG_FUNCTION (this << *bar << +tid << skipIfNoDataQueued);
|
||||
}
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (BlockAckManager);
|
||||
@@ -293,18 +294,26 @@ BlockAckManager::GetBar (bool remove)
|
||||
// (if needed) are scheduled
|
||||
m_retryPackets->Remove (WifiMacQueue::EMPTY, true);
|
||||
|
||||
while (!m_bars.empty ())
|
||||
{
|
||||
auto nextBar = m_bars.front ();
|
||||
auto nextBar = m_bars.begin ();
|
||||
|
||||
if (nextBar.bar->GetHeader ().IsBlockAckReq ())
|
||||
while (nextBar != m_bars.end ())
|
||||
{
|
||||
if (nextBar->bar->GetHeader ().IsBlockAckReq ())
|
||||
{
|
||||
Mac48Address recipient = nextBar.bar->GetHeader ().GetAddr1 ();
|
||||
AgreementsI it = m_agreements.find (std::make_pair (recipient, nextBar.tid));
|
||||
Mac48Address recipient = nextBar->bar->GetHeader ().GetAddr1 ();
|
||||
AgreementsI it = m_agreements.find (std::make_pair (recipient, nextBar->tid));
|
||||
if (it == m_agreements.end ())
|
||||
{
|
||||
// BA agreement was torn down; remove this BAR and continue
|
||||
m_bars.pop_front ();
|
||||
nextBar = m_bars.erase (nextBar);
|
||||
continue;
|
||||
}
|
||||
if (nextBar->skipIfNoDataQueued
|
||||
&& m_retryPackets->PeekByTidAndAddress (nextBar->tid, recipient) == m_retryPackets->end ()
|
||||
&& m_queue->PeekByTidAndAddress (nextBar->tid, recipient) == m_queue->end ())
|
||||
{
|
||||
// skip this BAR as there is no data queued
|
||||
nextBar++;
|
||||
continue;
|
||||
}
|
||||
// remove expired outstanding MPDUs and update the starting sequence number
|
||||
@@ -323,20 +332,20 @@ BlockAckManager::GetBar (bool remove)
|
||||
}
|
||||
// update BAR if the starting sequence number changed
|
||||
CtrlBAckRequestHeader reqHdr;
|
||||
nextBar.bar->GetPacket ()->PeekHeader (reqHdr);
|
||||
nextBar->bar->GetPacket ()->PeekHeader (reqHdr);
|
||||
if (reqHdr.GetStartingSequence () != it->second.first.GetStartingSequence ())
|
||||
{
|
||||
reqHdr.SetStartingSequence (it->second.first.GetStartingSequence ());
|
||||
Ptr<Packet> packet = Create<Packet> ();
|
||||
packet->AddHeader (reqHdr);
|
||||
nextBar.bar = Create<const WifiMacQueueItem> (packet, nextBar.bar->GetHeader ());
|
||||
nextBar->bar = Create<const WifiMacQueueItem> (packet, nextBar->bar->GetHeader ());
|
||||
}
|
||||
}
|
||||
|
||||
bar = nextBar.bar;
|
||||
bar = nextBar->bar;
|
||||
if (remove)
|
||||
{
|
||||
m_bars.pop_front ();
|
||||
m_bars.erase (nextBar);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -344,10 +353,10 @@ BlockAckManager::GetBar (bool remove)
|
||||
}
|
||||
|
||||
bool
|
||||
BlockAckManager::HasPackets (void) const
|
||||
BlockAckManager::HasPackets (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return (!m_retryPackets->IsEmpty () || m_bars.size () > 0);
|
||||
return (!m_retryPackets->IsEmpty () || GetBar (false) != 0);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@@ -661,7 +670,7 @@ BlockAckManager::GetBlockAckReqHeader (Mac48Address recipient, uint8_t tid) cons
|
||||
}
|
||||
|
||||
void
|
||||
BlockAckManager::ScheduleBar (Ptr<const WifiMacQueueItem> bar)
|
||||
BlockAckManager::ScheduleBar (Ptr<const WifiMacQueueItem> bar, bool skipIfNoDataQueued)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *bar);
|
||||
NS_ASSERT (bar->GetHeader ().IsBlockAckReq ());
|
||||
@@ -669,7 +678,7 @@ BlockAckManager::ScheduleBar (Ptr<const WifiMacQueueItem> bar)
|
||||
CtrlBAckRequestHeader reqHdr;
|
||||
bar->GetPacket ()->PeekHeader (reqHdr);
|
||||
uint8_t tid = reqHdr.GetTidInfo ();
|
||||
Bar request (bar, tid);
|
||||
Bar request (bar, tid, skipIfNoDataQueued);
|
||||
|
||||
// if a BAR for the given agreement is present, replace it with the new one
|
||||
for (std::list<Bar>::const_iterator i = m_bars.begin (); i != m_bars.end (); i++)
|
||||
|
||||
@@ -54,10 +54,12 @@ struct Bar
|
||||
*
|
||||
* \param bar the BAR
|
||||
* \param tid the Traffic ID
|
||||
* \param skipIfNoDataQueued true to hold this BAR if there is no data queued
|
||||
*/
|
||||
Bar (Ptr<const WifiMacQueueItem> bar, uint8_t tid);
|
||||
Bar (Ptr<const WifiMacQueueItem> bar, uint8_t tid, bool skipIfNoDataQueued = false);
|
||||
Ptr<const WifiMacQueueItem> bar; ///< block ack request
|
||||
uint8_t tid; ///< TID
|
||||
bool skipIfNoDataQueued; ///< do not send if there is no data queued
|
||||
};
|
||||
|
||||
|
||||
@@ -161,7 +163,7 @@ public:
|
||||
* \return true if there are packets that need of retransmission or at least a BAR is scheduled,
|
||||
* false otherwise
|
||||
*/
|
||||
bool HasPackets (void) const;
|
||||
bool HasPackets (void);
|
||||
/**
|
||||
* Invoked upon receipt of an ack frame after the transmission of a QoS data frame
|
||||
* sent under an established Block Ack agreement. Remove the acknowledged frame
|
||||
@@ -400,13 +402,14 @@ public:
|
||||
|
||||
/**
|
||||
* \param bar the Block Ack Request to enqueue
|
||||
* \param skipIfNoDataQueued do not send if there is no data queued
|
||||
*
|
||||
* Enqueue the given Block Ack Request into the queue storing the next BAR
|
||||
* frames to transmit. If a BAR for the same recipient and TID is already present
|
||||
* in the queue, it is replaced by the new one. If the given BAR is retransmitted,
|
||||
* it is placed at the head of the queue, otherwise at the tail.
|
||||
*/
|
||||
void ScheduleBar (Ptr<const WifiMacQueueItem> bar);
|
||||
void ScheduleBar (Ptr<const WifiMacQueueItem> bar, bool skipIfNoDataQueued = false);
|
||||
|
||||
private:
|
||||
/**
|
||||
|
||||
@@ -92,6 +92,13 @@ ConstantWifiAckPolicySelector::UpdateTxParams (Ptr<WifiPsdu> psdu, MacLowTransmi
|
||||
return;
|
||||
}
|
||||
|
||||
// If QosTxop forced the use of Block Ack QoS policy, do not make any change
|
||||
if (params.MustSendBlockAckRequest ())
|
||||
{
|
||||
NS_LOG_DEBUG ("Use Block Ack policy as requested");
|
||||
return;
|
||||
}
|
||||
|
||||
// find the maximum distance from the sequence number of an MPDU included in the
|
||||
// PSDU to the starting sequence number of the transmit window.
|
||||
uint16_t maxDistToStartingSeq = psdu->GetMaxDistFromStartingSeq (m_qosTxop->GetBaStartingSequence (receiver, tid));
|
||||
|
||||
@@ -164,9 +164,9 @@ QosTxop::PrepareBlockAckRequest (Mac48Address recipient, uint8_t tid) const
|
||||
}
|
||||
|
||||
void
|
||||
QosTxop::ScheduleBar (Ptr<const WifiMacQueueItem> bar)
|
||||
QosTxop::ScheduleBar (Ptr<const WifiMacQueueItem> bar, bool skipIfNoDataQueued)
|
||||
{
|
||||
m_baManager->ScheduleBar (bar);
|
||||
m_baManager->ScheduleBar (bar, skipIfNoDataQueued);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -902,8 +902,28 @@ QosTxop::MissedBlockAck (uint8_t nMpdus)
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Block Ack Request Fail");
|
||||
// if a BA agreement exists, we can get here if there is no outstanding
|
||||
// MPDU whose lifetime has not expired yet.
|
||||
if (m_baManager->ExistsAgreementInState (m_currentHdr.GetAddr1 (), tid,
|
||||
OriginatorBlockAckAgreement::ESTABLISHED))
|
||||
{
|
||||
// If there is any (expired) outstanding MPDU, request the BA manager to discard
|
||||
// it, which involves the scheduling of a BAR to advance the recipient's window
|
||||
if (m_baManager->GetNBufferedPackets (m_currentHdr.GetAddr1 (), tid) > 0)
|
||||
{
|
||||
m_baManager->DiscardOutstandingMpdus (m_currentHdr.GetAddr1 (), tid);
|
||||
}
|
||||
// otherwise, it means that we have not received a Block Ack in response to a
|
||||
// BlockAckRequest sent while no frame was outstanding, whose purpose was therefore
|
||||
// to advance the recipient's window. Schedule a BlockAckRequest with
|
||||
// skipIfNoDataQueued set to true, so that the BlockAckRequest is only sent
|
||||
// if there are data frames queued for this recipient.
|
||||
else
|
||||
{
|
||||
ScheduleBar (PrepareBlockAckRequest (m_currentHdr.GetAddr1 (), tid), true);
|
||||
}
|
||||
}
|
||||
//to reset the dcf.
|
||||
m_baManager->DiscardOutstandingMpdus (m_currentHdr.GetAddr1 (), GetTid (m_currentPacket, m_currentHdr));
|
||||
m_currentPacket = 0;
|
||||
ResetCw ();
|
||||
m_cwTrace = GetCw ();
|
||||
|
||||
@@ -197,11 +197,12 @@ public:
|
||||
Ptr<const WifiMacQueueItem> PrepareBlockAckRequest (Mac48Address recipient, uint8_t tid) const;
|
||||
/**
|
||||
* \param bar the Block Ack Request to schedule
|
||||
* \param skipIfNoDataQueued do not send if there is no data queued
|
||||
*
|
||||
* Request the Block Ack manager to schedule the transmission of the given
|
||||
* Block Ack Request.
|
||||
*/
|
||||
void ScheduleBar (Ptr<const WifiMacQueueItem> bar);
|
||||
void ScheduleBar (Ptr<const WifiMacQueueItem> bar, bool skipIfNoDataQueued = false);
|
||||
|
||||
/* dcf notifications forwarded here */
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user