20#include "ns3/simulator.h" 
   36        TypeId(
"ns3::BlockAckManager")
 
   40            .AddTraceSource(
"AgreementState",
 
   41                            "The state of the ADDBA handshake",
 
   43                            "ns3::BlockAckManager::AgreementStateTracedCallback");
 
 
   68                                          std::optional<Mac48Address> gcrGroupAddr)
 
   71    for (
auto it = 
first; it != last; ++it)
 
   73        [[maybe_unused]] 
const auto& [baAgreement, packetQueue] = it->second;
 
   74        if (baAgreement.GetGcrGroupAddress() == gcrGroupAddr)
 
 
   85                                          std::optional<Mac48Address> gcrGroupAddr)
 const 
   88    for (
auto it = 
first; it != last; ++it)
 
   90        [[maybe_unused]] 
const auto& [baAgreement, packetQueue] = it->second;
 
   91        if (baAgreement.GetGcrGroupAddress() == gcrGroupAddr)
 
 
  102                                         std::optional<Mac48Address> gcrGroupAddr)
 
  105    for (
auto it = 
first; it != last; ++it)
 
  107        if (it->second.GetGcrGroupAddress() == gcrGroupAddr)
 
 
  118                                         std::optional<Mac48Address> gcrGroupAddr)
 const 
  121    for (
auto it = 
first; it != last; ++it)
 
  123        if (it->second.GetGcrGroupAddress() == gcrGroupAddr)
 
 
  134                                          std::optional<Mac48Address> gcrGroupAddr)
 const 
  139        return std::cref(it->second.first);
 
 
  147                                         std::optional<Mac48Address> gcrGroupAddr)
 const 
  152        return std::cref(it->second);
 
 
  162    const auto tid = reqHdr.
GetTid();
 
  194        NS_ASSERT_MSG(it->second.first.IsReset(), 
"Existing agreement must be in RESET state");
 
  195        it->second = std::make_pair(std::move(agreement), 
PacketQueue{});
 
  200                                       std::make_pair(std::move(agreement), 
PacketQueue{}));
 
  206                                [&reqHdr](
const auto& elem) {
 
  207                                    return elem.second.first.GetGcrGroupAddress() ==
 
  210                  "There exists more than one " 
  212                      << 
"Block Ack agreement for recipient " << recipient << 
" and tid " << +tid);
 
 
  220                                            std::optional<Mac48Address> gcrGroupAddr)
 
 
  233                                           uint16_t startingSeq)
 
  236    const auto tid = respHdr.
GetTid();
 
  259        if (!it->second.first.IsEstablished())
 
  290            if (!agreement.second.first.IsEstablished())
 
 
  303                                          uint16_t startingSeq,
 
  306    NS_LOG_FUNCTION(
this << respHdr << originator << startingSeq << rxMiddle);
 
  307    const auto tid = respHdr.
