20#include "ns3/ht-capabilities.h"
21#include "ns3/ht-frame-exchange-manager.h"
23#include "ns3/packet.h"
83 Time availableTime)
const
91 const auto& header = peekedItem->GetOriginal()->GetHeader();
93 NS_ABORT_MSG_IF(recipient.IsBroadcast(),
"Recipient address is broadcast");
107 auto queue =
m_mac->GetTxopQueue(peekedItem->GetQueueAc());
114 auto gcrManager = apMac->GetGcrManager();
115 if (!gcrManager->UseConcealment(peekedItem->GetHeader()))
119 auto msdu = peekedItem->GetOriginal();
121 Create<WifiMpdu>(msdu->GetPacket(), msdu->GetHeader(), msdu->GetTimestamp());
122 gcrAmsdu->Aggregate(
nullptr);
123 queue->Replace(msdu, gcrAmsdu);
124 if (msdu->GetHeader().IsRetry())
126 gcrAmsdu->AssignSeqNo(msdu->GetHeader().GetSequenceNumber());
128 return m_htFem->CreateAliasIfNeeded(gcrAmsdu);
132 NS_LOG_DEBUG(
"No A-MSDU aggregation for groupcast frames without GCR service");
136 const auto tid = header.GetQosTid();
144 auto amsdu = queue->GetOriginal(peekedItem);
145 std::size_t nMsdu = 1;
146 peekedItem = queue->PeekByTidAndAddress(tid,
149 peekedItem->GetOriginal());
153 while (peekedItem && !peekedItem->GetHeader().IsQosAmsdu() &&
154 m_htFem->TryAggregateMsdu(peekedItem =
m_htFem->CreateAliasIfNeeded(peekedItem),
159 "Found item with sequence number assignment after one without: perhaps "
160 "sequence numbers were not released correctly?");
162 auto msdu = peekedItem->GetOriginal();
163 peekedItem = queue->PeekByTidAndAddress(tid, recipient,
m_htFem->GetAddress(), msdu);
164 queue->DequeueIfQueued({amsdu});
166 amsdu->Aggregate(msdu);
167 queue->Replace(msdu, amsdu);
174 NS_LOG_DEBUG(
"Aggregation failed (could not aggregate at least two MSDUs)");
179 return m_htFem->CreateAliasIfNeeded(amsdu);
185 return (4 - (amsduSize % 4)) % 4;
198 uint16_t maxAmsduSize =
m_mac->GetMaxAmsduSize(ac);
200 if (maxAmsduSize == 0)
202 NS_LOG_DEBUG(
"A-MSDU Aggregation is disabled on this station for " << ac);
210 auto ehtCapabilities = stationManager->GetStationEhtCapabilities(recipient);
211 auto he6GhzCapabilities = stationManager->GetStationHe6GhzCapabilities(recipient);
212 auto vhtCapabilities = stationManager->GetStationVhtCapabilities(recipient);
213 auto htCapabilities = stationManager->GetStationHtCapabilities(recipient);
219 uint16_t maxMpduSize = 0;
222 maxMpduSize = ehtCapabilities->GetMaxMpduLength();
226 maxMpduSize = he6GhzCapabilities->GetMaxMpduLength();
230 maxMpduSize = vhtCapabilities->GetMaxMpduLength();
233 if (!htCapabilities && !he6GhzCapabilities)
239 NS_LOG_DEBUG(
"A-MSDU Aggregation disabled because the recipient did not"
240 " send an HT Capabilities element");
251 maxAmsduSize = std::min(maxAmsduSize,
static_cast<uint16_t
>(maxMpduSize - 56));
262 maxAmsduSize = std::min(maxAmsduSize, htCapabilities->GetMaxAmsduLength());
267 maxAmsduSize = std::min(maxAmsduSize,
static_cast<uint16_t
>(maxMpduSize - 56));
276 maxAmsduSize = std::min(maxAmsduSize,
static_cast<uint16_t
>(maxMpduSize - 56));
283 maxAmsduSize = std::min(maxAmsduSize, htCapabilities->GetMaxAmsduLength());
289 maxAmsduSize = std::min(maxAmsduSize,
static_cast<uint16_t
>(3839));
303 uint32_t maxSize = aggregatedPacket->GetSize();
304 uint16_t extractedLength;
308 while (deserialized < maxSize)
310 deserialized += aggregatedPacket->RemoveHeader(hdr);
312 extractedMsdu = aggregatedPacket->CreateFragment(0,
static_cast<uint32_t>(extractedLength));
313 aggregatedPacket->RemoveAtStart(extractedLength);
314 deserialized += extractedLength;
316 padding = (4 - ((extractedLength + 14) % 4)) % 4;
318 if (padding > 0 && deserialized < maxSize)
320 aggregatedPacket->RemoveAtStart(padding);
321 deserialized += padding;
325 set.push_back(packetHdr);
327 NS_LOG_INFO(
"Deaggreated A-MSDU: extracted " << set.size() <<
" MSDUs");
Aggregator used to construct A-MSDUs.
static TypeId GetTypeId()
Get the type ID.
uint16_t GetMaxAmsduSize(Mac48Address recipient, uint8_t tid, WifiModulationClass modulation) const
Determine the maximum size for an A-MSDU of the given TID that can be sent to the given receiver when...
void DoDispose() override
Destructor implementation.
Ptr< WifiMac > m_mac
the MAC of this station
uint8_t m_linkId
ID of the link this object is connected to.
static WifiMpdu::DeaggregatedMsdus Deaggregate(Ptr< Packet > aggregatedPacket)
Ptr< HtFrameExchangeManager > m_htFem
the HT Frame Exchange Manager of this station
static uint16_t GetSizeIfAggregated(uint16_t msduSize, uint16_t amsduSize)
Compute the size of the A-MSDU resulting from the aggregation of an MSDU of size msduSize and an A-MS...
Ptr< WifiMpdu > GetNextAmsdu(Ptr< WifiMpdu > peekedItem, WifiTxParameters &txParams, Time availableTime) const
Attempt to aggregate other MSDUs to the given A-MSDU while meeting the following constraints:
void SetWifiMac(const Ptr< WifiMac > mac)
Set the MAC layer to use.
static uint8_t CalculatePadding(uint16_t amsduSize)
Calculate how much padding must be added to the end of an A-MSDU of the given size if a new MSDU is a...
void SetLinkId(uint8_t linkId)
Set the ID of the link this MSDU aggregator is associated with.
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.
std::list< std::pair< Ptr< const Packet >, AmsduSubframeHeader > > DeaggregatedMsdus
DeaggregatedMsdus typedef.
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism,...
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_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#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_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
#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_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ 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.
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.