wifi: (fixes #2578) Fix unexpected assert 'Internal collision but no packet in queue'

This commit is contained in:
Sébastien Deronne
2017-01-13 20:08:04 +01:00
parent 3fb64fda99
commit e905d6a2a7
3 changed files with 56 additions and 45 deletions

View File

@@ -56,6 +56,7 @@ Bugs fixed
- Bug 2564 - Simulation crashes when CtsTimeout is triggered for A-MPDU transmissions
- Bug 2566 - BlockAckManager::GetNRetryNeededPackets missing some packets in the queue
- Bug 2577 - simulation crashes when A-MPDU and multiple TOS are used with RTS-CTS enabled
- Bug 2578 - Assert "Internal collision but no packet in queue" unexpectedly triggered
- Bug 2584 - MacLow triggers StartNext even if there is no TXOP
- Bug 2590 - Minor enhancements in red-queue-disc{.h, .cc}
- Bug 2591 - 802.11e Block Ack mechanism cannot be enabled on HT/VHT stations

View File

@@ -166,6 +166,7 @@ DcfState::IsAccessRequested (void) const
{
return m_accessRequested;
}
void
DcfState::NotifyAccessRequested (void)
{

View File

@@ -666,65 +666,74 @@ void EdcaTxopN::NotifyInternalCollision (void)
WifiMacHeader header;
if (m_currentPacket == 0)
{
packet = m_queue->Peek (&header);
NS_ASSERT_MSG (packet, "Internal collision but no packet in queue");
if (m_baManager->HasPackets ())
{
packet = m_baManager->PeekNextPacket (header);
}
else
{
packet = m_queue->Peek (&header);
}
}
else
{
packet = m_currentPacket;
header = m_currentHdr;
}
if (m_isAccessRequestedForRts)
if (packet != 0)
{
if (!NeedRtsRetransmission (packet, header))
{
resetDcf = true;
m_stationManager->ReportFinalRtsFailed (header.GetAddr1 (), &header);
}
else
{
m_stationManager->ReportRtsFailed (header.GetAddr1 (), &header);
}
}
else if (header.GetAddr1 () == Mac48Address::GetBroadcast ())
{
resetDcf = false;
}
else
{
if (!NeedDataRetransmission (packet, header))
{
resetDcf = true;
m_stationManager->ReportFinalDataFailed (header.GetAddr1 (), &header);
}
else
{
m_stationManager->ReportDataFailed (header.GetAddr1 (), &header);
}
}
if (resetDcf)
{
NS_LOG_DEBUG ("reset DCF");
if (!m_txFailedCallback.IsNull ())
if (m_isAccessRequestedForRts)
{
m_txFailedCallback (header);
if (!NeedRtsRetransmission (packet, header))
{
resetDcf = true;
m_stationManager->ReportFinalRtsFailed (header.GetAddr1 (), &header);
}
else
{
m_stationManager->ReportRtsFailed (header.GetAddr1 (), &header);
}
}
//to reset the dcf.
if (m_currentPacket)
else if (header.GetAddr1 () == Mac48Address::GetBroadcast ())
{
NS_LOG_DEBUG ("Discarding m_currentPacket");
m_currentPacket = 0;
resetDcf = false;
}
else
{
NS_LOG_DEBUG ("Dequeueing and discarding head of queue");
packet = m_queue->Peek (&header);
if (!NeedDataRetransmission (packet, header))
{
resetDcf = true;
m_stationManager->ReportFinalDataFailed (header.GetAddr1 (), &header);
}
else
{
m_stationManager->ReportDataFailed (header.GetAddr1 (), &header);
}
}
if (resetDcf)
{
NS_LOG_DEBUG ("reset DCF");
if (!m_txFailedCallback.IsNull ())
{
m_txFailedCallback (header);
}
//to reset the dcf.
if (m_currentPacket)
{
NS_LOG_DEBUG ("Discarding m_currentPacket");
m_currentPacket = 0;
}
else
{
NS_LOG_DEBUG ("Dequeueing and discarding head of queue");
packet = m_queue->Peek (&header);
}
m_dcf->ResetCw ();
}
else
{
m_dcf->UpdateFailedCw ();
}
m_dcf->ResetCw ();
}
else
{
m_dcf->UpdateFailedCw ();
}
m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ());
m_dcf->StartBackoffNow (m_backoffTrace);