GetTid();
 
  334        it->second = std::move(agreement);
 
  345                      [&respHdr](
const auto& elem) {
 
  348        "There exists more than one " << (respHdr.
GetGcrGroupAddress().has_value() ? 
"GCR " : 
" ")
 
  349                                      << 
"Block Ack agreement for originator " << originator
 
  350                                      << 
" and tid " << +tid);
 
 
  356                                           std::optional<Mac48Address> gcrGroupAddr)
 
  358    NS_LOG_FUNCTION(
this << originator << tid << gcrGroupAddr.has_value());
 
 
  379    for (
const auto& member : members)
 
  381        DoStorePacket(mpdu, member, mpdu->begin()->second.GetDestinationAddr());
 
 
  388                               std::optional<Mac48Address> gcrGroupAddr)
 
  390    NS_LOG_FUNCTION(
this << *mpdu << recipient << gcrGroupAddr.has_value());
 
  391    NS_ASSERT(mpdu->GetHeader().IsQosData());
 
  393    const auto tid = mpdu->GetHeader().GetQosTid();
 
  397    const auto mpduDist =
 
  398        agreementIt->second.first.GetDistance(mpdu->GetHeader().GetSequenceNumber());
 
  408    auto it = agreementIt->second.second.rbegin();
 
  409    while (it != agreementIt->second.second.rend())
 
  411        if (mpdu->GetHeader().GetSequenceControl() == (*it)->GetHeader().GetSequenceControl())
 
  413            NS_LOG_DEBUG(
"Packet already in the queue of the BA agreement");
 
  418            agreementIt->second.first.GetDistance((*it)->GetHeader().GetSequenceNumber());
 
  420        if (mpduDist > dist || (mpduDist == dist && mpdu->GetHeader().GetFragmentNumber() >
 
  421                                                        (*it)->GetHeader().GetFragmentNumber()))
 
  428    agreementIt->second.second.insert(it.base(), mpdu);
 
  429    agreementIt->second.first.NotifyTransmittedMpdu(mpdu);
 
 
  453    NS_LOG_FUNCTION(
this << linkId << **mpduIt << 
static_cast<uint8_t
>(status));
 
  455    if (!(*mpduIt)->IsQueued())
 
  459        NS_LOG_DEBUG(
"MPDU is not stored in the EDCA queue, drop MPDU");
 
  460        return it->second.second.erase(mpduIt);
 
  466        return it->second.second.erase(mpduIt);
 
  476        NS_LOG_DEBUG(
"Old packet. Remove from the EDCA queue, too");
 
  480        return it->second.second.erase(mpduIt);
 
  483    std::optional<PacketQueueI> prevIt;
 
  484    if (mpduIt != it->second.second.begin())
 
  486        prevIt = std::prev(mpduIt);
 
  489    if (
m_queue->TtlExceeded(*mpduIt, now))
 
  495        return (prevIt.has_value() ? std::next(prevIt.value()) : it->second.second.begin());
 
  505    (*mpduIt)->GetHeader().SetRetry();
 
  506    (*mpduIt)->ResetInFlight(linkId); 
 
  508    return it->second.second.erase(mpduIt);
 
 
  515    NS_ASSERT(mpdu->GetHeader().IsQosData());
 
  517    const auto recipient = mpdu->GetOriginal()->GetHeader().GetAddr1();
 
  518    const auto tid = mpdu->GetHeader().GetQosTid();
 
  522    NS_ASSERT(it->second.first.IsEstablished());
 
  524    it->second.first.NotifyAckedMpdu(mpdu);
 
  531    for (
auto queueIt = it->second.second.begin(); queueIt != it->second.second.end(); ++queueIt)
 
  533        if ((*queueIt)->GetHeader().GetSequenceNumber() == mpdu->GetHeader().GetSequenceNumber())
 
  535            m_queue->DequeueIfQueued({*queueIt});
 
 
  547    NS_ASSERT(mpdu->GetHeader().IsQosData());
 
  548    const auto tid = mpdu->GetHeader().GetQosTid();
 
  549    const auto gcrGroupAddr = mpdu->GetHeader().GetAddr1();
 
  550    for (
const auto& recipient : recipients)
 
  554        NS_ASSERT(it->second.first.IsEstablished());
 
  555        it->second.first.NotifyAckedMpdu(mpdu);
 
 
  563    NS_ASSERT(mpdu->GetHeader().IsQosData());
 
  565    const auto recipient = mpdu->GetOriginal()->GetHeader().GetAddr1();
 
  566    const auto tid = mpdu->GetHeader().GetQosTid();
 
  570    NS_ASSERT(it->second.first.IsEstablished());
 
  574    for (
auto queueIt = it->second.second.begin(); queueIt != it->second.second.end(); ++queueIt)
 
  576        if ((*queueIt)->GetHeader().GetSequenceNumber() == mpdu->GetHeader().GetSequenceNumber())
 
 
  584std::pair<uint16_t, uint16_t>
 
  588                                   const std::set<uint8_t>& tids,
 
  611    uint16_t nSuccessfulMpdus = 0;
 
  612    uint16_t nFailedMpdus = 0;
 
  614    if (it->second.first.m_inactivityEvent.IsPending())
 
  619        it->second.first.m_inactivityEvent.Cancel();
 
  621        it->second.first.m_inactivityEvent =
 
  632    std::list<Ptr<const WifiMpdu>> acked;
 
  634    for (
auto queueIt = it->second.second.begin(); queueIt != it->second.second.end();)
 
  636        uint16_t currentSeq = (*queueIt)->GetHeader().GetSequenceNumber();
 
  640            it->second.first.NotifyAckedMpdu(*queueIt);
 
  646            acked.emplace_back(*queueIt);
 
  656    m_queue->DequeueIfQueued(acked);
 
  659    for (
auto queueIt = it->second.second.begin(); queueIt != it->second.second.end();)
 
  663        auto linkIds = (*queueIt)->GetInFlightLinkIds();
 
  665        if (linkIds.size() == 1 && *linkIds.begin() == linkId)
 
  679    return {nSuccessfulMpdus, nFailedMpdus};
 
 
  682std::optional<std::pair<uint16_t, uint16_t>>
 
  691                    "Received GCR Block Ack response from unexpected recipient");
 
  700    NS_ASSERT_MSG(it->second.first.GetGcrGroupAddress().has_value() &&
 
  701                      it->second.first.GetGcrGroupAddress().value() ==
 
  704    if (it->second.first.m_inactivityEvent.IsPending())
 
  709        it->second.first.m_inactivityEvent.Cancel();
 
  711        it->second.first.m_inactivityEvent =
 
  722    NS_ASSERT(itGcrBlockAcks->second.count(recipient) == 0);
 
  723    itGcrBlockAcks->second[recipient] = blockAck;
 
  725    if (itGcrBlockAcks->second.size() < members.size())
 
  732    std::vector<bool> acked;
 
  733    for (
auto queueIt = it->second.second.begin(); queueIt != it->second.second.end(); ++queueIt)
 
  735        auto currentSeq = (*queueIt)->GetHeader().GetSequenceNumber();
 
  737        auto received = 
true;
 
  738        for ([[maybe_unused]] 
const auto& [recipient, gcrBlockAcks] : itGcrBlockAcks->second)
 
  740            received &= gcrBlockAcks.IsPacketReceived(currentSeq, 0);
 
  742        acked.emplace_back(received);
 
  745    uint16_t nSuccessfulMpdus = 0;
 
  746    uint16_t nFailedMpdus = 0;
 
  748    std::list<Ptr<const WifiMpdu>> ackedMpdus;
 
  749    auto countAndNotify = 
true;
 
  750    for (
const auto& member : members)
 
  752        std::size_t index = 0;
 
  754        NS_ASSERT(acked.size() == it->second.second.size());
 
  755        for (
auto queueIt = it->second.second.begin(); queueIt != it->second.second.end();)
 
  757            if (acked.at(index++))
 
  759                it->second.first.NotifyAckedMpdu(*queueIt);
 
  767                    ackedMpdus.emplace_back(*queueIt);
 
  776        countAndNotify = 
false;
 
  780    m_queue->DequeueIfQueued(ackedMpdus);
 
  783    countAndNotify = 
true;
 
  784    for (
const auto& member : members)
 
  787        for (
auto queueIt = it->second.second.begin(); queueIt != it->second.second.end();)
 
  791            auto linkIds = (*queueIt)->GetInFlightLinkIds();
 
  793            if (linkIds.size() == 1 && *linkIds.begin() == linkId)
 
  809        countAndNotify = 
false;
 
  812    itGcrBlockAcks->second.clear();
 
  813    return std::make_pair(nSuccessfulMpdus, nFailedMpdus);
 
 
  831    for (
auto mpduIt = it->second.second.begin(); mpduIt != it->second.second.end();)
 
  834        auto linkIds = (*mpduIt)->GetInFlightLinkIds();
 
  835        if (!linkIds.contains(linkId))
 
 
  848    if (!mpdu->GetHeader().IsQosData())
 
  854    if (!mpdu->GetHeader().IsRetry() && !mpdu->IsInFlight())
 
  860    const auto recipient = mpdu->GetOriginal()->GetHeader().GetAddr1();
 
  861    const auto tid = mpdu->GetHeader().GetQosTid();
 
  862    if (!recipient.IsGroup())
 
  869        const auto groupAddress = mpdu->GetOriginal()->GetHeader().GetAddr1();
 
  872            if (it->first.second != tid || !it->second.first.GetGcrGroupAddress().has_value() ||
 
  873                it->second.first.GetGcrGroupAddress().value() != groupAddress)
 
 
  891    auto& [baAgreement, packetQueue] = iter->second;
 
  892    if (
const auto currStartingSeq = baAgreement.GetStartingSequence();
 
  900    baAgreement.NotifyDiscardedMpdu(mpdu);
 
  904    for (
auto mpduIt = iter->second.second.begin(); mpduIt != iter->second.second.end();)
 
  906        if (baAgreement.GetDistance((*mpduIt)->GetHeader().GetSequenceNumber()) >=
 
  910            m_queue->DequeueIfQueued({*mpduIt});
 
  915            mpduIt = packetQueue.erase(mpduIt);
 
  924    const auto [recipient, tid] = iter->first;
 
  925    NS_LOG_DEBUG(
"Schedule a Block Ack Request for agreement (" << recipient << 
", " << +tid
 
  931    hdr.
SetAddr2(mpdu->GetOriginal()->GetHeader().GetAddr2());
 
 
  943                                          uint16_t startingSeq,
 
  944                                          std::optional<Mac48Address> gcrGroupAddr)
 
  946    NS_LOG_FUNCTION(
this << originator << tid << startingSeq << gcrGroupAddr.has_value());
 
  950        it->second.NotifyReceivedBar(startingSeq);
 
 
  958    NS_ASSERT(mpdu->GetHeader().IsQosData());
 
  959    const auto originator = mpdu->GetOriginal()->GetHeader().GetAddr2();
 
  960    const auto tid = mpdu->GetHeader().GetQosTid();
 
  961    std::optional<Mac48Address> groupAddress;
 
  962    if (
const auto addr1 = mpdu->GetOriginal()->GetHeader().GetAddr1(); addr1.IsGroup())
 
  965            mpdu->GetHeader().IsQosAmsdu() ? mpdu->begin()->second.GetDestinationAddr() : addr1;
 
  970        it->second.NotifyReceivedMpdu(mpdu);
 
 
  977                                      std::optional<Mac48Address> gcrGroupAddr)
 const 
  982    if (gcrGroupAddr.has_value())
 
  989        reqHdr.
SetType((*it).second.first.GetBlockAckReqType());
 
 
 1005    pkt->AddHeader(reqHdr);
 
 1009    while ((item = 
m_queue->PeekByQueueId(queueId, item)))
 
 1011        if (item->GetHeader().IsBlockAckReq() && item->GetHeader().GetAddr1() == hdr.
GetAddr1())
 
 1014            item->GetPacket()->PeekHeader(otherHdr);
 
 
 1028const std::list<BlockAckManager::AgreementKey>&
 
 1057                                   std::optional<Mac48Address> gcrGroupAddr)
 
 1059    NS_LOG_FUNCTION(
this << recipient << tid << gcrGroupAddr.has_value());
 
 
 1066                                                   std::optional<Mac48Address> gcrGroupAddr)
 
 1068    NS_LOG_FUNCTION(
this << recipient << tid << gcrGroupAddr.has_value());
 
 1071    if (!it->second.first.IsRejected())
 
 1079    if (!gcrGroupAddr.has_value())
 
 
 1088                                                  std::optional<Mac48Address> gcrGroupAddr)
 
 1090    NS_LOG_FUNCTION(
this << recipient << tid << gcrGroupAddr.has_value());
 
 1093    if (!it->second.first.IsNoReply())
 
 1101    if (!gcrGroupAddr.has_value())
 
 
 1110                                                std::optional<Mac48Address> gcrGroupAddr)
 
 1112    NS_LOG_FUNCTION(
this << recipient << tid << gcrGroupAddr.has_value());
 
 1115    if (!it->second.first.IsReset())
 
 1123    if (gcrGroupAddr.has_value())
 
 
 1150    for (
auto mpduIt = it->second.second.begin(); mpduIt != it->second.second.end();)
 
 1155        if (mpduIt != it->second.second.begin())
 
 
 1231    uint16_t seqNum = 0;
 
 1234        if (key.second != tid)
 
 1238        if (pair.first.GetGcrGroupAddress() == groupAddress)
 
 1240            seqNum = pair.first.GetStartingSequence();
 
 
 1255    uint16_t gcrBufferSize = std::numeric_limits<uint16_t>::max();
 
 1258        if ((key.second == tid) && (pair.first.GetGcrGroupAddress() == groupAddress))
 
 1260            gcrBufferSize = std::min(pair.first.GetBufferSize(), gcrBufferSize);
 
 1263    return gcrBufferSize;
 
 
 1272    for (
const auto& member : members)
 
 1275            !agreement || !agreement->get().IsEstablished())
 
 
