wifi: Block Ack Manager schedules BARs received as MPDUs

This commit is contained in:
Stefano Avallone
2019-07-24 14:55:49 +02:00
parent f0bee86835
commit 769d055ac1
5 changed files with 50 additions and 30 deletions

View File

@@ -587,7 +587,20 @@ BlockAckManager::NotifyDiscardedMpdu (Ptr<const WifiMacQueueItem> mpdu)
// schedule a block ack request
NS_LOG_DEBUG ("Schedule a Block Ack Request for agreement (" << recipient << ", " << +tid << ")");
ScheduleBlockAckReq (recipient, tid);
Ptr<Packet> bar = Create<Packet> ();
bar->AddHeader (GetBlockAckReqHeader (recipient, tid));
WifiMacHeader hdr;
hdr.SetType (WIFI_MAC_CTL_BACKREQ);
hdr.SetAddr1 (recipient);
hdr.SetAddr2 (mpdu->GetHeader ().GetAddr2 ());
hdr.SetAddr3 (mpdu->GetHeader ().GetAddr3 ());
hdr.SetDsNotTo ();
hdr.SetDsNotFrom ();
hdr.SetNoRetry ();
hdr.SetNoMoreFragments ();
ScheduleBar (Create<const WifiMacQueueItem> (bar, hdr));
}
CtrlBAckRequestHeader
@@ -605,28 +618,35 @@ BlockAckManager::GetBlockAckReqHeader (Mac48Address recipient, uint8_t tid) cons
}
void
BlockAckManager::ScheduleBlockAckReq (Mac48Address recipient, uint8_t tid)
BlockAckManager::ScheduleBar (Ptr<const WifiMacQueueItem> bar)
{
NS_LOG_FUNCTION (this << recipient << +tid);
NS_LOG_FUNCTION (this << *bar);
NS_ASSERT (bar->GetHeader ().IsBlockAckReq ());
Ptr<Packet> bar = Create<Packet> ();
bar->AddHeader (GetBlockAckReqHeader (recipient, tid));
WifiMacHeader hdr;
hdr.SetAddr1 (recipient);
hdr.SetType (WIFI_MAC_CTL_BACKREQ);
Bar request (Create<const WifiMacQueueItem> (bar, hdr), tid);
CtrlBAckRequestHeader reqHdr;
bar->GetPacket ()->PeekHeader (reqHdr);
uint8_t tid = reqHdr.GetTidInfo ();
Bar request (bar, tid);
// 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++)
{
if (i->bar->GetHeader ().GetAddr1 () == recipient && i->tid == tid)
if (i->bar->GetHeader ().GetAddr1 () == bar->GetHeader ().GetAddr1 () && i->tid == tid)
{
i = m_bars.erase (i);
m_bars.insert (i, request);
return;
}
}
m_bars.push_back (request);
if (bar->GetHeader ().IsRetry ())
{
m_bars.push_front (request);
}
else
{
m_bars.push_back (request);
}
}
void

View File

@@ -393,22 +393,20 @@ public:
* \param recipient the recipient
* \param tid the TID
*
* Get the block ack request header for the established BA agreement
* Get the Block Ack Request header for the established BA agreement
* (<i>recipient</i>,<i>tid</i>).
*/
CtrlBAckRequestHeader GetBlockAckReqHeader (Mac48Address recipient, uint8_t tid) const;
/**
* \param recipient the recipient
* \param tid the TID
* \param bar the Block Ack Request to enqueue
*
* Enqueue a block ack request for the established BA agreement
* (<i>recipient</i>,<i>tid</i>) into the queue storing the next
* BAR frames to transmit. If a BAR for the given agreement is
* already present in the queue, it is replaced by the new one.
* 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 ScheduleBlockAckReq (Mac48Address recipient, uint8_t tid);
void ScheduleBar (Ptr<const WifiMacQueueItem> bar);
private:
/**

View File

@@ -1973,7 +1973,8 @@ MacLow::SendDataPacket (void)
{
Ptr<QosTxop> qosTxop = DynamicCast<QosTxop> (m_currentTxop);
NS_ASSERT (qosTxop != 0);
qosTxop->ScheduleBlockAckReq (m_currentPacket->GetAddr1 (), *m_currentPacket->GetTids ().begin ());
auto bar = qosTxop->PrepareBlockAckRequest (m_currentPacket->GetAddr1 (), *m_currentPacket->GetTids ().begin ());
qosTxop->ScheduleBar (bar);
}
ForwardDown (m_currentPacket, m_currentTxVector);
}
@@ -2089,7 +2090,8 @@ MacLow::SendDataAfterCts (Time duration)
{
Ptr<QosTxop> qosTxop = DynamicCast<QosTxop> (m_currentTxop);
NS_ASSERT (qosTxop != 0);
qosTxop->ScheduleBlockAckReq (m_currentPacket->GetAddr1 (), *m_currentPacket->GetTids ().begin ());
auto bar = qosTxop->PrepareBlockAckRequest (m_currentPacket->GetAddr1 (), *m_currentPacket->GetTids ().begin ());
qosTxop->ScheduleBar (bar);
}
ForwardDown (m_currentPacket, m_currentTxVector);
}

View File

@@ -164,9 +164,9 @@ QosTxop::PrepareBlockAckRequest (Mac48Address recipient, uint8_t tid) const
}
void
QosTxop::ScheduleBlockAckReq (Mac48Address address, uint8_t tid)
QosTxop::ScheduleBar (Ptr<const WifiMacQueueItem> bar)
{
m_baManager->ScheduleBlockAckReq (address, tid);
m_baManager->ScheduleBar (bar);
}
void
@@ -900,7 +900,8 @@ QosTxop::MissedBlockAck (uint8_t nMpdus)
}
else // missed block ack after data frame with Implicit BAR Ack policy
{
m_baManager->ScheduleBlockAckReq (m_currentHdr.GetAddr1 (), tid);
Ptr<const WifiMacQueueItem> bar = PrepareBlockAckRequest (m_currentHdr.GetAddr1 (), tid);
ScheduleBar (bar);
m_currentPacket = 0;
}
}

View File

@@ -196,13 +196,12 @@ public:
*/
Ptr<const WifiMacQueueItem> PrepareBlockAckRequest (Mac48Address recipient, uint8_t tid) const;
/**
* \param address recipient address
* \param tid traffic ID
* \param bar the Block Ack Request to schedule
*
* Request the Block Ack manager to schedule the transmission of a
* block ack request for the established BA agreement (<i>address</i>,<i>tid</i>).
* Request the Block Ack manager to schedule the transmission of the given
* Block Ack Request.
*/
void ScheduleBlockAckReq (Mac48Address address, uint8_t tid);
void ScheduleBar (Ptr<const WifiMacQueueItem> bar);
/* dcf notifications forwarded here */
/**