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...