wifi: Handle packets ack'ed with Normal Ack under BA agreement
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user