30#include "ns3/he-frame-exchange-manager.h" 
   44        TypeId(
"ns3::WifiDefaultAckManager")
 
   48            .AddAttribute(
"UseExplicitBar",
 
   49                          "Specify whether to send Block Ack Requests (if true) or use" 
   50                          " Implicit Block Ack Request ack policy (if false).",
 
   54            .AddAttribute(
"BaThreshold",
 
   55                          "Immediate acknowledgment is requested upon transmission of a frame " 
   56                          "whose sequence number is distant at least BaThreshold multiplied " 
   57                          "by the transmit window size from the starting sequence number of " 
   58                          "the transmit window. Set to zero to request a response for every " 
   62                          MakeDoubleChecker<double>(0.0, 1.0))
 
   63            .AddAttribute(
"DlMuAckSequenceType",
 
   64                          "Type of the acknowledgment sequence for DL MU PPDUs.",
 
   68                                          "DL_MU_BAR_BA_SEQUENCE",
 
   72                                          "DL_MU_AGGREGATE_TF"))
 
   73            .AddAttribute(
"MaxBlockAckMcs",
 
   74                          "The MCS used to send a BlockAck in a TB PPDU is the minimum between " 
   75                          "the MCS used for the PSDU sent in the preceding DL MU PPDU and the " 
   76                          "value of this attribute.",
 
   79                          MakeUintegerChecker<uint8_t>(0, 11));
 
   99    auto receiver = mpdu->GetHeader().GetAddr1();
 
  100    auto origReceiver = mpdu->GetOriginal()->GetHeader().GetAddr1();
 
  102    uint8_t tid = mpdu->GetHeader().GetQosTid();
 
  105                    "An established Block Ack agreement is required");
 
  107    uint16_t startingSeq = edca->GetBaStartingSequence(origReceiver, tid);
 
  108    uint16_t maxDistFromStartingSeq =
 
  111                    "The given QoS data frame is too old");
 
  118        return maxDistFromStartingSeq;
 
  121    for (
const auto& seqNumber : psduInfo->
seqNumbers.at(tid))
 
  125            uint16_t currDistToStartingSeq =
 
  128            if (currDistToStartingSeq > maxDistFromStartingSeq)
 
  130                maxDistFromStartingSeq = currDistToStartingSeq;
 
  136    return maxDistFromStartingSeq;
 
  145    uint8_t tid = mpdu->GetHeader().GetQosTid();
 
  146    Mac48Address receiver = mpdu->GetOriginal()->GetHeader().GetAddr1();
 
  162             edca->GetBaManager()->GetNBufferedPackets(receiver, tid) >
 
  164        !(edca->GetTxopLimit(
m_linkId).IsStrictlyPositive() &&
 
  172    NS_ASSERT(mpdu->GetHeader().IsQosData());
 
  173    auto tid = mpdu->GetHeader().GetQosTid();
 
  176    auto origReceiver = mpdu->GetOriginal()->GetHeader().GetAddr1();
 
  179    auto mpduDist = agreement->get().GetDistance(mpdu->GetHeader().GetSequenceNumber());
 
  181    Ptr<WifiMpdu> item = queue->PeekByTidAndAddress(tid, origReceiver);
 
  185        auto itemDist = agreement->get().GetDistance(item->GetHeader().GetSequenceNumber());
 
  186        if (itemDist == mpduDist)
 
  188            NS_LOG_DEBUG(
"No previous MPDU in-flight on the same link");
 
  192                        "While searching for given MPDU (" 
  193                            << *mpdu << 
"), found first another one (" << *item
 
  194                            << 
") with higher sequence number");
 
  195        if (
auto linkIds = item->GetInFlightLinkIds(); linkIds.count(
m_linkId) > 0)
 
  200        item = queue->PeekByTidAndAddress(tid, origReceiver, item);
 
  206std::unique_ptr<WifiAcknowledgment>
 
  237            std::unique_ptr<WifiAcknowledgment> acknowledgment;
 
  246                acknowledgment = std::make_unique<WifiNoAck>();
 
  249            return acknowledgment;
 
  258        auto acknowledgment = std::make_unique<WifiAckAfterTbPpdu>();
 
  263        return acknowledgment;
 
  283        auto acknowledgment = std::make_unique<WifiNoAck>();
 
  288        return acknowledgment;
 
  296            "Non-QoS data frame or Block Ack agreement not established, request Normal Ack");
 
  297        auto acknowledgment = std::make_unique<WifiNormalAck>();
 
  298        acknowledgment->ackTxVector =
 
  304        return acknowledgment;
 
  311        NS_LOG_DEBUG(
"A response is not needed: no ack for now, use Block Ack policy");
 
  319        auto acknowledgment = std::make_unique<WifiNoAck>();
 
  324        return acknowledgment;
 
  328    uint8_t tid = 
