wifi: merge GetNextPacket and PeekNextPacket in BlockAckManager

This commit is contained in:
Sébastien Deronne
2017-11-04 11:15:42 +01:00
parent d6ea6b989f
commit feebef1f11
3 changed files with 60 additions and 119 deletions

View File

@@ -252,7 +252,7 @@ BlockAckManager::CompleteAmpduExchange (Mac48Address recipient, uint8_t tid)
}
Ptr<const Packet>
BlockAckManager::GetNextPacket (WifiMacHeader &hdr)
BlockAckManager::GetNextPacket (WifiMacHeader &hdr, bool removePacket)
{
NS_LOG_FUNCTION (this << &hdr);
Ptr<const Packet> packet = 0;
@@ -276,111 +276,60 @@ BlockAckManager::GetNextPacket (WifiMacHeader &hdr)
recipient = (*it)->hdr.GetAddr1 ();
AgreementsI agreement = m_agreements.find (std::make_pair (recipient, tid));
NS_ASSERT (agreement != m_agreements.end ());
if (QosUtilsIsOldPacket (agreement->second.first.GetStartingSequence (),(*it)->hdr.GetSequenceNumber ()))
if (removePacket)
{
//Standard says the originator should not send a packet with seqnum < winstart
NS_LOG_DEBUG ("The Retry packet have sequence number < WinStartO --> Discard " << (*it)->hdr.GetSequenceNumber () << " " << agreement->second.first.GetStartingSequence ());
agreement->second.second.erase ((*it));
if (QosUtilsIsOldPacket (agreement->second.first.GetStartingSequence (),(*it)->hdr.GetSequenceNumber ()))
{
//Standard says the originator should not send a packet with seqnum < winstart
NS_LOG_DEBUG ("The Retry packet have sequence number < WinStartO --> Discard " << (*it)->hdr.GetSequenceNumber () << " " << agreement->second.first.GetStartingSequence ());
agreement->second.second.erase ((*it));
it = m_retryPackets.erase (it);
continue;
}
else if ((*it)->hdr.GetSequenceNumber () > (agreement->second.first.GetStartingSequence () + 63) % 4096)
{
agreement->second.first.SetStartingSequence ((*it)->hdr.GetSequenceNumber ());
}
}
packet = (*it)->packet->Copy ();
hdr = (*it)->hdr;
hdr.SetRetry ();
if (hdr.IsQosData ())
{
tid = hdr.GetQosTid ();
}
else
{
NS_FATAL_ERROR ("Packet in blockAck manager retry queue is not Qos Data");
}
recipient = hdr.GetAddr1 ();
if (!agreement->second.first.IsHtSupported ()
&& (ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED)
|| SwitchToBlockAckIfNeeded (recipient, tid, hdr.GetSequenceNumber ())))
{
hdr.SetQosAckPolicy (WifiMacHeader::BLOCK_ACK);
}
else
{
/* From section 9.10.3 in IEEE802.11e standard:
* In order to improve efficiency, originators using the Block Ack facility
* may send MPDU frames with the Ack Policy subfield in QoS control frames
* set to Normal Ack if only a few MPDUs are available for transmission.[...]
* When there are sufficient number of MPDUs, the originator may switch back to
* the use of Block Ack.
*/
hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
if (removePacket)
{
AgreementsI i = m_agreements.find (std::make_pair (recipient, tid));
i->second.second.erase (*it);
}
}
if (removePacket)
{
NS_LOG_INFO ("Retry packet seq = " << hdr.GetSequenceNumber ());
it = m_retryPackets.erase (it);
continue;
}
else if ((*it)->hdr.GetSequenceNumber () > (agreement->second.first.GetStartingSequence () + 63) % 4096)
{
agreement->second.first.SetStartingSequence ((*it)->hdr.GetSequenceNumber ());
}
packet = (*it)->packet->Copy ();
hdr = (*it)->hdr;
hdr.SetRetry ();
NS_LOG_INFO ("Retry packet seq = " << hdr.GetSequenceNumber ());
if (hdr.IsQosData ())
{
tid = hdr.GetQosTid ();
}
else
{
NS_FATAL_ERROR ("Packet in blockAck manager retry queue is not Qos Data");
}
recipient = hdr.GetAddr1 ();
if (!agreement->second.first.IsHtSupported ()
&& (ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED)
|| SwitchToBlockAckIfNeeded (recipient, tid, hdr.GetSequenceNumber ())))
{
hdr.SetQosAckPolicy (WifiMacHeader::BLOCK_ACK);
}
else
{
/* From section 9.10.3 in IEEE802.11e standard:
* In order to improve efficiency, originators using the Block Ack facility
* may send MPDU frames with the Ack Policy subfield in QoS control frames
* set to Normal Ack if only a few MPDUs are available for transmission.[...]
* When there are sufficient number of MPDUs, the originator may switch back to
* the use of Block Ack.
*/
hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
AgreementsI i = m_agreements.find (std::make_pair (recipient, tid));
i->second.second.erase (*it);
}
it = m_retryPackets.erase (it);
NS_LOG_DEBUG ("Removed one packet, retry buffer size = " << m_retryPackets.size () );
break;
}
}
return packet;
}
Ptr<const Packet>
BlockAckManager::PeekNextPacket (WifiMacHeader &hdr)
{
NS_LOG_FUNCTION (this << &hdr);
Ptr<const Packet> packet = 0;
uint8_t tid;
Mac48Address recipient;
CleanupBuffers ();
if (!m_retryPackets.empty ())
{
NS_LOG_DEBUG ("Retry buffer size is " << m_retryPackets.size ());
std::list<PacketQueueI>::const_iterator it = m_retryPackets.begin ();
while (it != m_retryPackets.end ())
{
if ((*it)->hdr.IsQosData ())
{
tid = (*it)->hdr.GetQosTid ();
}
else
{
NS_FATAL_ERROR ("Packet in blockAck manager retry queue is not Qos Data");
}
recipient = (*it)->hdr.GetAddr1 ();
AgreementsI agreement = m_agreements.find (std::make_pair (recipient, tid));
NS_ASSERT (agreement != m_agreements.end ());
packet = (*it)->packet->Copy ();
hdr = (*it)->hdr;
hdr.SetRetry ();
if (hdr.IsQosData ())
{
tid = hdr.GetQosTid ();
}
else
{
NS_FATAL_ERROR ("Packet in blockAck manager retry queue is not Qos Data");
}
recipient = hdr.GetAddr1 ();
if (!agreement->second.first.IsHtSupported ()
&& (ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED)
|| SwitchToBlockAckIfNeeded (recipient, tid, hdr.GetSequenceNumber ())))
{
hdr.SetQosAckPolicy (WifiMacHeader::BLOCK_ACK);
}
else
{
/* From section 9.10.3 in IEEE802.11e standard:
* In order to improve efficiency, originators using the Block Ack facility
* may send MPDU frames with the Ack Policy subfield in QoS control frames
* set to Normal Ack if only a few MPDUs are available for transmission.[...]
* When there are sufficient number of MPDUs, the originator may switch back to
* the use of Block Ack.
*/
hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
NS_LOG_DEBUG ("Removed one packet, retry buffer size = " << m_retryPackets.size ());
}
break;
}

View File

@@ -152,22 +152,14 @@ public:
void StorePacket (Ptr<const Packet> packet, const WifiMacHeader &hdr, Time tStamp);
/**
* \param hdr 802.11 header of returned packet (if exists).
* \param removePacket flag to indicate whether the packet should be removed from the queue.
*
* \return the packet
*
* This methods returns a packet (if exists) indicated as not received in
* corresponding block ack bitmap.
*/
Ptr<const Packet> GetNextPacket (WifiMacHeader &hdr);
/**
* \param hdr 802.11 header of returned packet (if exists).
*
* \return the packet
*
* This methods returns a packet (if exists) indicated as not received in
* corresponding block ack bitmap. This method doesn't remove the packet from this queue.
*/
Ptr<const Packet> PeekNextPacket (WifiMacHeader &hdr);
Ptr<const Packet> GetNextPacket (WifiMacHeader &hdr, bool removePacket);
/**
* Returns true if the BAR is scheduled. Returns false otherwise.
*

View File

@@ -175,7 +175,7 @@ EdcaTxopN::NotifyAccessGranted (void)
return;
}
/* check if packets need retransmission are stored in BlockAckManager */
m_currentPacket = m_baManager->GetNextPacket (m_currentHdr);
m_currentPacket = m_baManager->GetNextPacket (m_currentHdr, true);
if (m_currentPacket == 0)
{
Ptr<const WifiMacQueueItem> item = m_queue->PeekFirstAvailable (m_qosBlockedDestinations);
@@ -331,7 +331,7 @@ void EdcaTxopN::NotifyInternalCollision (void)
{
if (m_baManager->HasPackets ())
{
packet = m_baManager->PeekNextPacket (header);
packet = m_baManager->GetNextPacket (header, false);
}
else
{
@@ -714,7 +714,7 @@ EdcaTxopN::RestartAccessIfNeeded (void)
}
else if (m_baManager->HasPackets ())
{
packet = m_baManager->PeekNextPacket (hdr);
packet = m_baManager->GetNextPacket (hdr, false);
}
else
{
@@ -755,7 +755,7 @@ EdcaTxopN::StartAccessIfNeeded (void)
}
else if (m_baManager->HasPackets ())
{
packet = m_baManager->PeekNextPacket (hdr);
packet = m_baManager->GetNextPacket (hdr, false);
}
else
{
@@ -813,7 +813,7 @@ EdcaTxopN::StartNextPacket (void)
Time txopLimit = GetTxopLimit ();
NS_ASSERT (txopLimit.IsZero () || Simulator::Now () - m_startTxop <= txopLimit);
WifiMacHeader hdr = m_currentHdr;
Ptr<const Packet> peekedPacket = m_baManager->GetNextPacket (hdr);
Ptr<const Packet> peekedPacket = m_baManager->GetNextPacket (hdr, true);
if (peekedPacket == 0)
{
Ptr<const WifiMacQueueItem> peekedItem = m_queue->PeekByTidAndAddress (m_currentHdr.GetQosTid (),