diff --git a/src/wifi/model/msdu-aggregator.cc b/src/wifi/model/msdu-aggregator.cc index b9edc904d..9743d4389 100644 --- a/src/wifi/model/msdu-aggregator.cc +++ b/src/wifi/model/msdu-aggregator.cc @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Mirko Banchi + * Stefano Avallone */ #include "ns3/log.h" @@ -144,34 +145,6 @@ MsduAggregator::GetNextAmsdu (Mac48Address recipient, uint8_t tid, return 0; } - // Get the maximum size of the A-MPDU we can send to the recipient - uint32_t maxAmpduSize = 0; - Ptr mpduAggregator = qosTxop->GetLow ()->GetMpduAggregator (); - - if (mpduAggregator) - { - maxAmpduSize = mpduAggregator->GetMaxAmpduSize (recipient, tid, modulation); - } - - // If maxAmpduSize is 0, then the ampdu must be empty - NS_ASSERT (maxAmpduSize > 0 || ampduSize == 0); - - // Get the maximum PPDU Duration based on the preamble type. It must be a - // non null value because aggregation is available for HT, VHT and HE, which - // also provide a limit on the maximum PPDU duration - Time maxPpduDuration = GetPpduMaxTime (txVector.GetPreambleType ()); - NS_ASSERT (maxPpduDuration.IsStrictlyPositive ()); - - // the limit on the PPDU duration is the minimum between the maximum PPDU - // duration (depending on the PPDU format) and the additional limit provided - // by the caller (if non-zero) - if (ppduDurationLimit.IsStrictlyPositive ()) - { - maxPpduDuration = std::min (maxPpduDuration, ppduDurationLimit); - } - - Ptr phy = qosTxop->GetLow ()->GetPhy (); - NS_ASSERT (phy); Ptr amsdu = Create (); uint8_t nMsdu = 0; WifiMacHeader header = peekedItem->GetHeader (); @@ -196,35 +169,11 @@ MsduAggregator::GetNextAmsdu (Mac48Address recipient, uint8_t tid, } // check if the A-MSDU obtained by aggregating the peeked MSDU violates - // the A-MPDU size limit and compute the PPDU payload size - uint32_t ppduPayloadSize; - - if (maxAmpduSize > 0) // A-MPDU aggregation enabled + // the A-MPDU size limit or the PPDU duration limit + if (!qosTxop->IsWithinSizeAndTimeLimits (header.GetSize () + newAmsduSize + WIFI_MAC_FCS_LENGTH, + recipient, tid, txVector, ampduSize, ppduDurationLimit)) { - ppduPayloadSize = mpduAggregator->GetSizeIfAggregated (header.GetSize () + newAmsduSize - + WIFI_MAC_FCS_LENGTH, ampduSize); - - if (ppduPayloadSize > maxAmpduSize) - { - NS_LOG_DEBUG ("No other MSDU can be aggregated: maximum A-MPDU size exceeded"); - break; - } - } - else if (modulation == WIFI_MOD_CLASS_HE || modulation == WIFI_MOD_CLASS_VHT) - { - // VHT and HE frames always use A-MPDU structure, thus take the size - // of the MPDU Delimiter (4 bytes) into account - ppduPayloadSize = 4 + header.GetSize () + newAmsduSize + WIFI_MAC_FCS_LENGTH; - } - else - { - ppduPayloadSize = header.GetSize () + newAmsduSize + WIFI_MAC_FCS_LENGTH; - } - - // check if the PPDU duration limit is exceeded - if (phy->CalculateTxDuration (ppduPayloadSize, txVector, phy->GetFrequency ()) > maxPpduDuration) - { - NS_LOG_DEBUG ("No other MSDU can be aggregated: maximum duration reached"); + NS_LOG_DEBUG ("No other MSDU can be aggregated"); break; } diff --git a/src/wifi/model/qos-txop.cc b/src/wifi/model/qos-txop.cc index f37886d6c..a47464229 100644 --- a/src/wifi/model/qos-txop.cc +++ b/src/wifi/model/qos-txop.cc @@ -405,80 +405,45 @@ QosTxop::NotifyAccessGranted (void) m_startTxop = Simulator::Now (); if (m_currentPacket == 0) { - if (m_queue->IsEmpty () && !m_baManager->HasPackets ()) - { - NS_LOG_DEBUG ("queue is empty"); - return; - } if (m_baManager->HasBar (m_currentBar)) { SendBlockAckRequest (m_currentBar); return; } - /* check if packets need retransmission are stored in BlockAckManager */ - Ptr item = m_baManager->GetNextPacket (true); - if (item != 0) + Ptr peekedItem = PeekNextFrame (); + if (peekedItem == 0) { - m_currentPacket = item->GetPacket (); - m_currentHdr = item->GetHeader (); - m_currentPacketTimestamp = item->GetTimeStamp (); + NS_LOG_DEBUG ("no packets available for transmission"); + return; } - else + // check if a Block Ack agreement needs to be established + m_currentHdr = peekedItem->GetHeader (); + m_currentPacket = peekedItem->GetPacket (); + if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast () + && m_stationManager->GetQosSupported (m_currentHdr.GetAddr1 ()) + && (!m_baManager->ExistsAgreement (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ()) + || m_baManager->ExistsAgreementInState (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid (), OriginatorBlockAckAgreement::RESET)) + && SetupBlockAckIfNeeded ()) { - item = m_queue->PeekFirstAvailable (m_qosBlockedDestinations); - if (item == 0) - { - NS_LOG_DEBUG ("no available packets in the queue"); - return; - } - m_currentHdr = item->GetHeader (); - m_currentPacket = item->GetPacket (); - m_currentPacketTimestamp = item->GetTimeStamp (); - if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast () - && m_stationManager->GetQosSupported (m_currentHdr.GetAddr1 ()) - && (!m_baManager->ExistsAgreement (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ()) - || m_baManager->ExistsAgreementInState (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid (), OriginatorBlockAckAgreement::RESET)) - && SetupBlockAckIfNeeded ()) - { - return; - } - // Try A-MSDU aggregation - WifiTxVector txVector = m_low->GetDataTxVector (item->GetPacket (), &item->GetHeader ()); - item = 0; - if (m_low->GetMsduAggregator () != 0 && m_currentHdr.IsQosData () - && !m_currentHdr.GetAddr1 ().IsBroadcast () && !NeedFragmentation ()) - { - item = m_low->GetMsduAggregator ()->GetNextAmsdu (m_currentHdr.GetAddr1 (), - m_currentHdr.GetQosTid (), txVector); - } - if (item != 0) - { - NS_LOG_DEBUG ("tx unicast A-MSDU"); - } - else // dequeue the packet if aggregation was not attempted or failed - { - item = m_queue->DequeueFirstAvailable (m_qosBlockedDestinations); - } - NS_ASSERT (item != 0); - m_currentPacket = item->GetPacket (); - m_currentHdr = item->GetHeader (); - m_currentPacketTimestamp = item->GetTimeStamp (); - NS_ASSERT (m_currentPacket != 0); + return; + } - uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&m_currentHdr); - m_currentHdr.SetSequenceNumber (sequence); - m_stationManager->UpdateFragmentationThreshold (); - m_currentHdr.SetFragmentNumber (0); - m_currentHdr.SetNoMoreFragments (); - m_currentHdr.SetNoRetry (); - m_fragmentNumber = 0; - NS_LOG_DEBUG ("dequeued size=" << m_currentPacket->GetSize () << - ", to=" << m_currentHdr.GetAddr1 () << - ", seq=" << m_currentHdr.GetSequenceControl ()); - if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast ()) - { - VerifyBlockAck (); - } + m_stationManager->UpdateFragmentationThreshold (); + // dequeue the peeked item. Disable aggregation if fragmentation is needed + Ptr item = DequeuePeekedFrame (peekedItem, + m_low->GetDataTxVector (peekedItem->GetPacket (), &peekedItem->GetHeader ()), + !NeedFragmentation ()); + + NS_ASSERT (item != 0); + m_currentPacket = item->GetPacket (); + m_currentHdr = item->GetHeader (); + m_currentPacketTimestamp = item->GetTimeStamp (); + NS_ASSERT (m_currentPacket != 0); + + m_fragmentNumber = 0; + if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast ()) + { + VerifyBlockAck (); } } if (m_currentHdr.GetAddr1 ().IsGroup ()) @@ -548,15 +513,7 @@ void QosTxop::NotifyInternalCollision (void) WifiMacHeader header; if (m_currentPacket == 0) { - Ptr item; - if (m_baManager->HasPackets ()) - { - item = m_baManager->GetNextPacket (false); - } - else - { - item = m_queue->Peek (); - } + Ptr item = PeekNextFrame (); if (item) { packet = item->GetPacket (); @@ -1030,18 +987,9 @@ QosTxop::RestartAccessIfNeeded (void) packet = m_currentPacket; hdr = m_currentHdr; } - else if (m_baManager->HasPackets ()) - { - Ptr item = m_baManager->GetNextPacket (false); - if (item) - { - packet = item->GetPacket (); - hdr = item->GetHeader (); - } - } else { - Ptr item = m_queue->PeekFirstAvailable (m_qosBlockedDestinations); + Ptr item = PeekNextFrame (); if (item) { packet = item->GetPacket (); @@ -1070,25 +1018,11 @@ QosTxop::StartAccessIfNeeded (void) { Ptr packet; WifiMacHeader hdr; - if (m_baManager->HasPackets ()) + Ptr item = PeekNextFrame (); + if (item) { - Ptr item = m_baManager->GetNextPacket (false); - if (item) - { - packet = item->GetPacket (); - hdr = item->GetHeader (); - m_currentPacketTimestamp = item->GetTimeStamp (); - } - } - else - { - Ptr item = m_queue->PeekFirstAvailable (m_qosBlockedDestinations); - if (item) - { - packet = item->GetPacket (); - hdr = item->GetHeader (); - m_currentPacketTimestamp = item->GetTimeStamp (); - } + packet = item->GetPacket (); + hdr = item->GetHeader (); } if (packet != 0) { @@ -1137,21 +1071,12 @@ QosTxop::StartNextPacket (void) NS_ASSERT (txopLimit.IsZero () || Simulator::Now () - m_startTxop <= txopLimit); WifiMacHeader hdr = m_currentHdr; Ptr peekedPacket; - Ptr peekedItem = m_baManager->GetNextPacket (true); + Ptr peekedItem = PeekNextFrame (); if (peekedItem) { peekedPacket = peekedItem->GetPacket (); hdr = peekedItem->GetHeader (); } - else - { - peekedItem = m_queue->PeekByTidAndAddress (m_currentHdr.GetQosTid (), m_currentHdr.GetAddr1 ()); - if (peekedItem) - { - peekedPacket = peekedItem->GetPacket (); - hdr = peekedItem->GetHeader (); - } - } if ((m_currentHdr.IsQosBlockAck () && peekedPacket == 0) || m_baManager->HasBar (m_currentBar)) { SendBlockAckRequest (m_currentBar); @@ -1175,21 +1100,33 @@ QosTxop::StartNextPacket (void) { m_currentParams.EnableAck (); } - if (txopLimit >= GetLow ()->CalculateOverallTxTime (peekedPacket, &hdr, m_currentParams)) + if (m_stationManager->NeedRts (hdr.GetAddr1 (), &hdr, peekedPacket, m_low->GetDataTxVector (peekedPacket, &hdr))) { + m_currentParams.EnableRts (); + } + else + { + m_currentParams.DisableRts (); + } + if (GetTxopRemaining () >= GetLow ()->CalculateOverallTxTime (peekedPacket, &hdr, m_currentParams)) + { + // when dequeuing the peeked packet, A-MSDU aggregation is attempted if the + // packet has been peeked from the EDCA queue. Thus, compute the max available + // time for the transmission of the PPDU + Time maxPpduDuration = GetTxopRemaining () - m_low->CalculateOverheadTxTime (peekedPacket, &hdr, m_currentParams); + + Ptr item = DequeuePeekedFrame (peekedItem, m_low->GetDataTxVector (peekedPacket, &hdr), + true, 0, maxPpduDuration); + if (item == 0) + { + m_txopTrace (m_startTxop, Simulator::Now () - m_startTxop); + return; + } NS_LOG_DEBUG ("start next packet"); - Ptr item = m_queue->DequeueByTidAndAddress (m_currentHdr.GetQosTid (), - m_currentHdr.GetAddr1 ()); - NS_ASSERT (item != 0); m_currentPacket = item->GetPacket (); m_currentHdr = item->GetHeader (); NS_ASSERT (m_currentPacket != 0); - uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&m_currentHdr); - m_currentHdr.SetSequenceNumber (sequence); m_stationManager->UpdateFragmentationThreshold (); - m_currentHdr.SetFragmentNumber (0); - m_currentHdr.SetNoMoreFragments (); - m_currentHdr.SetNoRetry (); m_fragmentNumber = 0; VerifyBlockAck (); GetLow ()->StartTransmission (m_currentPacket, &m_currentHdr, m_currentParams, this);