GetTid(mpdu->GetPacket(), hdr);
 
  331        NS_LOG_DEBUG(
"Sending a single MPDU, no previous frame to ack: request Normal Ack");
 
  332        auto acknowledgment = std::make_unique<WifiNormalAck>();
 
  333        acknowledgment->ackTxVector =
 
  336        return acknowledgment;
 
  345        NS_LOG_DEBUG(
"Request to schedule a Block Ack Request");
 
  347        auto acknowledgment = std::make_unique<WifiBarBlockAck>();
 
  348        acknowledgment->blockAckReqTxVector =
 
  350        acknowledgment->blockAckTxVector = acknowledgment->blockAckReqTxVector;
 
  354        return acknowledgment;
 
  358        "A-MPDU using Implicit Block Ack Request policy or BlockAckReq, request Block Ack");
 
  359    auto acknowledgment = std::make_unique<WifiBlockAck>();
 
  360    acknowledgment->blockAckTxVector =
 
  364    return acknowledgment;
 
  367std::unique_ptr<WifiAcknowledgment>
 
  376std::unique_ptr<WifiAcknowledgment>
 
  390                    "QoS data frames only can be aggregated when transmitting a " 
  391                    "DL MU PPDU acknowledged via a sequence of BAR and BA frames");
 
  438        return std::unique_ptr<WifiDlMuBarBaSequence>(acknowledgment);
 
  464                                   << 
" to the list of stations receiving a BlockAckReq");
 
  474        return std::unique_ptr<WifiDlMuBarBaSequence>(acknowledgment);
 
  491                               << 
" as the station that will immediately reply with a Normal Ack");
 
  498    return std::unique_ptr<WifiDlMuBarBaSequence>(acknowledgment);
 
  501std::unique_ptr<WifiAcknowledgment>
 
  528        uint16_t staId = apMac->GetAssociationId(receiver, 
m_linkId);
 
  531                        "QoS data frames only can be aggregated when transmitting a " 
  532                        "DL MU PPDU acknowledged via a MU-BAR sent as SU frame");
 
  564                     << 
" to the list of stations that will be solicited by the MU-BAR");
 
  569                                              mpdu->GetOriginal()->GetHeader().GetAddr1(),
 
  577        return std::unique_ptr<WifiDlMuTfMuBar>(acknowledgment);
 
  583                    "QoS data frames only can be aggregated when transmitting a DL MU PPDU");
 
  589std::unique_ptr<WifiAcknowledgment>
 
  616        uint16_t staId = apMac->GetAssociationId(receiver, 
m_linkId);
 
  619                        "QoS data frames only can be aggregated when transmitting a " 
  620                        "DL MU PPDU acknowledged via a sequence of BAR and BA frames");
 
  651                                   << 
