--- a/RELEASE_NOTES Mon May 04 23:55:32 2015 +0200
+++ b/RELEASE_NOTES Tue May 05 00:29:40 2015 +0200
@@ -40,6 +40,7 @@
- Bug 2066 - A-MPDU reception should check for successful preamble
- Bug 2070 - Wrong report of Packets and Bytes stored in CoDeL
- Bug 2073 - NDisc cache entries update timer might be stuck in a loop
+- Bug 2075 - A-MPDU using RTS/CTS behaves wrongly when MaxSsrc is reached
- Bug 2076 - TCP MinRTO Attribute is not actually used
- Bug 2077 - Icmpv6L4Protocol::HandleDestinationUnreachable must check the packet size, not its serialized size
- Bug 2079 - mcs variable in ht-wifi-network example is confusing
--- a/src/wifi/model/edca-txop-n.cc Mon May 04 23:55:32 2015 +0200
+++ b/src/wifi/model/edca-txop-n.cc Tue May 05 00:29:40 2015 +0200
@@ -659,9 +659,35 @@
if (GetAmpduExist())
{
m_low->FlushAggregateQueue ();
+
+ NS_LOG_DEBUG ("Transmit Block Ack Request");
+ CtrlBAckRequestHeader reqHdr;
+ reqHdr.SetType (COMPRESSED_BLOCK_ACK);
+ uint8_t tid = m_currentHdr.GetQosTid ();
+ reqHdr.SetStartingSequence (m_txMiddle->PeekNextSequenceNumberfor (&m_currentHdr));
+ reqHdr.SetTidInfo (tid);
+ reqHdr.SetHtImmediateAck(true);
+ Ptr<Packet> bar = Create<Packet> ();
+ bar->AddHeader (reqHdr);
+ Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck());
+ m_currentBar = request;
+ WifiMacHeader hdr;
+ hdr.SetType (WIFI_MAC_CTL_BACKREQ);
+ hdr.SetAddr1 (request.recipient);
+ hdr.SetAddr2 (m_low->GetAddress ());
+ hdr.SetAddr3 (m_low->GetBssid ());
+ hdr.SetDsNotTo ();
+ hdr.SetDsNotFrom ();
+ hdr.SetNoRetry ();
+ hdr.SetNoMoreFragments ();
+ m_currentPacket = request.bar;
+ m_currentHdr = hdr;
+ }
+ else
+ {
+ m_currentPacket = 0;
}
// to reset the dcf.
- m_currentPacket = 0;
m_dcf->ResetCw ();
}
else
--- a/src/wifi/model/mac-low.cc Mon May 04 23:55:32 2015 +0200
+++ b/src/wifi/model/mac-low.cc Tue May 05 00:29:40 2015 +0200
@@ -913,7 +913,8 @@
rxSnr, txMode);
m_stationManager->ReportDataOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
rxSnr, txMode, tag.Get ());
-
+
+ FlushAggregateQueue();
bool gotAck = false;
if (m_txParams.MustWaitNormalAck ()
&& m_normalAckTimeoutEvent.IsRunning ())
@@ -951,6 +952,7 @@
m_listener->GotBlockAck (&blockAck, hdr.GetAddr2 (),txMode);
m_sentMpdus = 0;
m_ampdu = false;
+ FlushAggregateQueue();
}
else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
{
@@ -1576,6 +1578,7 @@
m_listener = 0;
m_sentMpdus = 0;
m_ampdu = false;
+ FlushAggregateQueue();
listener->MissedAck ();
}
void
@@ -1606,6 +1609,7 @@
m_listener = 0;
m_sentMpdus = 0;
m_ampdu = false;
+ FlushAggregateQueue();
listener->MissedBlockAck ();
}
void
@@ -1992,6 +1996,19 @@
NS_ASSERT (m_currentPacket != 0);
WifiTxVector dataTxVector = GetDataTxVector (m_currentPacket, &m_currentHdr);
+ if (m_aggregateQueue->GetSize () != 0)
+ {
+ for(int i = 0; i < m_txPackets.size(); i++)
+ {
+ uint8_t tid = GetTid (m_txPackets.at(i).packet, m_txPackets.at(i).hdr);
+ AcIndex ac = QosUtilsMapTidToAc (tid);
+ std::map<AcIndex, MacLowAggregationCapableTransmissionListener*>::const_iterator listenerIt= m_edcaListeners.find(ac);
+
+ listenerIt->second->CompleteMpduTx (m_txPackets.at(i).packet, m_txPackets.at(i).hdr, m_txPackets.at(i).timestamp);
+ }
+ m_txPackets.clear ();
+ }
+
WifiPreamble preamble;
if (m_phy->GetGreenfield() && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
//In the future has to make sure that receiver has greenfield enabled
@@ -2743,13 +2760,27 @@
m_aggregateQueue->Enqueue (aggPacket, peekedHdr);
if (i == 1 && hdr.IsQosData ())
{
- listenerIt->second->CompleteMpduTx (packet, hdr, tstamp);
+ if (!m_txParams.MustSendRts ())
+ {
+ listenerIt->second->CompleteMpduTx (packet, hdr, tstamp);
+ }
+ else
+ {
+ InsertInTxQueue (packet, hdr, tstamp);
+ }
}
NS_LOG_DEBUG ("Adding packet with Sequence number " << peekedHdr.GetSequenceNumber()<<" to A-MPDU, packet size = " << newPacket->GetSize ()<< ", A-MPDU size = " << currentAggregatedPacket->GetSize ());
i++;
isAmpdu = true;
m_sentMpdus++;
- listenerIt->second->CompleteMpduTx (peekedPacket, peekedHdr, tstamp);
+ if (!m_txParams.MustSendRts ())
+ {
+ listenerIt->second->CompleteMpduTx (peekedPacket, peekedHdr, tstamp);
+ }
+ else
+ {
+ InsertInTxQueue (peekedPacket, peekedHdr, tstamp);
+ }
if (retry)
listenerIt->second->RemoveFromBaQueue(tid, hdr.GetAddr1 (), peekedHdr.GetSequenceNumber ());
else
@@ -2849,6 +2880,19 @@
{
NS_LOG_DEBUG("Flush aggregate queue");
m_aggregateQueue->Flush ();
+ m_txPackets.clear ();
+}
+
+void
+MacLow::InsertInTxQueue (Ptr<const Packet> packet, const WifiMacHeader &hdr, Time tStamp)
+{
+ Item item;
+
+ item.packet = packet;
+ item.hdr = hdr;
+ item.timestamp = tStamp;
+
+ m_txPackets.push_back (item);
}
Ptr<Packet>
--- a/src/wifi/model/mac-low.h Mon May 04 23:55:32 2015 +0200
+++ b/src/wifi/model/mac-low.h Tue May 05 00:29:40 2015 +0200
@@ -1256,6 +1256,11 @@
*/
bool IsAmpdu (Ptr<const Packet> packet, const WifiMacHeader hdr);
/**
+ * Insert in a temporary queue.
+ * It is only used with a RTS/CTS exchange for an A-MPDU transmission.
+ */
+ void InsertInTxQueue (Ptr<const Packet> packet, const WifiMacHeader &hdr, Time tStamp);
+ /**
* Perform MSDU aggregation for a given MPDU in an A-MPDU
*
* \param packet packet picked for aggregation
@@ -1272,6 +1277,17 @@
Ptr<WifiPhy> m_phy; //!< Pointer to WifiPhy (actually send/receives frames)
Ptr<WifiRemoteStationManager> m_stationManager; //!< Pointer to WifiRemoteStationManager (rate control)
MacLowRxCallback m_rxCallback; //!< Callback to pass packet up
+
+ /**
+ * A struct for packet, Wifi header, and timestamp.
+ */
+ typedef struct
+ {
+ Ptr<const Packet> packet;
+ WifiMacHeader hdr;
+ Time timestamp;
+ } Item;
+
/**
* typedef for an iterator for a list of MacLowDcfListener.
*/
@@ -1346,6 +1362,7 @@
Ptr<WifiMacQueue> m_aggregateQueue; //!< Queue used for MPDU aggregation
WifiMode m_currentMode; //!< mode used for the current packet transmission
bool m_receivedAtLeastOneMpdu; //!< Flag whether an MPDU has already been successfully received while receiving an A-MPDU
+ std::vector<Item> m_txPackets; //!< Contain temporary items to be sent with the next A-MPDU transmission, once RTS/CTS exchange has succeeded. It is not used in other cases.
};
} // namespace ns3