26#include "ns3/eht-capabilities.h"
27#include "ns3/he-capabilities.h"
28#include "ns3/ht-capabilities.h"
29#include "ns3/ht-frame-exchange-manager.h"
31#include "ns3/packet.h"
32#include "ns3/vht-capabilities.h"
84 NS_ASSERT(!isSingle || ampdu->GetSize() == 0);
87 if (ampdu->GetSize() > 0)
100 tmp->AddHeader(mpdu->GetHeader());
108 ampdu->AddAtEnd(tmp);
127 IsGroupcast(recipient) && (
m_mac->GetTypeOfStation() ==
AP) && apMac->GetGcrManager())
129 recipient = apMac->GetGcrManager()->GetIndividuallyAddressedRecipient(recipient);
136 if (maxAmpduSize == 0)
138 NS_LOG_DEBUG(
"A-MPDU Aggregation is disabled on this station for " << ac);
146 auto ehtCapabilities = stationManager->GetStationEhtCapabilities(recipient);
147 auto heCapabilities = stationManager->GetStationHeCapabilities(recipient);
148 auto he6GhzCapabilities = stationManager->GetStationHe6GhzCapabilities(recipient);
149 auto vhtCapabilities = stationManager->GetStationVhtCapabilities(recipient);
150 auto htCapabilities = stationManager->GetStationHtCapabilities(recipient);
157 "EHT Capabilities element not received for " << recipient);
159 maxAmpduSize = std::min(maxAmpduSize, ehtCapabilities->GetMaxAmpduLength());
163 NS_ABORT_MSG_IF(!heCapabilities,
"HE Capabilities element not received for " << recipient);
165 maxAmpduSize = std::min(maxAmpduSize, heCapabilities->GetMaxAmpduLength());
166 if (he6GhzCapabilities)
168 maxAmpduSize = std::min(maxAmpduSize, he6GhzCapabilities->GetMaxAmpduLength());
174 "VHT Capabilities element not received for " << recipient);
176 maxAmpduSize = std::min(maxAmpduSize, vhtCapabilities->GetMaxAmpduLength());
180 NS_ABORT_MSG_IF(!htCapabilities,
"HT Capabilities element not received for " << recipient);
182 maxAmpduSize = std::min(maxAmpduSize, htCapabilities->GetMaxAmpduLength());
186 NS_LOG_DEBUG(
"A-MPDU aggregation is not available for non-HT PHYs");
197 return (4 - (ampduSize % 4)) % 4;
212std::vector<Ptr<WifiMpdu>>
215 Time availableTime)
const
219 std::vector<Ptr<WifiMpdu>> mpduList;
221 const auto& header = mpdu->GetHeader();
223 NS_ASSERT(header.IsQosData() && !recipient.IsBroadcast());
225 const auto& origAddr1 = mpdu->GetOriginal()->GetHeader().GetAddr1();
228 const auto tid = header.GetQosTid();
229 auto qosTxop =
m_mac->GetQosTxop(tid);
233 const auto bufferSize = qosTxop->GetBaBufferSize(origRecipient, tid, isGcr);
234 const auto startSeq = qosTxop->GetBaStartingSequence(origRecipient, tid, isGcr);
238 const auto agreementEstablished =
239 isGcr ? apMac->IsGcrBaAgreementEstablishedWithAllMembers(header.GetAddr1(), tid)
240 :
m_mac->GetBaAgreementEstablishedAsOriginator(recipient, tid).has_value();
241 if (agreementEstablished &&
249 const auto isGcrUr = isGcr && (apMac->GetGcrManager()->GetRetransmissionPolicy() ==
251 if (isGcrUr && header.IsRetry() && !nextMpdu->GetHeader().IsRetry())
257 apMac->GetGcrManager()->GetRetransmissionPolicyFor(header) !=
258 apMac->GetGcrManager()->GetRetransmissionPolicyFor(nextMpdu->GetHeader()))
268 << nextMpdu->GetHeader().GetSequenceNumber()
269 <<
" to A-MPDU, packet size = " << nextMpdu->GetSize()
270 <<
", A-MPDU size = " << txParams.
GetSize(recipient));
272 mpduList.push_back(nextMpdu);
276 qosTxop->PeekNextMpdu(
m_linkId, tid, origAddr1, nextMpdu->GetOriginal());
283 IsInWindow(peekedMpdu->GetHeader().GetSequenceNumber(), startSeq, bufferSize));
285 peekedMpdu =
m_htFem->CreateAliasIfNeeded(peekedMpdu);
291 qosTxop->GetNextMpdu(
m_linkId, peekedMpdu, txParams, availableTime,
false);
295 if (mpduList.size() == 1)
Aggregator used to construct A-MPDUs.
static uint8_t CalculatePadding(uint32_t ampduSize)
void DoDispose() override
Destructor implementation.
static void Aggregate(Ptr< const WifiMpdu > mpdu, Ptr< Packet > ampdu, bool isSingle)
Aggregate an MPDU to an A-MPDU.
Ptr< WifiMac > m_mac
the MAC of this station
Ptr< HtFrameExchangeManager > m_htFem
the HT Frame Exchange Manager of this station
uint32_t GetMaxAmpduSize(Mac48Address recipient, uint8_t tid, WifiModulationClass modulation) const
Determine the maximum size for an A-MPDU of the given TID that can be sent to the given receiver when...
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 TypeId GetTypeId()
Get the type ID.
void SetWifiMac(const Ptr< WifiMac > mac)
Set the MAC layer to use.
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...
std::vector< Ptr< WifiMpdu > > GetNextAmpdu(Ptr< WifiMpdu > mpdu, WifiTxParameters &txParams, Time availableTime) const
Attempt to aggregate other MPDUs to the given MPDU, while meeting the following constraints:
void SetLinkId(uint8_t linkId)
Set the ID of the link this MPDU aggregator is associated with.
uint8_t m_linkId
ID of the link this object is connected to.
Object()
Caller graph was not generated because of its size.
virtual void DoDispose()
Destructor implementation.
Smart pointer class similar to boost::intrusive_ptr.
Simulation virtual time values and global simulation resolution.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism,...
uint32_t GetSize(Mac48Address receiver) const
Get the size in bytes of the (A-)MPDU addressed to the given receiver.
WifiTxVector m_txVector
TXVECTOR of the frame being prepared.
WifiModulationClass GetModulationClass() const
Get the modulation class specified by this TXVECTOR.
#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_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 ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
@ WIFI_MOD_CLASS_HT
HT (Clause 19).
@ WIFI_MOD_CLASS_EHT
EHT (Clause 36).
@ WIFI_MOD_CLASS_VHT
VHT (Clause 22).
@ WIFI_MOD_CLASS_HE
HE (Clause 27).
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
bool IsGroupcast(const Mac48Address &adr)
Check whether a MAC destination address corresponds to a groupcast transmission.
void AddWifiMacTrailer(Ptr< Packet > packet)
Add FCS trailer to a packet.
bool IsGcr(Ptr< WifiMac > mac, const WifiMacHeader &hdr)
Return whether a given packet is transmitted using the GCR service.
Mac48Address GetIndividuallyAddressedRecipient(Ptr< WifiMac > mac, const WifiMacHeader &hdr)
Get the MAC address of the individually addressed recipient to use for a given packet.
bool IsInWindow(uint16_t seq, uint16_t winstart, uint16_t winsize)