" to the list of stations that will reply with a Block Ack");
 
  657                edca->GetBaManager()->GetBlockAckReqHeader(
 
  658                    mpdu->GetOriginal()->GetHeader().GetAddr1(),
 
  664        return std::unique_ptr<WifiDlMuAggregateTf>(acknowledgment);
 
  671        "QoS data and MU-BAR Trigger frames only can be aggregated when transmitting a DL MU PPDU");
 
  677std::unique_ptr<WifiAcknowledgment>
 
  682    NS_ASSERT(mpdu->GetHeader().IsTrigger());
 
  691    mpdu->GetPacket()->PeekHeader(trigger);
 
  696        auto acknowledgment = std::make_unique<WifiUlMuMultiStaBa>();
 
  698        for (
const auto& userInfo : trigger)
 
  700            uint16_t aid12 = userInfo.GetAid12();
 
  707            NS_ABORT_MSG_IF(aid12 == 0 || aid12 > 2007, 
"Allocation of RA-RUs is not supported");
 
  714            while (tid < 8 && !m_mac->GetBaAgreementEstablishedAsRecipient(staAddress, tid))
 
  719                          "No Block Ack agreement established with originator " << staAddress);
 
  721            std::size_t index = acknowledgment->baType.m_bitmapLen.size();
 
  722            acknowledgment->stationsReceivingMultiStaBa.emplace(std::make_pair(staAddress, tid),
 
  727            acknowledgment->baType.m_bitmapLen.push_back(
 
  731        uint16_t staId = trigger.begin()->GetAid12();
 
  732        acknowledgment->tbPpduTxVector = trigger.GetHeTbTxVector(staId);
 
  734            apMac->GetStaList(
m_linkId).find(staId)->second,
 
  735            acknowledgment->tbPpduTxVector);
 
  736        return acknowledgment;
 
  738    else if (trigger.
IsBsrp())
 
  740        return std::make_unique<WifiNoAck>();
 
AttributeValue implementation for Boolean.
 
This class can be used to hold variables of floating point type such as 'double' or 'float'.
 
Hold variables of type enum.
 
Smart pointer class similar to boost::intrusive_ptr.
 
a unique identifier for an interface.
 
TypeId SetParent(TypeId tid)
Set the parent TypeId.
 
Hold an unsigned integer type.
 
WifiAckManager is an abstract base class.
 
uint8_t m_linkId
ID of the link this Acknowledgment Manager is operating on.
 
Ptr< WifiMac > m_mac
MAC which is using this Acknowledgment Manager.
 
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager() const
 
WifiDefaultAckManager is the default ack manager.
 
bool IsResponseNeeded(Ptr< const WifiMpdu > mpdu, const WifiTxParameters &txParams) const
Determine whether the (A-)MPDU containing the given MPDU and the MPDUs (if any) included in the given...
 
static TypeId GetTypeId()
Get the type ID.
 
virtual std::unique_ptr< WifiAcknowledgment > GetAckInfoIfBarBaSequence(Ptr< const WifiMpdu > mpdu, const WifiTxParameters &txParams)
Compute the information about the acknowledgment of the current multi-user frame (as described by the...
 
bool m_useExplicitBar
true for sending BARs, false for using Implicit BAR policy
 
uint8_t m_maxMcsForBlockAckInTbPpdu
Max MCS used to send a BlockAck in a TB PPDU.
 
double m_baThreshold
Threshold to determine when a BlockAck must be requested.
 
virtual std::unique_ptr< WifiAcknowledgment > GetAckInfoIfTfMuBar(Ptr< const WifiMpdu > mpdu, const WifiTxParameters &txParams)
Compute the information about the acknowledgment of the current multi-user frame (as described by the...
 
~WifiDefaultAckManager() override
 
WifiAcknowledgment::Method m_dlMuAckType
Type of the ack sequence for DL MU PPDUs.
 
std::unique_ptr< WifiAcknowledgment > TryAggregateMsdu(Ptr< const WifiMpdu > msdu, const WifiTxParameters &txParams) override
Determine the acknowledgment method to use if the given MSDU is aggregated to the current frame.
 
uint16_t GetMaxDistFromStartingSeq(Ptr< const WifiMpdu > mpdu, const WifiTxParameters &txParams) const
Get the maximum distance between the starting sequence number of the Block Ack agreement which the gi...
 
bool ExistInflightOnSameLink(Ptr< const WifiMpdu > mpdu) const
 
std::unique_ptr< WifiAcknowledgment > TryAddMpdu(Ptr< const WifiMpdu > mpdu, const WifiTxParameters &txParams) override
Determine the acknowledgment method to use if the given MPDU is added to the current frame.
 
virtual std::unique_ptr< WifiAcknowledgment > GetAckInfoIfAggregatedMuBar(Ptr< const WifiMpdu > mpdu, const WifiTxParameters &txParams)
Compute the information about the acknowledgment of the current multi-user frame (as described by the...
 
virtual std::unique_ptr< WifiAcknowledgment > TryUlMuTransmission(Ptr< const WifiMpdu > mpdu, const WifiTxParameters &txParams)
Calculate the acknowledgment method for the TB PPDUs solicited by the given Trigger Frame.
 
Ptr< FrameExchangeManager > GetFrameExchangeManager(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get the Frame Exchange Manager associated with the given link.
 
BlockAckType GetBaTypeAsRecipient(Mac48Address originator, uint8_t tid) const
 
BlockAckType GetBaTypeAsOriginator(const Mac48Address &recipient, uint8_t tid) const
 
virtual Ptr< WifiMacQueue > GetTxopQueue(AcIndex ac) const
Get the wifi MAC queue of the (Qos)Txop associated with the given AC, if such (Qos)Txop is installed,...
 
BlockAckReqType GetBarTypeAsOriginator(const Mac48Address &recipient, uint8_t tid) const
 
OriginatorAgreementOptConstRef GetBaAgreementEstablishedAsOriginator(Mac48Address recipient, uint8_t tid) const
 
Ptr< QosTxop > GetQosTxop(AcIndex ac) const
Accessor for a specified EDCA object.
 
WifiTxVector GetAckTxVector(Mac48Address to, const WifiTxVector &dataTxVector) const
Return a TXVECTOR for the Ack frame given the destination and the mode of the Data used by the sender...
 
WifiTxVector GetBlockAckTxVector(Mac48Address to, const WifiTxVector &dataTxVector) const
Return a TXVECTOR for the BlockAck frame given the destination and the mode of the Data used by the s...
 
WifiTxVector GetRtsTxVector(Mac48Address address)
 
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism,...
 
std::unique_ptr< WifiProtection > m_protection
protection method
 
uint32_t GetSize(Mac48Address receiver) const
Get the size in bytes of the (A-)MPDU addressed to the given receiver.
 
std::unique_ptr< WifiAcknowledgment > m_acknowledgment
acknowledgment method
 
const PsduInfo * GetPsduInfo(Mac48Address receiver) const
Get a pointer to the information about the PSDU addressed to the given receiver, if present,...
 
WifiTxVector m_txVector
TXVECTOR of the frame being prepared.
 
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
 
uint16_t GetGuardInterval() const
 
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
 
void SetGuardInterval(uint16_t guardInterval)
Sets the guard interval duration (in nanoseconds)
 
void SetHeMuUserInfo(uint16_t staId, HeMuUserInfo userInfo)
Set the HE MU user-specific transmission information for the given STA-ID.
 
WifiPreamble GetPreambleType() const
 
HeMuUserInfo GetHeMuUserInfo(uint16_t staId) const
Get the HE MU user-specific transmission information for the given STA-ID.
 
uint16_t GetChannelWidth() const
 
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
 
#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...
 
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
 
Ptr< const AttributeChecker > MakeBooleanChecker()
 
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
 
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
 
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
 
#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_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.
 
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
 
bool QosUtilsIsOldPacket(uint16_t startingSeq, uint16_t seqNumber)
This function checks if packet with sequence number seqNumber is an "old" packet.
 
uint8_t GetTid(Ptr< const Packet > packet, const WifiMacHeader hdr)
This function is useful to get traffic id of different packet types.
 
Every class exported by the ns3 library is enclosed in the ns3 namespace.
 
static constexpr uint16_t SEQNO_SPACE_HALF_SIZE
Size of the half the space of sequence numbers (used to determine old packets)
 
bool IsEht(WifiPreamble preamble)
Return true if a preamble corresponds to an EHT transmission.
 
static constexpr uint16_t NO_USER_STA_ID
STA_ID for a RU that is intended for no user (Section 26.11.1 802.11ax-2021)
 
uint32_t GetMuBarSize(std::list< BlockAckReqType > types)
Return the total MU-BAR size (including FCS trailer).
 
static constexpr uint16_t SEQNO_SPACE_SIZE
Size of the space of sequence numbers.
 
Ptr< const AttributeChecker > MakeEnumChecker(int v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
 
std::vector< uint8_t > m_bitmapLen
Length (bytes) of included bitmaps.
 
void SetQosAckPolicy(Mac48Address receiver, uint8_t tid, WifiMacHeader::QosAckPolicy ackPolicy)
Set the QoS Ack policy to use for the MPDUs addressed to the given receiver and belonging to the give...
 
information related to a BlockAck frame sent by a station
 
WifiDlMuAggregateTf specifies that a DL MU PPDU made of PSDUs including each a MU-BAR Trigger Frame i...
 
std::map< Mac48Address, BlockAckInfo > stationsReplyingWithBlockAck
Set of stations replying with a BlockAck frame.
 
information related to an Ack frame sent by a station
 
information related to a BlockAck frame sent by a station
 
information related to a BlockAckReq frame sent to a station
 
WifiDlMuBarBaSequence specifies that a DL MU PPDU is acknowledged through a sequence of BlockAckReq a...
 
std::map< Mac48Address, BlockAckReqInfo > stationsSendBlockAckReqTo
Set of stations receiving a BlockAckReq frame and replying with a BlockAck frame.
 
std::map< Mac48Address, BlockAckInfo > stationsReplyingWithBlockAck
Set of stations replying with a BlockAck frame (no more than one)
 
std::map< Mac48Address, AckInfo > stationsReplyingWithNormalAck
Set of stations replying with an Ack frame (no more than one)
 
information related to a BlockAck frame sent by a station
 
WifiDlMuTfMuBar specifies that a DL MU PPDU is followed after a SIFS duration by a MU-BAR Trigger Fra...
 
std::list< BlockAckReqType > barTypes
BAR types.
 
std::map< Mac48Address, BlockAckInfo > stationsReplyingWithBlockAck
Set of stations replying with a BlockAck frame.
 
WifiTxVector muBarTxVector
TXVECTOR used to transmit the MU-BAR Trigger Frame.
 
information about the frame being prepared for a specific receiver
 
std::map< uint8_t, std::set< uint16_t > > seqNumbers
set of the sequence numbers of the MPDUs added for each TID