wifi: Schedule a BAR transmission subject to the availability of data frames

This commit is contained in:
Stefano Avallone
2019-09-29 18:21:03 +02:00
parent 7f271f896e
commit 95a6a26387
6 changed files with 66 additions and 26 deletions

View File

@@ -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"),

View File

@@ -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++)

View File

@@ -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:
/**

View File

@@ -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));

View File

@@ -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 ();

View File

@@ -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 */
/**