diff -r c175b2ae730c src/wifi/model/edca-txop-n.cc --- a/src/wifi/model/edca-txop-n.cc Wed Mar 11 16:50:35 2015 +0100 +++ b/src/wifi/model/edca-txop-n.cc Fri Mar 13 15:44:18 2015 +0100 @@ -646,9 +646,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 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 -r c175b2ae730c src/wifi/model/mac-low.cc --- a/src/wifi/model/mac-low.cc Wed Mar 11 16:50:35 2015 +0100 +++ b/src/wifi/model/mac-low.cc Fri Mar 13 15:44:18 2015 +0100 @@ -1976,6 +1976,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::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 @@ -2719,13 +2732,27 @@ m_aggregateQueue->Enqueue (aggPacket, peekedHdr); if (i == 1 && hdr.IsQosData ()) { + 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"); 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 @@ -2811,6 +2838,19 @@ { 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); } } // namespace ns3 diff -r c175b2ae730c src/wifi/model/mac-low.h --- a/src/wifi/model/mac-low.h Wed Mar 11 16:50:35 2015 +0100 +++ b/src/wifi/model/mac-low.h Fri Mar 13 15:44:18 2015 +0100 @@ -1242,10 +1242,26 @@ * */ 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); 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. */ @@ -1320,6 +1336,7 @@ 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