diff --git a/src/wifi/model/edca-txop-n.cc b/src/wifi/model/edca-txop-n.cc index 385f2b2e7..f8b1806cc 100644 --- a/src/wifi/model/edca-txop-n.cc +++ b/src/wifi/model/edca-txop-n.cc @@ -656,28 +656,42 @@ void EdcaTxopN::NotifyInternalCollision (void) { NS_LOG_FUNCTION (this); bool resetDcf = false; + // If an internal collision is experienced, the frame involved may still + // be sitting in the queue, and m_currentPacket may still be null. + Ptr packet; + WifiMacHeader header; + if (m_currentPacket == 0) + { + packet = m_queue->Peek (&header); + NS_ASSERT_MSG (packet, "Internal collision but no packet in queue"); + } + else + { + packet = m_currentPacket; + header = m_currentHdr; + } if (m_isAccessRequestedForRts) { - if (!NeedRtsRetransmission ()) + if (!NeedRtsRetransmission (packet, header)) { resetDcf = true; - m_stationManager->ReportFinalRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr); + m_stationManager->ReportFinalRtsFailed (header.GetAddr1 (), &header); } else { - m_stationManager->ReportRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr); + m_stationManager->ReportRtsFailed (header.GetAddr1 (), &header); } } else { - if (!NeedDataRetransmission ()) + if (!NeedDataRetransmission (packet, header)) { resetDcf = true; - m_stationManager->ReportFinalDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr); + m_stationManager->ReportFinalDataFailed (header.GetAddr1 (), &header); } else { - m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr); + m_stationManager->ReportDataFailed (header.GetAddr1 (), &header); } } if (resetDcf) @@ -685,10 +699,19 @@ void EdcaTxopN::NotifyInternalCollision (void) NS_LOG_DEBUG ("reset DCF"); if (!m_txFailedCallback.IsNull ()) { - m_txFailedCallback (m_currentHdr); + m_txFailedCallback (header); } //to reset the dcf. - m_currentPacket = 0; + 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 @@ -786,7 +809,7 @@ EdcaTxopN::MissedCts (void) { NS_LOG_FUNCTION (this); NS_LOG_DEBUG ("missed cts"); - if (!NeedRtsRetransmission ()) + if (!NeedRtsRetransmission (m_currentPacket, m_currentHdr)) { NS_LOG_DEBUG ("Cts Fail"); bool resetCurrentPacket = true; @@ -934,7 +957,7 @@ EdcaTxopN::MissedAck (void) { NS_LOG_FUNCTION (this); NS_LOG_DEBUG ("missed ack"); - if (!NeedDataRetransmission ()) + if (!NeedDataRetransmission (m_currentPacket, m_currentHdr)) { NS_LOG_DEBUG ("Ack Fail"); m_stationManager->ReportFinalDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr); @@ -1152,19 +1175,17 @@ EdcaTxopN::StartAccessIfNeeded (void) } bool -EdcaTxopN::NeedRtsRetransmission (void) +EdcaTxopN::NeedRtsRetransmission (Ptr packet, const WifiMacHeader &hdr) { NS_LOG_FUNCTION (this); - return m_stationManager->NeedRtsRetransmission (m_currentHdr.GetAddr1 (), &m_currentHdr, - m_currentPacket); + return m_stationManager->NeedRtsRetransmission (hdr.GetAddr1 (), &hdr, packet); } bool -EdcaTxopN::NeedDataRetransmission (void) +EdcaTxopN::NeedDataRetransmission (Ptr packet, const WifiMacHeader &hdr) { NS_LOG_FUNCTION (this); - return m_stationManager->NeedDataRetransmission (m_currentHdr.GetAddr1 (), &m_currentHdr, - m_currentPacket); + return m_stationManager->NeedDataRetransmission (hdr.GetAddr1 (), &hdr, packet); } bool diff --git a/src/wifi/model/edca-txop-n.h b/src/wifi/model/edca-txop-n.h index f5cd94845..fc265b977 100644 --- a/src/wifi/model/edca-txop-n.h +++ b/src/wifi/model/edca-txop-n.h @@ -309,17 +309,21 @@ public: /** * Check if RTS should be re-transmitted if CTS was missed. * + * \param packet current packet being transmitted + * \param hdr current header being transmitted * \return true if RTS should be re-transmitted, * false otherwise */ - bool NeedRtsRetransmission (void); + bool NeedRtsRetransmission (Ptr packet, const WifiMacHeader &hdr); /** * Check if DATA should be re-transmitted if ACK was missed. * + * \param packet current packet being transmitted + * \param hdr current header being transmitted * \return true if DATA should be re-transmitted, * false otherwise */ - bool NeedDataRetransmission (void); + bool NeedDataRetransmission (Ptr packet, const WifiMacHeader &hdr); /** * Check if Block ACK Request should be re-transmitted. *