uint16_t GetTimeout() const
Return the timeout.
void SetGcrGroupAddress(const Mac48Address &gcrGroupAddress)
Set the GCR group address for this agreement.
void SetImmediateBlockAck()
Set block ack policy to immediate Ack.
void SetStartingSequence(uint16_t seq)
Set starting sequence number.
EventId m_inactivityEvent
inactivity event
void SetBufferSize(uint16_t bufferSize)
Set buffer size.
void SetDelayedBlockAck()
Set block ack policy to delayed Ack.
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support.
void SetTimeout(uint16_t timeout)
Set timeout.
void SetHtSupported(bool htSupported)
Enable or disable HT support.
Manages all block ack agreements for an originator station.
std::optional< std::pair< uint16_t, uint16_t > > NotifyGotGcrBlockAck(uint8_t linkId, const CtrlBAckResponseHeader &blockAck, const Mac48Address &recipient, const GcrManager::GcrMembers &members)
void SetTxFailedCallback(TxFailed callback)
std::pair< Mac48Address, uint8_t > AgreementKey
agreement key typedef (MAC address and TID)
void UpdateOriginatorAgreement(const MgtAddBaResponseHeader &respHdr, const Mac48Address &recipient, uint16_t startingSeq)
Callback< void, Mac48Address, uint8_t > m_unblockPackets
unblock packets callback
OriginatorAgreements::iterator OriginatorAgreementsI
An iterator for originator block ack agreements.
void SetQueue(const Ptr< WifiMacQueue > queue)
void SetTxOkCallback(TxOk callback)
std::map< Mac48Address, CtrlBAckResponseHeader > GcrBlockAcks
List of received GCR BlockAck frames indexed by originator.
OriginatorAgreementsI GetOriginatorBaAgreement(const Mac48Address &recipient, uint8_t tid, std::optional< Mac48Address > gcrGroupAddr=std::nullopt)
CtrlBAckRequestHeader GetBlockAckReqHeader(const Mac48Address &recipient, uint8_t tid, std::optional< Mac48Address > gcrGroupAddr=std::nullopt) const
void NotifyOriginatorAgreementNoReply(const Mac48Address &recipient, uint8_t tid, std::optional< Mac48Address > gcrGroupAddr)
uint8_t m_blockAckThreshold
block ack threshold
void NotifyLastGcrUrTx(Ptr< const WifiMpdu > mpdu, const GcrManager::GcrMembers &recipients)
Notify the block ack manager about the last groupcast MPDU transmitted with the GCR-UR service.
RecipientAgreements m_recipientAgreements
Recipient Block Ack agreements.
~BlockAckManager() override
static TypeId GetTypeId()
Get the type ID.
TracedCallback< Time, Mac48Address, uint8_t, OriginatorBlockAckAgreement::State > m_originatorAgreementState
The trace source fired when a state transition occurred.
void SetBlockAckThreshold(uint8_t nPackets)
DroppedOldMpdu m_droppedOldMpduCallback
the dropped MPDU callback
std::list< Ptr< WifiMpdu > > PacketQueue
typedef for a list of WifiMpdu.
void SetDroppedOldMpduCallback(DroppedOldMpdu callback)
TxFailed m_txFailedCallback
transmit failed callback
void SetUnblockDestinationCallback(Callback< void, Mac48Address, uint8_t > callback)
Set unblock destination callback.
std::optional< std::reference_wrapper< const OriginatorBlockAckAgreement > > OriginatorAgreementOptConstRef
optional const reference to OriginatorBlockAckAgreement
Ptr< WifiMacQueue > m_queue
queue
RecipientAgreements::iterator RecipientAgreementsI
An iterator for recipient block ack agreements.
uint16_t GetRecipientBufferSize(const Mac48Address &recipient, uint8_t tid) const
This function returns the buffer size negotiated with the recipient.
void NotifyOriginatorAgreementRejected(const Mac48Address &recipient, uint8_t tid, std::optional< Mac48Address > gcrGroupAddr)
void CreateOriginatorAgreement(const MgtAddBaRequestHeader &reqHdr, const Mac48Address &recipient)
void CreateRecipientAgreement(const MgtAddBaResponseHeader &respHdr, const Mac48Address &originator, uint16_t startingSeq, Ptr< MacRxMiddle > rxMiddle)
Callback< void, Mac48Address, uint8_t, bool, std::optional< Mac48Address > > m_blockAckInactivityTimeout
BlockAck inactivity timeout callback.
OriginatorAgreements::const_iterator OriginatorAgreementsCI
A const iterator for originator block ack agreements.
void DestroyOriginatorAgreement(const Mac48Address &recipient, uint8_t tid, std::optional< Mac48Address > gcrGroupAddr)
bool NeedGcrBarRetransmission(const Mac48Address &gcrGroupAddress, const Mac48Address &recipient, uint8_t tid) const
This function returns true if a GCR block ack agreement is established with the given recipient,...
void NotifyMissedBlockAck(uint8_t linkId, const Mac48Address &recipient, uint8_t tid)
OriginatorAgreements m_originatorAgreements
This data structure contains, for each originator block ack agreement (recipient, TID),...
void StorePacket(Ptr< WifiMpdu > mpdu)
void RemoveFromSendBarIfDataQueuedList(const Mac48Address &recipient, uint8_t tid)
Remove the given (recipient, TID) pair from the list of BA agreements for which a BAR shall only be s...
void NotifyGotAck(uint8_t linkId, Ptr< const WifiMpdu > mpdu)
Invoked upon receipt of an Ack frame on the given link after the transmission of a QoS data frame sen...
void AddToSendBarIfDataQueuedList(const Mac48Address &recipient, uint8_t tid)
Add the given (recipient, TID) pair to the list of BA agreements for which a BAR shall only be sent i...
void NotifyDiscardedMpdu(Ptr< const WifiMpdu > mpdu)
bool IsGcrAgreementEstablished(const Mac48Address &gcrGroupAddress, uint8_t tid, const GcrManager::GcrMembers &members) const
Check if a GCR Block Ack agreement has been successfully established with all members of the group.
void NotifyGotMpdu(Ptr< const WifiMpdu > mpdu)
void HandleDiscardedMpdu(Ptr< const WifiMpdu > mpdu, OriginatorAgreementsI iter)
Handle discarded MPDU by making the transmit window advance beyond the discarded frame.
bool NeedBarRetransmission(uint8_t tid, const Mac48Address &recipient)
This function returns true if a block ack agreement is established with the given recipient for the g...
void SetBlockDestinationCallback(Callback< void, Mac48Address, uint8_t > callback)
Set block destination callback.
void NotifyOriginatorAgreementReset(const Mac48Address &recipient, uint8_t tid, std::optional< Mac48Address > gcrGroupAddr)
std::list< AgreementKey > m_sendBarIfDataQueued
list of BA agreements for which a BAR shall only be sent if data is queued
void DestroyRecipientAgreement(const Mac48Address &originator, uint8_t tid, std::optional< Mac48Address > gcrGroupAddr)
Destroy a recipient Block Ack agreement.
uint32_t GetNBufferedPackets(const Mac48Address &recipient, uint8_t tid) const
PacketQueueI HandleInFlightMpdu(uint8_t linkId, PacketQueueI mpduIt, MpduStatus status, const OriginatorAgreementsI &it, const Time &now)
Handle the given in flight MPDU based on its given status.
std::list< Ptr< WifiMpdu > >::iterator PacketQueueI
typedef for an iterator for PacketQueue.
void SetBlockAckInactivityCallback(Callback< void, Mac48Address, uint8_t, bool, std::optional< Mac48Address > > callback)
Set block ack inactivity callback.
OriginatorAgreementOptConstRef GetAgreementAsOriginator(const Mac48Address &recipient, uint8_t tid, std::optional< Mac48Address > gcrGroupAddr=std::nullopt) const
RecipientAgreements::const_iterator RecipientAgreementsCI
A const iterator for recipient block ack agreements.
uint16_t GetOriginatorStartingSequence(const Mac48Address &recipient, uint8_t tid) const
This function returns the starting sequence number of the transmit window.
void NotifyGotBlockAckRequest(const Mac48Address &originator, uint8_t tid, uint16_t startingSeq, std::optional< Mac48Address > gcrGroupAddr=std::nullopt)
uint16_t GetGcrStartingSequence(const Mac48Address &groupAddress, uint8_t tid) const
This function returns the starting sequence number of the transmit window for a given GCR Block Ack a...
uint16_t GetGcrBufferSize(const Mac48Address &groupAddress, uint8_t tid) const
This function returns the minimum buffer size from ADDBA Response frames sent by all members of a gro...
TxOk m_txOkCallback
transmit OK callback
MpduStatus
Enumeration for the statuses of a buffered MPDU.
std::pair< uint16_t, uint16_t > NotifyGotBlockAck(uint8_t linkId, const CtrlBAckResponseHeader &blockAck, const Mac48Address &recipient, const std::set< uint8_t > &tids, size_t index=0)
void DoDispose() override
Destructor implementation.
std::optional< std::reference_wrapper< const RecipientBlockAckAgreement > > RecipientAgreementOptConstRef
optional const reference to RecipientBlockAckAgreement
void ScheduleBar(const CtrlBAckRequestHeader &reqHdr, const WifiMacHeader &hdr)
void InactivityTimeout(const Mac48Address &recipient, uint8_t tid, std::optional< Mac48Address > gcrGroupAddr)
Inactivity timeout function for a Block Ack agreement.
Callback< void, Mac48Address, uint8_t > m_blockPackets
block packets callback
void DoStorePacket(Ptr< WifiMpdu > mpdu, const Mac48Address &recipient, std::optional< Mac48Address > gcrGroupAddr=std::nullopt)
void StoreGcrPacket(Ptr< WifiMpdu > mpdu, const GcrManager::GcrMembers &members)
RecipientAgreementsI GetRecipientBaAgreement(const Mac48Address &originator, uint8_t tid, std::optional< Mac48Address > gcrGroupAddr=std::nullopt)
RecipientAgreementOptConstRef GetAgreementAsRecipient(const Mac48Address &originator, uint8_t tid, std::optional< Mac48Address > gcrGroupAddr=std::nullopt) const
const std::list< AgreementKey > & GetSendBarIfDataQueuedList() const
std::map< Mac48Address, GcrBlockAcks > m_gcrBlockAcks
received GCR Block ACKs
void NotifyMissedAck(uint8_t linkId, Ptr< WifiMpdu > mpdu)
Invoked upon missed reception of an Ack frame on the given link after the transmission of a QoS data ...
bool IsNull() const
Check for null implementation.
std::unordered_set< Mac48Address, WifiAddressHash > GcrMembers
MAC addresses of member STAs of a GCR group.
A base class which provides memory management and object aggregation.
Maintains the state and information about transmitted MPDUs with Ack Policy set to Block Ack for an o...
void SetState(State state)
Set the current state.
void InitTxWindow()
Initialize the originator's transmit window by setting its size and starting sequence number equal to...
Smart pointer class similar to boost::intrusive_ptr.
Maintains the scoreboard and the receive reordering buffer used by a recipient of a Block Ack agreeme...
void SetMacRxMiddle(const Ptr< MacRxMiddle > rxMiddle)
Set the MAC RX Middle to use.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static Time Now()
Return the current simulation virtual time.
Simulation virtual time values and global simulation resolution.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
#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(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.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
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 constexpr uint16_t SEQNO_SPACE_HALF_SIZE
Size of the half the space of sequence numbers (used to determine old packets)
std:: tuple< WifiContainerQueueType, WifiReceiverAddressType, Mac48Address, std::optional< uint8_t > > WifiContainerQueueId
Tuple (queue type, receiver address type, Address, TID) identifying a container queue.
static constexpr uint8_t SINGLE_LINK_OP_ID
Link ID for single link operations (helps tracking places where correct link ID is to be used to supp...