wifi: Add a new GetNextAmsdu method to MsduAggregator
which does not dequeue MSDUs.
This commit is contained in:
@@ -23,15 +23,14 @@
|
||||
#include "ns3/packet.h"
|
||||
#include "msdu-aggregator.h"
|
||||
#include "qos-txop.h"
|
||||
#include "mpdu-aggregator.h"
|
||||
#include "wifi-remote-station-manager.h"
|
||||
#include "mac-low.h"
|
||||
#include "wifi-phy.h"
|
||||
#include "wifi-net-device.h"
|
||||
#include "ht-capabilities.h"
|
||||
#include "regular-wifi-mac.h"
|
||||
#include "wifi-mac-queue.h"
|
||||
#include "wifi-mac-trailer.h"
|
||||
#include "ht-frame-exchange-manager.h"
|
||||
#include "wifi-tx-parameters.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace ns3 {
|
||||
@@ -63,6 +62,7 @@ void
|
||||
MsduAggregator::DoDispose ()
|
||||
{
|
||||
m_mac = 0;
|
||||
m_htFem = 0;
|
||||
Object::DoDispose ();
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ MsduAggregator::SetWifiMac (const Ptr<RegularWifiMac> mac)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << mac);
|
||||
m_mac = mac;
|
||||
m_htFem = DynamicCast<HtFrameExchangeManager> (m_mac->GetFrameExchangeManager ());
|
||||
}
|
||||
|
||||
uint16_t
|
||||
@@ -184,6 +185,69 @@ MsduAggregator::GetNextAmsdu (Mac48Address recipient, uint8_t tid,
|
||||
return amsdu;
|
||||
}
|
||||
|
||||
Ptr<WifiMacQueueItem>
|
||||
MsduAggregator::GetNextAmsdu (Ptr<const WifiMacQueueItem> peekedItem, WifiTxParameters& txParams,
|
||||
Time availableTime, WifiMacQueueItem::QueueIteratorPair& queueIt) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *peekedItem << &txParams << availableTime);
|
||||
|
||||
NS_ASSERT (peekedItem->IsQueued ());
|
||||
NS_ASSERT (peekedItem->GetQueueIteratorPairs ().size () == 1);
|
||||
WifiMacQueueItem::QueueIteratorPair peekedIt = peekedItem->GetQueueIteratorPairs ().front ();
|
||||
NS_ASSERT ((*peekedIt.it)->GetPacket () == peekedItem->GetPacket ());
|
||||
|
||||
uint8_t tid = peekedItem->GetHeader ().GetQosTid ();
|
||||
Mac48Address recipient = peekedItem->GetHeader ().GetAddr1 ();
|
||||
|
||||
/* "The Address 1 field of an MPDU carrying an A-MSDU shall be set to an
|
||||
* individual address or to the GCR concealment address" (Section 10.12
|
||||
* of 802.11-2016)
|
||||
*/
|
||||
NS_ABORT_MSG_IF (recipient.IsBroadcast (), "Recipient address is broadcast");
|
||||
|
||||
/* "A STA shall not transmit an A-MSDU within a QoS Data frame under a block
|
||||
* ack agreement unless the recipient indicates support for A-MSDU by setting
|
||||
* the A-MSDU Supported field to 1 in its BlockAck Parameter Set field of the
|
||||
* ADDBA Response frame" (Section 10.12 of 802.11-2016)
|
||||
*/
|
||||
// No check required for now, as we always set the A-MSDU Supported field to 1
|
||||
|
||||
// TODO Add support for the Max Number Of MSDUs In A-MSDU field in the Extended
|
||||
// Capabilities element sent by the recipient
|
||||
|
||||
NS_ASSERT (m_htFem != 0);
|
||||
|
||||
if (GetMaxAmsduSize (recipient, tid, txParams.m_txVector.GetModulationClass ()) == 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("A-MSDU aggregation disabled");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Ptr<WifiMacQueueItem> amsdu = Copy (peekedItem);
|
||||
uint8_t nMsdu = 1;
|
||||
|
||||
peekedIt.it++;
|
||||
|
||||
while ((peekedIt.it = peekedIt.queue->PeekByTidAndAddress (tid, recipient, peekedIt.it)) != peekedIt.queue->end ()
|
||||
&& m_htFem->TryAggregateMsdu (*peekedIt.it, txParams, availableTime))
|
||||
{
|
||||
amsdu->Aggregate (*peekedIt.it);
|
||||
peekedIt.it++;
|
||||
nMsdu++;
|
||||
}
|
||||
|
||||
if (nMsdu == 1)
|
||||
{
|
||||
NS_LOG_DEBUG ("Aggregation failed (could not aggregate at least two MSDUs)");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Aggregation succeeded
|
||||
queueIt = peekedIt;
|
||||
|
||||
return amsdu;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
MsduAggregator::CalculatePadding (uint16_t amsduSize)
|
||||
{
|
||||
|
||||
@@ -34,6 +34,8 @@ class Packet;
|
||||
class QosTxop;
|
||||
class WifiTxVector;
|
||||
class RegularWifiMac;
|
||||
class HtFrameExchangeManager;
|
||||
class WifiTxParameters;
|
||||
|
||||
/**
|
||||
* \brief Aggregator used to construct A-MSDUs
|
||||
@@ -98,6 +100,40 @@ public:
|
||||
WifiTxVector txVector, uint32_t ampduSize = 0,
|
||||
Time ppduDurationLimit = Time::Min ()) const;
|
||||
|
||||
/**
|
||||
* Attempt to aggregate other MSDUs to the given A-MSDU while meeting the
|
||||
* following constraints:
|
||||
*
|
||||
* - the A-MSDU size does not exceed the maximum A-MSDU size as determined for
|
||||
* the modulation class indicated by the given TxVector
|
||||
*
|
||||
* - the size of the A-MPDU resulting from the aggregation of the MPDU in which
|
||||
* the A-MSDU will be embedded and the current A-MPDU (as specified by the given
|
||||
* TX parameters) does not exceed the maximum A-MPDU size as determined for
|
||||
* the modulation class indicated by the given TxVector
|
||||
*
|
||||
* - the time to transmit the resulting PPDU, according to the given TxVector,
|
||||
* does not exceed the maximum PPDU duration allowed by the corresponding
|
||||
* modulation class (if any)
|
||||
*
|
||||
* - the time to transmit the resulting PPDU and to carry out protection and
|
||||
* acknowledgment, as specified by the given TX parameters, does not exceed the
|
||||
* given available time (if distinct from Time::Min ())
|
||||
*
|
||||
* If it is not possible to aggregate at least two MSDUs, no MSDU is dequeued
|
||||
* from the EDCA queue and a null pointer is returned.
|
||||
*
|
||||
* \param peekedItem the MSDU which we attempt to aggregate other MSDUs to
|
||||
* \param txParams the TX parameters for the current frame
|
||||
* \param availableTime the time available for the frame exchange
|
||||
* \param[out] queueIt a QueueIteratorPair pointing to the queue item following the
|
||||
* last item used to prepare the returned A-MSDU, if any; otherwise,
|
||||
* its value is unchanged
|
||||
* \return the resulting A-MSDU, if aggregation is possible, a null pointer otherwise.
|
||||
*/
|
||||
Ptr<WifiMacQueueItem> GetNextAmsdu (Ptr<const WifiMacQueueItem> peekedItem, WifiTxParameters& txParams,
|
||||
Time availableTime, WifiMacQueueItem::QueueIteratorPair& queueIt) const;
|
||||
|
||||
/**
|
||||
* Determine the maximum size for an A-MSDU of the given TID that can be sent
|
||||
* to the given receiver when using the given modulation class.
|
||||
@@ -139,7 +175,8 @@ protected:
|
||||
virtual void DoDispose ();
|
||||
|
||||
private:
|
||||
Ptr<RegularWifiMac> m_mac; //!< the MAC of this station
|
||||
Ptr<RegularWifiMac> m_mac; //!< the MAC of this station
|
||||
Ptr<HtFrameExchangeManager> m_htFem; //!< the HT Frame Exchange Manager of this station
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include "wifi-phy.h"
|
||||
#include "wifi-ack-policy-selector.h"
|
||||
#include "wifi-psdu.h"
|
||||
#include "qos-frame-exchange-manager.h"
|
||||
#include "ht-frame-exchange-manager.h"
|
||||
#include "wifi-tx-parameters.h"
|
||||
|
||||
#undef NS_LOG_APPEND_CONTEXT
|
||||
@@ -593,8 +593,40 @@ QosTxop::GetNextMpdu (Ptr<const WifiMacQueueItem> peekedItem, WifiTxParameters&
|
||||
NS_ASSERT (peekedIt.queue == PeekPointer (m_queue));
|
||||
Ptr<WifiMacQueueItem> mpdu;
|
||||
|
||||
mpdu = *peekedIt.it;
|
||||
peekedIt.it++;
|
||||
// If it is a non-broadcast QoS Data frame and it is not a retransmission nor a fragment,
|
||||
// attempt A-MSDU aggregation
|
||||
if (peekedItem->GetHeader ().IsQosData ())
|
||||
{
|
||||
uint8_t tid = peekedItem->GetHeader ().GetQosTid ();
|
||||
|
||||
// we should not be asked to dequeue an MPDU that is beyond the transmit window.
|
||||
// Note that PeekNextMpdu() temporarily assigns the next available sequence number
|
||||
// to the peeked frame
|
||||
NS_ASSERT (!GetBaAgreementEstablished (recipient, tid)
|
||||
|| IsInWindow (peekedItem->GetHeader ().GetSequenceNumber (),
|
||||
GetBaStartingSequence (recipient, tid),
|
||||
GetBaBufferSize (recipient, tid)));
|
||||
|
||||
// try A-MSDU aggregation
|
||||
if (m_stationManager->GetHtSupported () && !recipient.IsBroadcast ()
|
||||
&& !peekedItem->GetHeader ().IsRetry () && !peekedItem->IsFragment ())
|
||||
{
|
||||
Ptr<HtFrameExchangeManager> htFem = StaticCast<HtFrameExchangeManager> (m_qosFem);
|
||||
mpdu = htFem->GetMsduAggregator ()->GetNextAmsdu (peekedItem, txParams, availableTime, peekedIt);
|
||||
}
|
||||
|
||||
if (mpdu != 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("Prepared an MPDU containing an A-MSDU");
|
||||
}
|
||||
// else aggregation was not attempted or failed
|
||||
}
|
||||
|
||||
if (mpdu == 0)
|
||||
{
|
||||
mpdu = *peekedIt.it;
|
||||
peekedIt.it++;
|
||||
}
|
||||
|
||||
// Assign a sequence number if this is not a fragment nor a retransmission
|
||||
AssignSequenceNumber (mpdu);
|
||||
|
||||
Reference in New Issue
Block a user