wifi: Handle packets ack'ed with Normal Ack under BA agreement

This commit is contained in:
Stefano Avallone
2019-04-09 17:07:48 +02:00
parent ee92df37d9
commit 8612d07e8b
3 changed files with 102 additions and 0 deletions

View File

@@ -502,6 +502,76 @@ BlockAckManager::AlreadyExists (uint16_t currentSeq, Mac48Address recipient, uin
return false;
}
void
BlockAckManager::NotifyGotAck (Ptr<const WifiMacQueueItem> mpdu)
{
NS_LOG_FUNCTION (this << *mpdu);
NS_ASSERT (mpdu->GetHeader ().IsQosData ());
Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
uint8_t tid = mpdu->GetHeader ().GetQosTid ();
NS_ASSERT (ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED));
AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
NS_ASSERT (it != m_agreements.end ());
// remove the acknowledged frame from the queue of outstanding packets
PacketQueueI queueIt = it->second.second.begin ();
while (queueIt != it->second.second.end ())
{
if ((*queueIt)->GetHeader ().GetSequenceNumber () == mpdu->GetHeader ().GetSequenceNumber ())
{
queueIt = it->second.second.erase (queueIt);
}
else
{
queueIt++;
}
}
uint16_t startingSeq = it->second.first.GetStartingSequence ();
if (mpdu->GetHeader ().GetSequenceNumber () == startingSeq)
{
// make the transmit window advance
it->second.first.SetStartingSequence ((startingSeq + 1) % 4096);
}
}
void
BlockAckManager::NotifyMissedAck (Ptr<WifiMacQueueItem> mpdu)
{
NS_LOG_FUNCTION (this << *mpdu);
NS_ASSERT (mpdu->GetHeader ().IsQosData ());
Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
uint8_t tid = mpdu->GetHeader ().GetQosTid ();
NS_ASSERT (ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED));
AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
NS_ASSERT (it != m_agreements.end ());
// remove the frame from the queue of outstanding packets (it will be re-inserted
// if retransmitted)
PacketQueueI queueIt = it->second.second.begin ();
while (queueIt != it->second.second.end ())
{
if ((*queueIt)->GetHeader ().GetSequenceNumber () == mpdu->GetHeader ().GetSequenceNumber ())
{
queueIt = it->second.second.erase (queueIt);
}
else
{
queueIt++;
}
}
// insert in the retransmission queue
if (!AlreadyExists (mpdu->GetHeader ().GetSequenceNumber (), recipient, tid))
{
InsertInRetryQueue (mpdu);
}
}
void
BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address recipient, double rxSnr, WifiMode txMode, double dataSnr)
{

View File

@@ -179,6 +179,24 @@ public:
* false otherwise
*/
bool HasPackets (void) const;
/**
* 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
* from the outstanding packets and update the starting sequence number of the
* transmit window, if needed.
*
* \param mpdu The acknowledged MPDU.
*/
void NotifyGotAck (Ptr<const WifiMacQueueItem> mpdu);
/**
* Invoked upon missed reception of an ack frame after the transmission of a
* QoS data frame sent under an established Block Ack agreement. Remove the
* acknowledged frame from the outstanding packets and insert it in the
* retransmission queue.
*
* \param mpdu The unacknowledged MPDU.
*/
void NotifyMissedAck (Ptr<WifiMacQueueItem> mpdu);
/**
* \param blockAck The received block ack frame.
* \param recipient Sender of block ack frame.

View File

@@ -872,6 +872,12 @@ QosTxop::GotAck (void)
}
}
}
if (m_currentHdr.IsQosData () && GetBaAgreementEstablished (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ()))
{
// notify the BA manager that the current packet was acknowledged
m_baManager->NotifyGotAck (Create<const WifiMacQueueItem> (m_currentPacket, m_currentHdr,
m_currentPacketTimestamp));
}
m_currentPacket = 0;
ResetCw ();
}
@@ -955,6 +961,14 @@ QosTxop::MissedAck (void)
m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr,
m_currentPacket->GetSize ());
m_currentHdr.SetRetry ();
if (m_currentHdr.IsQosData () && GetBaAgreementEstablished (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ()))
{
// notify the BA manager that the current packet was not acknowledged
m_baManager->NotifyMissedAck (Create<WifiMacQueueItem> (m_currentPacket, m_currentHdr,
m_currentPacketTimestamp));
// let the BA manager handle its retransmission
m_currentPacket = 0;
}
UpdateFailedCw ();
m_cwTrace = GetCw ();
}