wifi: WifiMacQueueItem keeps MSDUs separate in case of A-MSDU

This commit is contained in:
Stefano Avallone
2019-09-01 00:34:26 +02:00
parent 1ef995ce3b
commit a5d0e94985
4 changed files with 151 additions and 66 deletions

View File

@@ -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

View File

@@ -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
};

View File

@@ -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
{

View File

@@ -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
};
/**