17#include "ns3/packet.h"
32 : m_isSingle(isSingle)
49 : m_isSingle(mpduList.size() == 1),
52 NS_ABORT_MSG_IF(mpduList.empty(),
"Cannot initialize a WifiPsdu with an empty MPDU list");
83 packet =
m_mpduList.at(0)->GetPacket()->Copy();
84 packet->AddHeader(
m_mpduList.at(0)->GetHeader());
106 for (std::size_t i = 1; i <
m_mpduList.size(); i++)
108 if (
m_mpduList.at(i)->GetHeader().GetAddr1() != ra)
110 NS_ABORT_MSG(
"MPDUs in an A-MPDU must have the same receiver address");
121 for (std::size_t i = 1; i <
m_mpduList.size(); i++)
123 if (
m_mpduList.at(i)->GetHeader().GetAddr2() != ta)
125 NS_ABORT_MSG(
"MPDUs in an A-MPDU must have the same transmitter address");
134 return m_mpduList.at(0)->GetHeader().HasNav();
142 for (std::size_t i = 1; i <
m_mpduList.size(); i++)
144 if (
m_mpduList.at(i)->GetHeader().GetDuration() != duration)
146 NS_ABORT_MSG(
"MPDUs in an A-AMPDU must have the same Duration/ID");
158 mpdu->GetHeader().SetDuration(duration);
168 mpdu->IncrementRetryCount();
178 if (mpdu->GetHeader().IsQosData())
180 s.insert(mpdu->GetHeader().GetQosTid());
197 if ((*it)->GetHeader().IsQosData() && (*it)->GetHeader().GetQosTid() == tid)
199 policy = (*it)->GetHeader().GetQosAckPolicy();
210 if ((*it)->GetHeader().IsQosData() && (*it)->GetHeader().GetQosTid() == tid &&
211 (*it)->GetHeader().GetQosAckPolicy() != policy)
213 NS_ABORT_MSG(
"QoS Data frames with the same TID must have the same QoS Ack Policy");
226 if (mpdu->GetHeader().IsQosData() && mpdu->GetHeader().GetQosTid() == tid)
228 mpdu->GetHeader().SetQosAckPolicy(policy);
238 uint16_t maxDistFromStartingSeq = 0;
239 bool foundFirst =
false;
243 uint16_t currSeqNum = mpdu->GetHeader().GetSequenceNumber();
247 uint16_t currDistToStartingSeq =
250 if (!foundFirst || currDistToStartingSeq > maxDistFromStartingSeq)
253 maxDistFromStartingSeq = currDistToStartingSeq;
260 NS_LOG_DEBUG(
"All QoS Data frames in this PSDU are old frames");
264 return maxDistFromStartingSeq;
303 subframe->AddAtEnd(pad);
312 size_t subframeSize = 4;
327std::vector<Ptr<WifiMpdu>>::const_iterator
333std::vector<Ptr<WifiMpdu>>::iterator
339std::vector<Ptr<WifiMpdu>>::const_iterator
345std::vector<Ptr<WifiMpdu>>::iterator
357 os <<
", A-MPDU of " <<
GetNMpdus() <<
" MPDUs";
360 os <<
" (" << *mpdu <<
")";
380 for (
const auto& [staId, psdu] : psduMap)
384 os <<
"[PSDU for STA_ID=" << staId <<
", ";
398 for (
const auto& [staId, psdu] : psduMap)
402 os <<
"[PSDU for STA_ID=" << staId <<
", ";
static uint8_t CalculatePadding(uint32_t ampduSize)
static void Aggregate(Ptr< const WifiMpdu > mpdu, Ptr< Packet > ampdu, bool isSingle)
Aggregate an MPDU to an A-MPDU.
static AmpduSubframeHeader GetAmpduSubframeHeader(uint16_t mpduSize, bool isSingle)
Get the A-MPDU subframe header corresponding to the MPDU size and whether the MPDU is a single MPDU.
static uint32_t GetSizeIfAggregated(uint32_t mpduSize, uint32_t ampduSize)
Compute the size of the A-MPDU resulting from the aggregation of an MPDU of size mpduSize and an A-MP...
Smart pointer class similar to boost::intrusive_ptr.
Simulation virtual time values and global simulation resolution.
WifiMpdu stores a (const) packet along with a MAC header.
WifiPsdu stores an MPDU, S-MPDU or A-MPDU, by keeping header(s) and payload(s) separate for each cons...
std::set< uint8_t > GetTids() const
Get the set of TIDs of the QoS Data frames included in the PSDU.
void SetAckPolicyForTid(uint8_t tid, WifiMacHeader::QosAckPolicy policy)
Set the QoS Ack Policy of the QoS Data frames included in the PSDU that have the given TID to the giv...
const WifiMacHeader & GetHeader(std::size_t i) const
Get the header of the i-th MPDU.
void Print(std::ostream &os) const
Print the PSDU contents.
Time GetDuration() const
Get the duration from the Duration/ID field, which is common to all the MPDUs.
Ptr< const Packet > GetPacket() const
Get the PSDU as a single packet.
Ptr< Packet > GetAmpduSubframe(std::size_t i) const
Get a copy of the i-th A-MPDU subframe (includes subframe header, MPDU, and possibly padding)
std::vector< Ptr< WifiMpdu > >::const_iterator end() const
Return a const iterator to past-the-last MPDU.
std::vector< Ptr< WifiMpdu > >::const_iterator begin() const
Return a const iterator to the first MPDU.
WifiPsdu(Ptr< const Packet > p, const WifiMacHeader &header)
Create a PSDU storing an MPDU.
Mac48Address GetAddr2() const
Get the Transmitter Address (TA), which is common to all the MPDUs.
uint32_t m_size
the size of the PSDU in bytes
uint32_t GetSize() const
Return the size of the PSDU in bytes.
Ptr< const Packet > GetPayload(std::size_t i) const
Get the payload of the i-th MPDU.
std::size_t GetAmpduSubframeSize(std::size_t i) const
Return the size of the i-th A-MPDU subframe.
bool m_isSingle
true for an S-MPDU
Mac48Address GetAddr1() const
Get the Receiver Address (RA), which is common to all the MPDUs.
bool IsAggregate() const
Return true if the PSDU is an S-MPDU or A-MPDU.
bool IsSingle() const
Return true if the PSDU is an S-MPDU.
void SetDuration(Time duration)
Set the Duration/ID field on all the MPDUs.
void IncrementRetryCount()
Increment the frame retry count for all the MPDUs.
std::vector< Ptr< WifiMpdu > > m_mpduList
list of constituent MPDUs
uint16_t GetMaxDistFromStartingSeq(uint16_t startingSeq) const
Get the maximum distance between the sequence number of any QoS Data frame included in this PSDU that...
std::size_t GetNMpdus() const
Return the number of MPDUs constituting the PSDU.
WifiMacHeader::QosAckPolicy GetAckPolicyForTid(uint8_t tid) const
Get the QoS Ack Policy of the QoS Data frames included in the PSDU that have the given TID.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
bool QosUtilsIsOldPacket(uint16_t startingSeq, uint16_t seqNumber)
This function checks if packet with sequence number seqNumber is an "old" packet.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octets of the IEEE 802.11 MAC FCS field.
std::ostream & operator<<(std::ostream &os, const Angles &a)
std::unordered_map< uint16_t, Ptr< WifiPsdu > > WifiPsduMap
Map of PSDUs indexed by STA-ID.
static constexpr uint16_t SEQNO_SPACE_SIZE
Size of the space of sequence numbers.
void AddWifiMacTrailer(Ptr< Packet > packet)
Add FCS trailer to a packet.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)