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 ());
129 agreement.SetImmediateBlockAck ();
133 agreement.SetDelayedBlockAck ();
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 ());
664 reqHdr.SetTidInfo (tid);
665 reqHdr.SetStartingSequence ((*it).second.first.GetStartingSequence ());
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 SetUnblockDestinationCallback(Callback< void, Mac48Address, uint8_t > callback)
Set unblock destination callback.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
BlockAckType GetBlockAckType(Mac48Address recipient, uint8_t tid) const
This function returns the type of Block Acks sent by the recipient.
Simulation virtual time values and global simulation resolution.
Smart pointer class similar to boost::intrusive_ptr.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void NotifyMissedBlockAck(Mac48Address recipient, uint8_t tid)
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
Maintains the state and information about transmitted MPDUs with Ack Policy set to Block Ack for an o...
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...
std::list< Ptr< WifiMacQueueItem > >::iterator PacketQueueI
typedef for an iterator for PacketQueue.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
std::map< std::pair< Mac48Address, uint8_t >, std::pair< OriginatorBlockAckAgreement, PacketQueue > >::const_iterator AgreementsCI
typedef for a const iterator for Agreements.
void CreateAgreement(const MgtAddBaRequestHeader *reqHdr, Mac48Address recipient)
uint32_t GetNBufferedPackets(Mac48Address recipient, uint8_t tid) const
void ScheduleBar(Ptr< const WifiMacQueueItem > bar, bool skipIfNoDataQueued=false)
TracedCallback< Time, Mac48Address, uint8_t, OriginatorBlockAckAgreement::State > m_agreementState
The trace source fired when a state transition occurred.
uint8_t m_blockAckThreshold
block ack threshold
Agreements m_agreements
This data structure contains, for each block ack agreement (recipient, TID), a set of packets for whi...
void NotifyMissedAck(Ptr< WifiMacQueueItem > mpdu)
Invoked upon missed reception of an Ack frame after the transmission of a QoS data frame sent under a...
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
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...
const uint16_t SEQNO_SPACE_HALF_SIZE
Size of the half the space of sequence numbers (used to determine old packets)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
std::map< std::pair< Mac48Address, uint8_t >, std::pair< OriginatorBlockAckAgreement, PacketQueue > >::iterator AgreementsI
typedef for an iterator for Agreements.
BlockAckReqType GetBlockAckReqType(Mac48Address recipient, uint8_t tid) const
This function returns the type of Block Acks sent to the recipient.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
bool QosUtilsIsOldPacket(uint16_t startingSeq, uint16_t seqNumber)
This function checks if packet with sequence number seqNumber is an "old" packet. ...
The different BlockAckRequest variants.
CtrlBAckRequestHeader GetBlockAckReqHeader(Mac48Address recipient, uint8_t tid) const
BlockAckRequest frame information.
TxOk m_txOkCallback
transmit OK callback
bool ExistsAgreementInState(Mac48Address recipient, uint8_t tid, OriginatorBlockAckAgreement::State state) const
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
void RemoveFromRetryQueue(Mac48Address address, uint8_t tid, uint16_t seq)
Remove an item from retransmission queue.
void SetTxFailedCallback(TxFailed callback)
void NotifyGotBlockAck(const CtrlBAckResponseHeader &blockAck, Mac48Address recipient, const std::set< uint8_t > &tids, double rxSnr, double dataSnr, const WifiTxVector &dataTxVector, size_t index=0)
void NotifyDiscardedMpdu(Ptr< const WifiMacQueueItem > mpdu)
Ptr< WifiMacQueue > GetRetransmitQueue(void)
const WifiMacHeader & GetHeader(void) const
Get the header stored in this item.
void NotifyAgreementEstablished(Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
uint16_t GetTimeout(void) const
Return the timeout.
void SetQueue(const Ptr< WifiMacQueue > queue)
void SetWifiRemoteStationManager(const Ptr< WifiRemoteStationManager > manager)
Set up WifiRemoteStationManager associated with this BlockAckManager.
static TypeId GetTypeId(void)
Get the type ID.
bool GetHtSupported(void) const
Return whether the device has HT capability support enabled.
static Mac48Address GetBroadcast(void)
void NotifyAgreementRejected(Mac48Address recipient, uint8_t tid)
bool ExistsAgreement(Mac48Address recipient, uint8_t tid) const
std::list< Ptr< WifiMacQueueItem > >::const_iterator PacketQueueCI
typedef for a const iterator for PacketQueue.
void SetBlockDestinationCallback(Callback< void, Mac48Address, uint8_t > callback)
Set block destination callback.
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...
void DestroyAgreement(Mac48Address recipient, uint8_t tid)
static const ConstIterator EMPTY
Invalid iterator to signal an empty queue.
void SetState(State state)
Set the current state.
void SetTxOkCallback(TxOk callback)
bool HasPackets(void)
Returns true if there are packets that need of retransmission or at least a BAR is scheduled...
uint16_t GetRecipientBufferSize(Mac48Address recipient, uint8_t tid) const
This function returns the buffer size negotiated with the recipient.
void InsertInRetryQueue(Ptr< WifiMacQueueItem > mpdu)
void SetStartingSequence(uint16_t seq)
Set starting sequence number.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void InactivityTimeout(Mac48Address recipient, uint8_t tid)
Inactivity timeout function.
Callback< void, Mac48Address, uint8_t, bool > m_blockAckInactivityTimeout
BlockAck inactivity timeout callback.
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...
void DiscardOutstandingMpdus(Mac48Address recipient, uint8_t tid)
Callback< void, Mac48Address, uint8_t > m_blockPackets
block packets callback
void StorePacket(Ptr< WifiMacQueueItem > mpdu)
std::list< Ptr< WifiMacQueueItem > > PacketQueue
typedef for a list of WifiMacQueueItem.
Ptr< WifiMacQueue > m_retryPackets
This list contains all iterators to stored packets that need to be retransmitted. ...
static Time Now(void)
Return the current simulation virtual time.
State
Represents the state for this agreement.
void NotifyAgreementReset(Mac48Address recipient, uint8_t tid)
void SetBlockAckInactivityCallback(Callback< void, Mac48Address, uint8_t, bool > callback)
Set block ack inactivity callback.
uint16_t GetOriginatorStartingSequence(Mac48Address recipient, uint8_t tid) const
This function returns the starting sequence number of the transmit window.
void SetDelayedBlockAck(void)
Set block ack policy to delayed Ack.
EventId m_inactivityEvent
inactivity event
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support.
bool SwitchToBlockAckIfNeeded(Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
Callback< void, Mac48Address, uint8_t > m_unblockPackets
unblock packets callback
The different BlockAck variants.
std::list< Bar > m_bars
list of BARs
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Ptr< const WifiMacQueueItem > bar
BlockAckRequest or MU-BAR Trigger Frame.
uint8_t tid
TID (unused if MU-BAR)
void SetBlockAckThreshold(uint8_t nPackets)
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
void UpdateAgreement(const MgtAddBaResponseHeader *respHdr, Mac48Address recipient, uint16_t startingSeq)
void NotifyAgreementNoReply(Mac48Address recipient, uint8_t tid)
const uint16_t SEQNO_SPACE_SIZE
Size of the space of sequence numbers.
void SetImmediateBlockAck(void)
Set block ack policy to immediate Ack.
void SetTimeout(uint16_t timeout)
Set timeout.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
A base class which provides memory management and object aggregation.
Manages all block ack agreements for an originator station.
bool IsNull(void) const
Check for null implementation.
TxFailed m_txFailedCallback
transmit failed callback
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.
Ptr< WifiRemoteStationManager > m_stationManager
the station manager
void SetBufferSize(uint16_t bufferSize)
Set buffer size.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
bool skipIfNoDataQueued
do not send if there is no data queued (unused if MU-BAR)
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...
void InitTxWindow(void)
Initialize the originator's transmit window by setting its size and starting sequence number equal to...
void AddHeader(const Header &header)
Add header to this packet.
Ptr< WifiMacQueue > m_queue
queue