22 #include "ns3/simulator.h"
43 skipIfNoDataQueued (skipIfNoDataQueued)
55 .SetGroupName (
"Wifi")
57 .AddTraceSource (
"AgreementState",
58 "The state of the ADDBA handshake",
60 "ns3::BlockAckManager::AgreementStateTracedCallback")
92 it =
m_agreements.find (std::make_pair (recipient, tid));
98 return it->second.first.IsEstablished ();
100 return it->second.first.IsPending ();
102 return it->second.first.IsRejected ();
104 return it->second.first.IsNoReply ();
106 return it->second.first.IsReset ();
118 std::pair<Mac48Address, uint8_t> key (recipient, reqHdr->
GetTid ());
135 uint8_t tid = reqHdr->
GetTid ();
139 std::pair<OriginatorBlockAckAgreement, PacketQueue> value (agreement, queue);
159 if ((*i)->GetHeader ().GetAddr1 () == recipient && (*i)->GetHeader ().GetQosTid () == tid)
170 for (std::list<Bar>::const_iterator i =
m_bars.begin (); i !=
m_bars.end (); )
172 if (i->bar->GetHeader ().GetAddr1 () == recipient && i->tid == tid)
186 uint16_t startingSeq)
189 uint8_t tid = respHdr->
GetTid ();
207 if (!it->second.first.IsEstablished ())
253 while (it != agreementIt->second.second.end ())
257 NS_LOG_DEBUG (
"Packet already in the queue of the BA agreement");
261 uint16_t dist = agreementIt->second.first.GetDistance ((*it)->GetHeader ().GetSequenceNumber ());
263 if (mpduDist < dist ||
271 agreementIt->second.second.insert (it, mpdu);
272 agreementIt->second.first.NotifyTransmittedMpdu (mpdu);
283 auto nextBar =
m_bars.begin ();
285 while (nextBar !=
m_bars.end ())
287 Mac48Address recipient = nextBar->bar->GetHeader ().GetAddr1 ();
290 && (!nextBar->bar->GetHeader ().IsBlockAckReq ()
291 ||
address != recipient || tid != nextBar->tid))
297 if (nextBar->bar->GetHeader ().IsBlockAckReq ())
303 nextBar =
m_bars.erase (nextBar);
306 if (nextBar->skipIfNoDataQueued
308 &&
m_queue->PeekByTidAndAddress (nextBar->tid, recipient) ==
m_queue->end ())
315 for (
auto mpduIt = it->second.second.begin (); mpduIt != it->second.second.end (); )
320 it->second.first.NotifyDiscardedMpdu (*mpduIt);
321 mpduIt = it->second.second.erase (mpduIt);
330 nextBar->bar->GetPacket ()->PeekHeader (reqHdr);
336 nextBar->bar = Create<const WifiMacQueueItem> (packet, nextBar->bar->GetHeader ());
366 uint32_t nPackets = 0;
368 while (queueIt != (*it).second.second.end ())
370 uint16_t currentSeq = (*queueIt)->GetHeader ().GetSequenceNumber ();
373 while (queueIt != (*it).second.second.end () && (*queueIt)->GetHeader ().GetSequenceNumber () == currentSeq)
399 NS_ASSERT (mpdu->GetHeader ().IsQosData ());
401 Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
402 uint8_t tid = mpdu->GetHeader ().GetQosTid ();
410 while (queueIt != it->second.second.end ())
412 if ((*queueIt)->GetHeader ().GetSequenceNumber () == mpdu->GetHeader ().GetSequenceNumber ())
414 queueIt = it->second.second.erase (queueIt);
422 it->second.first.NotifyAckedMpdu (mpdu);
441 while (queueIt != it->second.second.end ())
445 queueIt = it->second.second.erase (queueIt);
459 const std::set<uint8_t>& tids,
double rxSnr,
double dataSnr,
462 NS_LOG_FUNCTION (
this << blockAck << recipient << rxSnr << dataSnr << dataTxVector << index);
471 tid = *tids.begin ();
475 bool foundFirstLost =
false;
476 uint16_t nSuccessfulMpdus = 0;
477 uint16_t nFailedMpdus = 0;
481 if (it->second.first.m_inactivityEvent.IsRunning ())
486 it->second.first.m_inactivityEvent.Cancel ();
494 uint16_t currentStartingSeq = it->second.first.GetStartingSequence ();
499 for (
PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd; )
501 currentSeq = (*queueIt)->GetHeader ().GetSequenceNumber ();
503 (*queueIt)->GetHeader ().GetFragmentNumber ()))
511 foundFirstLost =
true;
518 queueIt = it->second.second.erase (queueIt);
528 for (
PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd; )
530 currentSeq = (*queueIt)->GetHeader ().GetSequenceNumber ();
533 it->second.first.NotifyAckedMpdu (*queueIt);
550 queueIt = it->second.second.erase (queueIt);
570 for (
auto& item : it->second.second)
577 it->second.second.clear ();
588 while (!it->second.second.empty ())
594 it->second.second.pop_front ();
609 if (!mpdu->GetHeader ().IsQosData ())
615 Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
616 uint8_t tid = mpdu->GetHeader ().GetQosTid ();
624 uint16_t currStartingSeq = it->second.first.GetStartingSequence ();
635 it->second.first.NotifyDiscardedMpdu (mpdu);
638 NS_LOG_DEBUG (
"Schedule a Block Ack Request for agreement (" << recipient <<
", " << +tid <<
")");
645 hdr.
SetAddr2 (mpdu->GetHeader ().GetAddr2 ());
646 hdr.
SetAddr3 (mpdu->GetHeader ().GetAddr3 ());
652 ScheduleBar (Create<const WifiMacQueueItem> (bar, hdr));
663 reqHdr.
SetType ((*it).second.first.GetBlockAckReqType ());
673 NS_ASSERT (bar->GetHeader ().IsBlockAckReq () || bar->GetHeader ().IsTrigger ());
676 if (bar->GetHeader ().IsBlockAckReq ())
679 bar->GetPacket ()->PeekHeader (reqHdr);
682 #ifdef NS3_BUILD_PROFILE_DEBUG
686 bar->GetPacket ()->PeekHeader (triggerHdr);
690 Bar request (bar, tid, skipIfNoDataQueued);
693 std::list<Bar>::const_iterator i =
m_bars.end ();
695 if (bar->GetHeader ().IsBlockAckReq ())
699 if (i->bar->GetHeader ().IsBlockAckReq ()
700 && i->bar->GetHeader ().GetAddr1 () == bar->GetHeader ().GetAddr1 () && i->tid == tid)
708 if (bar->GetHeader ().IsRetry ())
710 m_bars.push_front (request);
714 m_bars.insert (i, request);
731 if (!it->second.first.IsEstablished ())
736 it->second.first.SetStartingSequence (startingSeq);
745 if (!it->second.first.IsRejected ())
758 if (!it->second.first.IsNoReply ())
772 if (!it->second.first.IsReset ())
793 uint32_t packets =
m_queue->GetNPacketsByTidAndAddress (tid, recipient) +
812 for (
auto& mpdu : it->second.second)
845 uint16_t itSeq = (*it)->GetHeader ().GetSequenceNumber ();
847 if (agreementIt->second.first.GetDistance (itSeq) >= agreementIt->second.first.GetDistance (startSeq)
848 && agreementIt->second.first.GetDistance (itSeq) <= agreementIt->second.first.GetDistance (endSeq))
850 NS_LOG_DEBUG (
"Removing frame with seqnum = " << itSeq);
868 uint16_t currStartingSeq = agreementIt->second.first.GetStartingSequence ();
871 "The new starting sequence number is an old sequence number");
873 if (startingSeq == currStartingSeq)
884 while (it != agreementIt->second.second.end ())
886 uint16_t itSeq = (*it)->GetHeader ().GetSequenceNumber ();
888 if (agreementIt->second.first.GetDistance (itSeq) <= agreementIt->second.first.GetDistance (lastRemovedSeq))
890 NS_LOG_DEBUG (
"Removing frame with seqnum = " << itSeq);
891 it = agreementIt->second.second.erase (it);
953 WifiMacQueue::ConstIterator it =
m_retryPackets->PeekByTidAndAddress (tid, recipient);
959 NS_LOG_DEBUG (
"Packet already in the retransmit queue");
963 uint16_t dist = agreementIt->second.first.GetDistance ((*it)->GetHeader ().GetSequenceNumber ());
965 if (mpduDist < dist ||
984 size = it->second.first.GetBufferSize ();
994 return it->second.first.GetBlockAckReqType ();
1002 return it->second.first.GetBlockAckType ();
1008 uint16_t seqNum = 0;
1012 seqNum = it->second.first.GetStartingSequence ();
void SetImmediateBlockAck(void)
Set block ack policy to immediate Ack.
void SetStartingSequence(uint16_t seq)
Set starting sequence number.
void SetDelayedBlockAck(void)
Set block ack policy to delayed Ack.
uint16_t GetTimeout(void) const
Return the timeout.
EventId m_inactivityEvent
inactivity event
void SetBufferSize(uint16_t bufferSize)
Set buffer size.
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.
void StorePacket(Ptr< WifiMacQueueItem > mpdu)
std::list< Ptr< WifiMacQueueItem > >::iterator PacketQueueI
typedef for an iterator for PacketQueue.
void ScheduleBar(Ptr< const WifiMacQueueItem > bar, bool skipIfNoDataQueued=false)
void SetTxFailedCallback(TxFailed callback)
void NotifyAgreementRejected(Mac48Address recipient, uint8_t tid)
CtrlBAckRequestHeader GetBlockAckReqHeader(Mac48Address recipient, uint8_t tid) const
Callback< void, Mac48Address, uint8_t > m_unblockPackets
unblock packets callback
void SetQueue(const Ptr< WifiMacQueue > queue)
void SetTxOkCallback(TxOk callback)
bool SwitchToBlockAckIfNeeded(Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
uint8_t m_blockAckThreshold
block ack threshold
Ptr< WifiMacQueue > m_retryPackets
This list contains all iterators to stored packets that need to be retransmitted.
void SetBlockAckThreshold(uint8_t nPackets)
std::list< Ptr< WifiMacQueueItem > > PacketQueue
typedef for a list of WifiMacQueueItem.
void CreateAgreement(const MgtAddBaRequestHeader *reqHdr, Mac48Address recipient)
void NotifyAgreementEstablished(Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
void RemoveOldPackets(Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
Remove packets from the retransmit queue and from the queue of outstanding packets that become old af...
void DestroyAgreement(Mac48Address recipient, uint8_t tid)
void NotifyDiscardedMpdu(Ptr< const WifiMacQueueItem > mpdu)
void NotifyGotAck(Ptr< const WifiMacQueueItem > mpdu)
Invoked upon receipt of an Ack frame after the transmission of a QoS data frame sent under an establi...
TxFailed m_txFailedCallback
transmit failed callback
void SetUnblockDestinationCallback(Callback< void, Mac48Address, uint8_t > callback)
Set unblock destination callback.
Ptr< WifiMacQueue > m_queue
queue
void NotifyGotBlockAck(const CtrlBAckResponseHeader &blockAck, Mac48Address recipient, const std::set< uint8_t > &tids, double rxSnr, double dataSnr, const WifiTxVector &dataTxVector, size_t index=0)
BlockAckReqType GetBlockAckReqType(Mac48Address recipient, uint8_t tid) const
This function returns the type of Block Acks sent to the recipient.
void NotifyAgreementReset(Mac48Address recipient, uint8_t tid)
void NotifyMissedAck(Ptr< WifiMacQueueItem > mpdu)
Invoked upon missed reception of an Ack frame after the transmission of a QoS data frame sent under a...
TracedCallback< Time, Mac48Address, uint8_t, OriginatorBlockAckAgreement::State > m_agreementState
The trace source fired when a state transition occurred.
std::map< std::pair< Mac48Address, uint8_t >, std::pair< OriginatorBlockAckAgreement, PacketQueue > >::const_iterator AgreementsCI
typedef for a const iterator for Agreements.
void UpdateAgreement(const MgtAddBaResponseHeader *respHdr, Mac48Address recipient, uint16_t startingSeq)
Ptr< const WifiMacQueueItem > GetBar(bool remove=true, uint8_t tid=8, Mac48Address recipient=Mac48Address::GetBroadcast())
Returns the next BlockAckRequest or MU-BAR Trigger Frame to send, if any.
uint16_t GetRecipientBufferSize(Mac48Address recipient, uint8_t tid) const
This function returns the buffer size negotiated with the recipient.
void InactivityTimeout(Mac48Address recipient, uint8_t tid)
Inactivity timeout function.
bool ExistsAgreement(Mac48Address recipient, uint8_t tid) const
void NotifyAgreementNoReply(Mac48Address recipient, uint8_t tid)
bool NeedBarRetransmission(uint8_t tid, Mac48Address recipient)
This function returns true if a block ack agreement is established with the given recipient for the g...
BlockAckType GetBlockAckType(Mac48Address recipient, uint8_t tid) const
This function returns the type of Block Acks sent by the recipient.
static TypeId GetTypeId(void)
Get the type ID.
Agreements m_agreements
This data structure contains, for each block ack agreement (recipient, TID), a set of packets for whi...
void DiscardOutstandingMpdus(Mac48Address recipient, uint8_t tid)
void InsertInRetryQueue(Ptr< WifiMacQueueItem > mpdu)
void SetBlockDestinationCallback(Callback< void, Mac48Address, uint8_t > callback)
Set block destination callback.
void RemoveFromRetryQueue(Mac48Address address, uint8_t tid, uint16_t seq)
Remove an item from retransmission queue.
Ptr< WifiMacQueue > GetRetransmitQueue(void)
void SetBlockAckInactivityCallback(Callback< void, Mac48Address, uint8_t, bool > callback)
Set block ack inactivity callback.
std::list< Ptr< WifiMacQueueItem > >::const_iterator PacketQueueCI
typedef for a const iterator for PacketQueue.
bool ExistsAgreementInState(Mac48Address recipient, uint8_t tid, OriginatorBlockAckAgreement::State state) const
Callback< void, Mac48Address, uint8_t, bool > m_blockAckInactivityTimeout
BlockAck inactivity timeout callback.
std::map< std::pair< Mac48Address, uint8_t >, std::pair< OriginatorBlockAckAgreement, PacketQueue > >::iterator AgreementsI
typedef for an iterator for Agreements.
TxOk m_txOkCallback
transmit OK callback
void SetWifiRemoteStationManager(const Ptr< WifiRemoteStationManager > manager)
Set up WifiRemoteStationManager associated with this BlockAckManager.
bool HasPackets(void)
Returns true if there are packets that need of retransmission or at least a BAR is scheduled.
void NotifyMissedBlockAck(Mac48Address recipient, uint8_t tid)
uint32_t GetNBufferedPackets(Mac48Address recipient, uint8_t tid) const
Callback< void, Mac48Address, uint8_t > m_blockPackets
block packets callback
uint16_t GetOriginatorStartingSequence(Mac48Address recipient, uint8_t tid) const
This function returns the starting sequence number of the transmit window.
std::list< Bar > m_bars
list of BARs
Ptr< WifiRemoteStationManager > m_stationManager
the station manager
bool IsNull(void) const
Check for null implementation.
static Mac48Address GetBroadcast(void)
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 InitTxWindow(void)
Initialize the originator's transmit window by setting its size and starting sequence number equal to...
void SetState(State state)
Set the current state.
State
Represents the state for this agreement.
void AddHeader(const Header &header)
Add header to this packet.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static Time Now(void)
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.
static const ConstIterator EMPTY
Invalid iterator to signal an empty queue.
const WifiMacHeader & GetHeader(void) const
Get the header stored in this item.
void ReportAmpduTxStatus(Mac48Address address, uint16_t nSuccessfulMpdus, uint16_t nFailedMpdus, double rxSnr, double dataSnr, WifiTxVector dataTxVector)
Typically called per A-MPDU, either when a Block ACK was successfully received or when a BlockAckTime...
bool GetHtSupported(void) const
Return whether the device has HT capability support enabled.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#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_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.
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.
const uint16_t SEQNO_SPACE_SIZE
Size of the space of sequence numbers.
const uint16_t SEQNO_SPACE_HALF_SIZE
Size of the half the space of sequence numbers (used to determine old packets)
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
BlockAckRequest frame information.
uint8_t tid
TID (unused if MU-BAR)
bool skipIfNoDataQueued
do not send if there is no data queued (unused if MU-BAR)
Ptr< const WifiMacQueueItem > bar
BlockAckRequest or MU-BAR Trigger Frame.
The different BlockAckRequest variants.
The different BlockAck variants.