From d0ec938b4242061721db44c719195f632f6eb727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deronne?= Date: Tue, 5 May 2015 00:29:40 +0200 Subject: [PATCH] Bug 2075 [wifi] - A-MPDU using RTS/CTS behaves wrongly when MaxSsrc is reached --- RELEASE_NOTES | 1 + src/wifi/model/edca-txop-n.cc | 28 +++++++++++++++++++- src/wifi/model/mac-low.cc | 50 ++++++++++++++++++++++++++++++++--- src/wifi/model/mac-low.h | 17 ++++++++++++ 4 files changed, 92 insertions(+), 4 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index e62b7672a..31d76cc4f 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -40,6 +40,7 @@ Bugs fixed - 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 diff --git a/src/wifi/model/edca-txop-n.cc b/src/wifi/model/edca-txop-n.cc index ad1faa708..1f5f32810 100644 --- a/src/wifi/model/edca-txop-n.cc +++ b/src/wifi/model/edca-txop-n.cc @@ -659,9 +659,35 @@ EdcaTxopN::MissedCts (void) 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 bar = Create (); + 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 diff --git a/src/wifi/model/mac-low.cc b/src/wifi/model/mac-low.cc index 869b455cd..124f0c3b7 100644 --- a/src/wifi/model/mac-low.cc +++ b/src/wifi/model/mac-low.cc @@ -913,7 +913,8 @@ MacLow::ReceiveOk (Ptr packet, double rxSnr, WifiMode txMode, WifiPreamb 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 @@ MacLow::ReceiveOk (Ptr packet, double rxSnr, WifiMode txMode, WifiPreamb 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 @@ MacLow::NormalAckTimeout (void) m_listener = 0; m_sentMpdus = 0; m_ampdu = false; + FlushAggregateQueue(); listener->MissedAck (); } void @@ -1606,6 +1609,7 @@ MacLow::BlockAckTimeout (void) m_listener = 0; m_sentMpdus = 0; m_ampdu = false; + FlushAggregateQueue(); listener->MissedBlockAck (); } void @@ -1992,6 +1996,19 @@ MacLow::SendDataAfterCts (Mac48Address source, Time duration, WifiMode txMode) 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::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 @@ MacLow::AggregateToAmpdu (Ptr packet, const WifiMacHeader hdr) 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 @@ MacLow::FlushAggregateQueue (void) { NS_LOG_DEBUG("Flush aggregate queue"); m_aggregateQueue->Flush (); + m_txPackets.clear (); +} + +void +MacLow::InsertInTxQueue (Ptr packet, const WifiMacHeader &hdr, Time tStamp) +{ + Item item; + + item.packet = packet; + item.hdr = hdr; + item.timestamp = tStamp; + + m_txPackets.push_back (item); } Ptr diff --git a/src/wifi/model/mac-low.h b/src/wifi/model/mac-low.h index 32de735cf..6d780a8e7 100644 --- a/src/wifi/model/mac-low.h +++ b/src/wifi/model/mac-low.h @@ -1255,6 +1255,11 @@ private: * */ bool IsAmpdu (Ptr 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 packet, const WifiMacHeader &hdr, Time tStamp); /** * Perform MSDU aggregation for a given MPDU in an A-MPDU * @@ -1272,6 +1277,17 @@ private: Ptr m_phy; //!< Pointer to WifiPhy (actually send/receives frames) Ptr 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 packet; + WifiMacHeader hdr; + Time timestamp; + } Item; + /** * typedef for an iterator for a list of MacLowDcfListener. */ @@ -1346,6 +1362,7 @@ private: Ptr 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 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