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, recipient, peekedItem->GetOriginal());
150 while (peekedItem && !peekedItem->GetHeader().IsQosAmsdu() &&
151 m_htFem->TryAggregateMsdu(peekedItem =
m_htFem->CreateAliasIfNeeded(peekedItem),
156 "Found item with sequence number assignment after one without: perhaps "
157 "sequence numbers were not released correctly?");
159 auto msdu = peekedItem->GetOriginal();
160 peekedItem = queue->PeekByTidAndAddress(tid, recipient, msdu);
161 queue->DequeueIfQueued({amsdu});
163 amsdu->Aggregate(msdu);
164 queue->Replace(msdu, amsdu);
171 NS_LOG_DEBUG(
"Aggregation failed (could not aggregate at least two MSDUs)");
176 return m_htFem->CreateAliasIfNeeded(amsdu);
182 return (4 - (amsduSize % 4)) % 4;
195 uint16_t maxAmsduSize =
m_mac->GetMaxAmsduSize(ac);
197 if (maxAmsduSize == 0)
199 NS_LOG_DEBUG(
"A-MSDU Aggregation is disabled on this station for " << ac);
207 auto ehtCapabilities = stationManager->GetStationEhtCapabilities(recipient);
208 auto he6GhzCapabilities = stationManager->GetStationHe6GhzCapabilities(recipient);
209 auto vhtCapabilities = stationManager->GetStationVhtCapabilities(recipient);
210 auto htCapabilities = stationManager->GetStationHtCapabilities(recipient);
216 uint16_t maxMpduSize = 0;
219 maxMpduSize = ehtCapabilities->GetMaxMpduLength();
223 maxMpduSize = he6GhzCapabilities->GetMaxMpduLength();
227 maxMpduSize = vhtCapabilities->GetMaxMpduLength();
230 if (!htCapabilities && !he6GhzCapabilities)
236 NS_LOG_DEBUG(
"A-MSDU Aggregation disabled because the recipient did not"
237 " send an HT Capabilities element");
248 maxAmsduSize = std::min(maxAmsduSize,
static_cast<uint16_t
>(maxMpduSize - 56));
259 maxAmsduSize = std::min(maxAmsduSize, htCapabilities->GetMaxAmsduLength());
264 maxAmsduSize = std::min(maxAmsduSize,
static_cast<uint16_t
>(maxMpduSize - 56));
273 maxAmsduSize = std::min(maxAmsduSize,
static_cast<uint16_t
>(maxMpduSize - 56));
280 maxAmsduSize = std::min(maxAmsduSize, htCapabilities->GetMaxAmsduLength());
286 maxAmsduSize = std::min(maxAmsduSize,
static_cast<uint16_t
>(3839));
300 uint32_t maxSize = aggregatedPacket->GetSize();
301 uint16_t extractedLength;
305 while (deserialized < maxSize)
307 deserialized += aggregatedPacket->RemoveHeader(hdr);
309 extractedMsdu = aggregatedPacket->CreateFragment(0,
static_cast<uint32_t>(extractedLength));
310 aggregatedPacket->RemoveAtStart(extractedLength);
311 deserialized += extractedLength;
313 padding = (4 - ((extractedLength + 14) % 4)) % 4;
315 if (padding > 0 && deserialized < maxSize)
317 aggregatedPacket->RemoveAtStart(padding);
318 deserialized += padding;
322 set.push_back(packetHdr);
324 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.