wifi: WifiMacQueueItem keeps MSDUs separate in case of A-MSDU
This commit is contained in:
@@ -75,36 +75,6 @@ MsduAggregator::GetSizeIfAggregated (uint16_t msduSize, uint16_t amsduSize)
|
||||
return amsduSize + CalculatePadding (amsduSize) + 14 + msduSize;
|
||||
}
|
||||
|
||||
void
|
||||
MsduAggregator::Aggregate (Ptr<const Packet> msdu, Ptr<Packet> amsdu,
|
||||
Mac48Address src, Mac48Address dest) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_ASSERT (amsdu);
|
||||
|
||||
// pad the previous A-MSDU subframe if the A-MSDU is not empty
|
||||
if (amsdu->GetSize () > 0)
|
||||
{
|
||||
uint8_t padding = CalculatePadding (amsdu->GetSize ());
|
||||
|
||||
if (padding)
|
||||
{
|
||||
Ptr<Packet> pad = Create<Packet> (padding);
|
||||
amsdu->AddAtEnd (pad);
|
||||
}
|
||||
}
|
||||
|
||||
// add A-MSDU subframe header and MSDU
|
||||
AmsduSubframeHeader hdr;
|
||||
hdr.SetDestinationAddr (dest);
|
||||
hdr.SetSourceAddr (src);
|
||||
hdr.SetLength (static_cast<uint16_t> (msdu->GetSize ()));
|
||||
|
||||
Ptr<Packet> tmp = msdu->Copy ();
|
||||
tmp->AddHeader (hdr);
|
||||
amsdu->AddAtEnd (tmp);
|
||||
}
|
||||
|
||||
Ptr<WifiMacQueueItem>
|
||||
MsduAggregator::GetNextAmsdu (Mac48Address recipient, uint8_t tid,
|
||||
WifiTxVector txVector, uint32_t ampduSize,
|
||||
@@ -145,10 +115,8 @@ MsduAggregator::GetNextAmsdu (Mac48Address recipient, uint8_t tid,
|
||||
return 0;
|
||||
}
|
||||
|
||||
Ptr<Packet> amsdu = Create<Packet> ();
|
||||
Ptr<WifiMacQueueItem> amsdu = Create<WifiMacQueueItem> (Create<const Packet> (), (*peekedIt)->GetHeader ());
|
||||
uint8_t nMsdu = 0;
|
||||
WifiMacHeader header = (*peekedIt)->GetHeader ();
|
||||
Time tstamp = (*peekedIt)->GetTimeStamp ();
|
||||
// We need to keep track of the first MSDU. When it is processed, it is not known
|
||||
// if aggregation will succeed or not.
|
||||
WifiMacQueue::ConstIterator first = peekedIt;
|
||||
@@ -160,7 +128,7 @@ MsduAggregator::GetNextAmsdu (Mac48Address recipient, uint8_t tid,
|
||||
{
|
||||
// check if aggregating the peeked MSDU violates the A-MSDU size limit
|
||||
uint16_t newAmsduSize = GetSizeIfAggregated ((*peekedIt)->GetPacket ()->GetSize (),
|
||||
amsdu->GetSize ());
|
||||
amsdu->GetPacket ()->GetSize ());
|
||||
|
||||
if (newAmsduSize > maxAmsduSize)
|
||||
{
|
||||
@@ -170,33 +138,25 @@ MsduAggregator::GetNextAmsdu (Mac48Address recipient, uint8_t tid,
|
||||
|
||||
// check if the A-MSDU obtained by aggregating the peeked MSDU violates
|
||||
// the A-MPDU size limit or the PPDU duration limit
|
||||
if (!qosTxop->GetLow ()->IsWithinSizeAndTimeLimits (header.GetSize () + newAmsduSize + WIFI_MAC_FCS_LENGTH,
|
||||
if (!qosTxop->GetLow ()->IsWithinSizeAndTimeLimits (amsdu->GetHeader ().GetSize () + newAmsduSize
|
||||
+ WIFI_MAC_FCS_LENGTH,
|
||||
recipient, tid, txVector, ampduSize, ppduDurationLimit))
|
||||
{
|
||||
NS_LOG_DEBUG ("No other MSDU can be aggregated");
|
||||
break;
|
||||
}
|
||||
|
||||
// We can now safely aggregate the MSDU to the A-MSDU
|
||||
Aggregate ((*peekedIt)->GetPacket (), amsdu,
|
||||
qosTxop->MapSrcAddressForAggregation (header),
|
||||
qosTxop->MapDestAddressForAggregation (header));
|
||||
|
||||
/* "The expiration of the A-MSDU lifetime timer occurs only when the lifetime
|
||||
* timer of all of the constituent MSDUs of the A-MSDU have expired" (Section
|
||||
* 10.12 of 802.11-2016)
|
||||
*/
|
||||
// The timestamp of the A-MSDU is the most recent among those of the MSDUs
|
||||
tstamp = Max (tstamp, (*peekedIt)->GetTimeStamp ());
|
||||
|
||||
// The MSDU can be aggregated to the A-MSDU.
|
||||
// If it is the first MSDU, move to the next one
|
||||
if (nMsdu == 0)
|
||||
{
|
||||
amsdu = Copy (*peekedIt);
|
||||
peekedIt++;
|
||||
}
|
||||
// otherwise, remove it from the queue
|
||||
else
|
||||
{
|
||||
amsdu->Aggregate (*peekedIt);
|
||||
peekedIt = queue->Remove (peekedIt);
|
||||
}
|
||||
|
||||
@@ -214,10 +174,7 @@ MsduAggregator::GetNextAmsdu (Mac48Address recipient, uint8_t tid,
|
||||
// Aggregation succeeded, we have to remove the first MSDU
|
||||
queue->Remove (first);
|
||||
|
||||
header.SetQosAmsdu ();
|
||||
header.SetAddr3 (qosTxop->GetLow ()->GetBssid ());
|
||||
|
||||
return Create<WifiMacQueueItem> (amsdu, header, tstamp);
|
||||
return amsdu;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "ns3/nstime.h"
|
||||
#include "wifi-mode.h"
|
||||
#include "qos-utils.h"
|
||||
#include <map>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -57,17 +58,6 @@ public:
|
||||
MsduAggregator ();
|
||||
virtual ~MsduAggregator ();
|
||||
|
||||
/**
|
||||
* Aggregate an MSDU to an A-MSDU.
|
||||
*
|
||||
* \param msdu the MSDU.
|
||||
* \param amsdu the A-MSDU.
|
||||
* \param src the source address.
|
||||
* \param dest the destination address
|
||||
*/
|
||||
void Aggregate (Ptr<const Packet> msdu, Ptr<Packet> amsdu,
|
||||
Mac48Address src, Mac48Address dest) const;
|
||||
|
||||
/**
|
||||
* Compute the size of the A-MSDU resulting from the aggregation of an MSDU of
|
||||
* size <i>msduSize</i> and an A-MSDU of size <i>amsduSize</i>.
|
||||
@@ -137,7 +127,6 @@ public:
|
||||
*/
|
||||
void SetEdcaQueues (EdcaQueues map);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Calculate how much padding must be added to the end of an A-MSDU of the
|
||||
* given size if a new MSDU is added.
|
||||
@@ -149,6 +138,7 @@ private:
|
||||
*/
|
||||
static uint8_t CalculatePadding (uint16_t amsduSize);
|
||||
|
||||
private:
|
||||
EdcaQueues m_edca; //!< the map of EDCA queues
|
||||
};
|
||||
|
||||
|
||||
@@ -41,6 +41,10 @@ WifiMacQueueItem::WifiMacQueueItem (Ptr<const Packet> p, const WifiMacHeader & h
|
||||
m_header (header),
|
||||
m_tstamp (tstamp)
|
||||
{
|
||||
if (header.IsQosData () && header.IsQosAmsdu ())
|
||||
{
|
||||
m_msduList = MsduAggregator::Deaggregate (p->Copy ());
|
||||
}
|
||||
}
|
||||
|
||||
WifiMacQueueItem::~WifiMacQueueItem ()
|
||||
@@ -83,6 +87,108 @@ WifiMacQueueItem::GetSize (void) const
|
||||
return m_packet->GetSize () + m_header.GetSerializedSize () + WIFI_MAC_FCS_LENGTH;
|
||||
}
|
||||
|
||||
void
|
||||
WifiMacQueueItem::Aggregate (Ptr<const WifiMacQueueItem> msdu)
|
||||
{
|
||||
NS_ASSERT (msdu != 0);
|
||||
NS_LOG_FUNCTION (this << *msdu);
|
||||
NS_ABORT_MSG_IF (!msdu->GetHeader ().IsQosData () || msdu->GetHeader ().IsQosAmsdu (),
|
||||
"Only QoS data frames that do not contain an A-MSDU can be aggregated");
|
||||
|
||||
if (m_msduList.empty ())
|
||||
{
|
||||
// An MSDU is going to be aggregated to this MPDU, hence this has to be an A-MSDU now
|
||||
Ptr<const WifiMacQueueItem> firstMsdu = Create<const WifiMacQueueItem> (*this);
|
||||
m_packet = Create<Packet> ();
|
||||
DoAggregate (firstMsdu);
|
||||
|
||||
m_header.SetQosAmsdu ();
|
||||
// Set Address3 according to Table 9-26 of 802.11-2016
|
||||
if (m_header.IsToDs () && !m_header.IsFromDs ())
|
||||
{
|
||||
// from STA to AP: BSSID is in Address1
|
||||
m_header.SetAddr3 (m_header.GetAddr1 ());
|
||||
}
|
||||
else if (!m_header.IsToDs () && m_header.IsFromDs ())
|
||||
{
|
||||
// from AP to STA: BSSID is in Address2
|
||||
m_header.SetAddr3 (m_header.GetAddr2 ());
|
||||
}
|
||||
// in the WDS case (ToDS = FromDS = 1), both Address 3 and Address 4 need
|
||||
// to be set to the BSSID, but neither Address 1 nor Address 2 contain the
|
||||
// BSSID. Hence, it is left up to the caller to set these Address fields.
|
||||
}
|
||||
DoAggregate (msdu);
|
||||
}
|
||||
|
||||
void
|
||||
WifiMacQueueItem::DoAggregate (Ptr<const WifiMacQueueItem> msdu)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *msdu);
|
||||
|
||||
// build the A-MSDU Subframe header
|
||||
AmsduSubframeHeader hdr;
|
||||
/*
|
||||
* (See Table 9-26 of 802.11-2016)
|
||||
*
|
||||
* ToDS | FromDS | DA | SA
|
||||
* 0 | 0 | Addr1 | Addr2
|
||||
* 0 | 1 | Addr1 | Addr3
|
||||
* 1 | 0 | Addr3 | Addr2
|
||||
* 1 | 1 | Addr3 | Addr4
|
||||
*/
|
||||
hdr.SetDestinationAddr (msdu->GetHeader ().IsToDs () ? msdu->GetHeader ().GetAddr3 ()
|
||||
: msdu->GetHeader ().GetAddr1 ());
|
||||
hdr.SetSourceAddr (!msdu->GetHeader ().IsFromDs () ? msdu->GetHeader ().GetAddr2 ()
|
||||
: (!msdu->GetHeader ().IsToDs ()
|
||||
? msdu->GetHeader ().GetAddr3 ()
|
||||
: msdu->GetHeader ().GetAddr4 ()));
|
||||
hdr.SetLength (static_cast<uint16_t> (msdu->GetPacket ()->GetSize ()));
|
||||
|
||||
m_msduList.push_back ({msdu->GetPacket ()->Copy (), hdr});
|
||||
|
||||
// build the A-MSDU
|
||||
NS_ASSERT (m_packet);
|
||||
Ptr<Packet> amsdu = m_packet->Copy ();
|
||||
|
||||
// pad the previous A-MSDU subframe if the A-MSDU is not empty
|
||||
if (m_packet->GetSize () > 0)
|
||||
{
|
||||
uint8_t padding = MsduAggregator::CalculatePadding (m_packet->GetSize ());
|
||||
|
||||
if (padding)
|
||||
{
|
||||
amsdu->AddAtEnd (Create<Packet> (padding));
|
||||
}
|
||||
}
|
||||
|
||||
// add A-MSDU subframe header and MSDU
|
||||
Ptr<Packet> amsduSubframe = msdu->GetPacket ()->Copy ();
|
||||
amsduSubframe->AddHeader (hdr);
|
||||
amsdu->AddAtEnd (amsduSubframe);
|
||||
m_packet = amsdu;
|
||||
|
||||
/* "The expiration of the A-MSDU lifetime timer occurs only when the lifetime
|
||||
* timer of all of the constituent MSDUs of the A-MSDU have expired" (Section
|
||||
* 10.12 of 802.11-2016)
|
||||
*/
|
||||
// The timestamp of the A-MSDU is the most recent among those of the MSDUs
|
||||
m_tstamp = Max (m_tstamp, msdu->GetTimeStamp ());
|
||||
}
|
||||
|
||||
|
||||
MsduAggregator::DeaggregatedMsdusCI
|
||||
WifiMacQueueItem::begin (void)
|
||||
{
|
||||
return m_msduList.begin ();
|
||||
}
|
||||
|
||||
MsduAggregator::DeaggregatedMsdusCI
|
||||
WifiMacQueueItem::end (void)
|
||||
{
|
||||
return m_msduList.end ();
|
||||
}
|
||||
|
||||
void
|
||||
WifiMacQueueItem::Print (std::ostream& os) const
|
||||
{
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
#include "ns3/nstime.h"
|
||||
#include "wifi-mac-header.h"
|
||||
#include "msdu-aggregator.h"
|
||||
#include "amsdu-subframe-header.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -96,6 +98,27 @@ public:
|
||||
*/
|
||||
uint32_t GetSize (void) const;
|
||||
|
||||
/**
|
||||
* \brief Aggregate the MSDU contained in the given MPDU to this MPDU (thus
|
||||
* constituting an A-MSDU). Note that the given MPDU cannot contain
|
||||
* an A-MSDU.
|
||||
* \param msdu the MPDU containing the MSDU to aggregate
|
||||
*/
|
||||
void Aggregate (Ptr<const WifiMacQueueItem> msdu);
|
||||
|
||||
/**
|
||||
* \brief Get a constant iterator pointing to the first MSDU in the list of aggregated MSDUs.
|
||||
*
|
||||
* \return a constant iterator pointing to the first MSDU in the list of aggregated MSDUs
|
||||
*/
|
||||
MsduAggregator::DeaggregatedMsdusCI begin (void);
|
||||
/**
|
||||
* \brief Get a constant iterator indicating past-the-last MSDU in the list of aggregated MSDUs.
|
||||
*
|
||||
* \return a constant iterator indicating past-the-last MSDU in the list of aggregated MSDUs
|
||||
*/
|
||||
MsduAggregator::DeaggregatedMsdusCI end (void);
|
||||
|
||||
/**
|
||||
* \brief Print the item contents.
|
||||
* \param os output stream in which the data should be printed.
|
||||
@@ -103,9 +126,18 @@ public:
|
||||
virtual void Print (std::ostream &os) const;
|
||||
|
||||
private:
|
||||
Ptr<const Packet> m_packet; //!< The packet contained in this queue item
|
||||
WifiMacHeader m_header; //!< Wifi MAC header associated with the packet
|
||||
Time m_tstamp; //!< timestamp when the packet arrived at the queue
|
||||
/**
|
||||
* \brief Aggregate the MSDU contained in the given MPDU to this MPDU (thus
|
||||
* constituting an A-MSDU). Note that the given MPDU cannot contain
|
||||
* an A-MSDU.
|
||||
* \param msdu the MPDU containing the MSDU to aggregate
|
||||
*/
|
||||
void DoAggregate (Ptr<const WifiMacQueueItem> msdu);
|
||||
|
||||
Ptr<const Packet> m_packet; //!< The packet (MSDU or A-MSDU) contained in this queue item
|
||||
WifiMacHeader m_header; //!< Wifi MAC header associated with the packet
|
||||
Time m_tstamp; //!< timestamp when the packet arrived at the queue
|
||||
MsduAggregator::DeaggregatedMsdus m_msduList; //!< The list of aggregated MSDUs included in this MPDU
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user