--- a/RELEASE_NOTES Thu Aug 04 22:43:52 2016 +0200
+++ b/RELEASE_NOTES Fri Aug 05 22:44:56 2016 +0200
@@ -49,6 +49,7 @@
- Bug 1939 - Aggregating the same object to two nodes produce unexpected results
- Bug 1977 - v4Ping verbose output when not explicitly stopped
- Bug 2057 - ARP and Ndisc caches should be updated by receiving valid L3 packets
+- Bug 2222 - incorrect EDCA behavior in case of internal collision
- Bug 2308 - PacketTag instead of ByteTag in LTE PDCP/RLC
- Bug 2346 - SixLowPan ConpressionThreshold can be violated.
- Bug 2329 - TCP Veno implementation
--- a/src/wifi/model/block-ack-manager.cc Thu Aug 04 22:43:52 2016 +0200
+++ b/src/wifi/model/block-ack-manager.cc Fri Aug 05 22:44:56 2016 +0200
@@ -322,9 +322,68 @@
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>::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);
+ }
+ break;
+ }
+ }
+ return packet;
+}
Ptr<const Packet>
-BlockAckManager::PeekNextPacket (WifiMacHeader &hdr, Mac48Address recipient, uint8_t tid, Time *tstamp)
+BlockAckManager::PeekNextPacketByTidAndAddress (WifiMacHeader &hdr, Mac48Address recipient, uint8_t tid, Time *tstamp)
{
NS_LOG_FUNCTION (this);
Ptr<const Packet> packet = 0;
--- a/src/wifi/model/block-ack-manager.h Thu Aug 04 22:43:52 2016 +0200
+++ b/src/wifi/model/block-ack-manager.h Fri Aug 05 22:44:56 2016 +0200
@@ -152,6 +152,15 @@
* 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);
bool HasBar (struct Bar &bar);
/**
* Returns true if there are packets that need of retransmission or at least a
@@ -320,9 +329,11 @@
*/
bool RemovePacket (uint8_t tid, Mac48Address recipient, uint16_t seqnumber);
/*
- * Peek in retransmit queue and get the next packet without removing it from the queue
+ * Peek in retransmit queue and get the next packet having address indicated
+ * by <i>type</i> equals to <i>addr</i>, and tid equals to <i>tid</i>.
+ * This method doesn't remove the packet from this queue.
*/
- Ptr<const Packet> PeekNextPacket (WifiMacHeader &hdr, Mac48Address recipient, uint8_t tid, Time *timestamp);
+ Ptr<const Packet> PeekNextPacketByTidAndAddress (WifiMacHeader &hdr, Mac48Address recipient, uint8_t tid, Time *timestamp);
/**
* This function returns true if the lifetime of the packets a BAR refers to didn't expire yet else it returns false.
* If it return false then the BAR will be discarded (i.e. will not be re-transmitted)
--- a/src/wifi/model/edca-txop-n.cc Thu Aug 04 22:43:52 2016 +0200
+++ b/src/wifi/model/edca-txop-n.cc Fri Aug 05 22:44:56 2016 +0200
@@ -264,7 +264,8 @@
m_mpduAggregator (0),
m_typeOfStation (STA),
m_blockAckType (COMPRESSED_BLOCK_ACK),
- m_startTxop (Seconds (0))
+ m_startTxop (Seconds (0)),
+ m_isAccessRequestedForRts (false)
{
NS_LOG_FUNCTION (this);
m_transmissionListener = new EdcaTxopN::TransmissionListener (this);
@@ -483,7 +484,7 @@
Ptr<const Packet>
EdcaTxopN::PeekNextRetransmitPacket (WifiMacHeader &header,Mac48Address recipient, uint8_t tid, Time *timestamp)
{
- return m_baManager->PeekNextPacket (header,recipient,tid, timestamp);
+ return m_baManager->PeekNextPacketByTidAndAddress (header,recipient,tid, timestamp);
}
void
@@ -496,6 +497,7 @@
EdcaTxopN::NotifyAccessGranted (void)
{
NS_LOG_FUNCTION (this);
+ m_isAccessRequestedForRts = false;
if (m_currentPacket == 0)
{
if (m_queue->IsEmpty () && !m_baManager->HasPackets ())
@@ -653,7 +655,49 @@
void EdcaTxopN::NotifyInternalCollision (void)
{
NS_LOG_FUNCTION (this);
- NotifyCollision ();
+ bool resetDcf = false;
+ if (m_isAccessRequestedForRts)
+ {
+ if (!NeedRtsRetransmission ())
+ {
+ resetDcf = true;
+ m_stationManager->ReportFinalRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
+ }
+ else
+ {
+ m_stationManager->ReportRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
+ }
+ }
+ else
+ {
+ if (!NeedDataRetransmission ())
+ {
+ resetDcf = true;
+ m_stationManager->ReportFinalDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
+ }
+ else
+ {
+ m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
+ }
+ }
+ if (resetDcf)
+ {
+ NS_LOG_DEBUG ("reset DCF");
+ if (!m_txFailedCallback.IsNull ())
+ {
+ m_txFailedCallback (m_currentHdr);
+ }
+ //to reset the dcf.
+ m_currentPacket = 0;
+ m_dcf->ResetCw ();
+ }
+ else
+ {
+ m_dcf->UpdateFailedCw ();
+ }
+ m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ());
+ m_dcf->StartBackoffNow (m_backoffTrace);
+ RestartAccessIfNeeded ();
}
void
@@ -1046,6 +1090,29 @@
|| !m_queue->IsEmpty () || m_baManager->HasPackets ())
&& !m_dcf->IsAccessRequested ())
{
+ Ptr<const Packet> packet;
+ WifiMacHeader hdr;
+ if (m_currentPacket != 0)
+ {
+ packet = m_currentPacket;
+ hdr = m_currentHdr;
+ }
+ else if (m_baManager->HasPackets ())
+ {
+ packet = m_baManager->PeekNextPacket (hdr);
+ }
+ else if (m_queue->PeekFirstAvailable (&hdr, m_currentPacketTimestamp, m_qosBlockedDestinations) != 0)
+ {
+ packet = m_queue->PeekFirstAvailable (&hdr, m_currentPacketTimestamp, m_qosBlockedDestinations);
+ }
+ if (packet != 0)
+ {
+ m_isAccessRequestedForRts = m_stationManager->NeedRts (hdr.GetAddr1 (), &hdr, packet, m_low->GetDataTxVector (packet, &hdr));
+ }
+ else
+ {
+ m_isAccessRequestedForRts = false;
+ }
m_manager->RequestAccess (m_dcf);
}
}
@@ -1058,6 +1125,29 @@
&& (!m_queue->IsEmpty () || m_baManager->HasPackets ())
&& !m_dcf->IsAccessRequested ())
{
+ Ptr<const Packet> packet;
+ WifiMacHeader hdr;
+ if (m_currentPacket != 0)
+ {
+ packet = m_currentPacket;
+ hdr = m_currentHdr;
+ }
+ else if (m_baManager->HasPackets ())
+ {
+ packet = m_baManager->PeekNextPacket (hdr);
+ }
+ else if (m_queue->PeekFirstAvailable (&hdr, m_currentPacketTimestamp, m_qosBlockedDestinations) != 0)
+ {
+ packet = m_queue->PeekFirstAvailable (&hdr, m_currentPacketTimestamp, m_qosBlockedDestinations);
+ }
+ if (packet != 0)
+ {
+ m_isAccessRequestedForRts = m_stationManager->NeedRts (hdr.GetAddr1 (), &hdr, packet, m_low->GetDataTxVector (packet, &hdr));
+ }
+ else
+ {
+ m_isAccessRequestedForRts = false;
+ }
m_manager->RequestAccess (m_dcf);
}
}
--- a/src/wifi/model/edca-txop-n.h Thu Aug 04 22:43:52 2016 +0200
+++ b/src/wifi/model/edca-txop-n.h Fri Aug 05 22:44:56 2016 +0200
@@ -587,6 +587,7 @@
uint16_t m_blockAckInactivityTimeout;
struct Bar m_currentBar;
Time m_startTxop;
+ bool m_isAccessRequestedForRts;
TracedValue<uint32_t> m_backoffTrace;
TracedValue<uint32_t> m_cwTrace;
};
--- a/src/wifi/model/mac-low.h Thu Aug 04 22:43:52 2016 +0200
+++ b/src/wifi/model/mac-low.h Fri Aug 05 22:44:56 2016 +0200
@@ -833,7 +833,6 @@
*/
void FlushAggregateQueue (void);
-protected:
/**
* Return a TXVECTOR for the DATA frame given the destination.
* The function consults WifiRemoteStationManager, which controls the rate
@@ -844,6 +843,7 @@
* \return TXVECTOR for the given packet
*/
virtual WifiTxVector GetDataTxVector (Ptr<const Packet> packet, const WifiMacHeader *hdr) const;
+
private:
/**
* Cancel all scheduled events. Called before beginning a transmission