wifi: Avoid using m_currentPacket if it has not yet been assigned

In the case of an internal collision, it may be the case that no packet
has yet been dequeued, and hence m_currentPacket and m_currentHdr are
not yet set, but backoff still needs to take place.  This patch will
peek the head of the queue under such conditions.
This commit is contained in:
Tom Henderson
2016-08-25 10:51:01 -07:00
parent a0e8cead91
commit 599d96fe5a
2 changed files with 43 additions and 18 deletions

View File

@@ -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<const Packet> 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<const Packet> 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<const Packet> 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

View File

@@ -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<const Packet> 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<const Packet> packet, const WifiMacHeader &hdr);
/**
* Check if Block ACK Request should be re-transmitted.
*