From e905d6a2a7685bb6528fec22c009cd197878e5ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deronne?= Date: Fri, 13 Jan 2017 20:08:04 +0100 Subject: [PATCH] wifi: (fixes #2578) Fix unexpected assert 'Internal collision but no packet in queue' --- RELEASE_NOTES | 1 + src/wifi/model/dcf-manager.cc | 1 + src/wifi/model/edca-txop-n.cc | 99 +++++++++++++++++++---------------- 3 files changed, 56 insertions(+), 45 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 30c77ae7d..5f0dac292 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -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 diff --git a/src/wifi/model/dcf-manager.cc b/src/wifi/model/dcf-manager.cc index 46e5a21c7..ca9eefea2 100644 --- a/src/wifi/model/dcf-manager.cc +++ b/src/wifi/model/dcf-manager.cc @@ -166,6 +166,7 @@ DcfState::IsAccessRequested (void) const { return m_accessRequested; } + void DcfState::NotifyAccessRequested (void) { diff --git a/src/wifi/model/edca-txop-n.cc b/src/wifi/model/edca-txop-n.cc index 496fab395..5aa0be580 100644 --- a/src/wifi/model/edca-txop-n.cc +++ b/src/wifi/model/edca-txop-n.cc @@ -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);