22 #include "ns3/simulator.h" 42 recipient (recipient),
56 .SetGroupName (
"Wifi")
58 .AddTraceSource (
"AgreementState",
59 "The state of the ADDBA handshake",
61 "ns3::BlockAckManager::AgreementStateTracedCallback")
93 it =
m_agreements.find (std::make_pair (recipient, tid));
99 return it->second.first.IsEstablished ();
101 return it->second.first.IsPending ();
103 return it->second.first.IsRejected ();
105 return it->second.first.IsNoReply ();
107 return it->second.first.IsReset ();
119 std::pair<Mac48Address, uint8_t> key (recipient, reqHdr->
GetTid ());
125 agreement.SetWinEnd ((agreement.GetStartingSequence () + agreement.GetBufferSize () - 1) %
SEQNO_SPACE_SIZE);
131 agreement.SetImmediateBlockAck ();
135 agreement.SetDelayedBlockAck ();
137 uint8_t tid = reqHdr->
GetTid ();
141 std::pair<OriginatorBlockAckAgreement, PacketQueue> value (agreement, queue);
161 if ((*i)->GetHeader ().GetAddr1 () == recipient && (*i)->GetHeader ().GetQosTid () == tid)
172 for (std::list<Bar>::const_iterator i =
m_bars.begin (); i !=
m_bars.end (); )
174 if (i->recipient == recipient && i->tid == tid)
190 uint8_t tid = respHdr->
GetTid ();
209 if (!it->second.first.IsEstablished ())
236 NS_ASSERT (mpdu->GetHeader ().IsQosData ());
238 uint8_t tid = mpdu->GetHeader ().GetQosTid ();
239 Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
244 uint16_t startingSeq = agreementIt->second.first.GetStartingSequence ();
256 while (it != agreementIt->second.second.end ())
258 if (mpdu->GetHeader ().GetSequenceControl () == (*it)->GetHeader ().GetSequenceControl ())
260 NS_LOG_DEBUG (
"Packet already in the queue of the BA agreement");
266 if (mpduDist < dist ||
267 (mpduDist == dist && mpdu->GetHeader ().GetFragmentNumber () < (*it)->GetHeader ().GetFragmentNumber ()))
274 agreementIt->second.second.insert (it, mpdu);
308 uint32_t nPackets = 0;
310 while (queueIt != (*it).second.second.end ())
312 uint16_t currentSeq = (*queueIt)->GetHeader ().GetSequenceNumber ();
315 while (queueIt != (*it).second.second.end () && (*queueIt)->GetHeader ().GetSequenceNumber () == currentSeq)
341 NS_ASSERT (mpdu->GetHeader ().IsQosData ());
343 Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
344 uint8_t tid = mpdu->GetHeader ().GetQosTid ();
352 while (queueIt != it->second.second.end ())
354 if ((*queueIt)->GetHeader ().GetSequenceNumber () == mpdu->GetHeader ().GetSequenceNumber ())
356 queueIt = it->second.second.erase (queueIt);
364 uint16_t startingSeq = it->second.first.GetStartingSequence ();
365 if (mpdu->GetHeader ().GetSequenceNumber () == startingSeq)
368 it->second.first.SetStartingSequence ((startingSeq + 1) %
SEQNO_SPACE_SIZE);
376 NS_ASSERT (mpdu->GetHeader ().IsQosData ());
378 Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
379 uint8_t tid = mpdu->GetHeader ().GetQosTid ();
388 while (queueIt != it->second.second.end ())
390 if ((*queueIt)->GetHeader ().GetSequenceNumber () == mpdu->GetHeader ().GetSequenceNumber ())
392 queueIt = it->second.second.erase (queueIt);
413 bool foundFirstLost =
false;
414 uint8_t nSuccessfulMpdus = 0;
415 uint8_t nFailedMpdus = 0;
419 if (it->second.first.m_inactivityEvent.IsRunning ())
424 it->second.first.m_inactivityEvent.Cancel ();
432 uint16_t currentStartingSeq = it->second.first.GetStartingSequence ();
437 for (
PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd; )
439 currentSeq = (*queueIt)->GetHeader ().GetSequenceNumber ();
441 (*queueIt)->GetHeader ().GetFragmentNumber ()))
449 foundFirstLost =
true;
456 queueIt = it->second.second.erase (queueIt);
466 for (
PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd; )
468 currentSeq = (*queueIt)->GetHeader ().GetSequenceNumber ();
481 foundFirstLost =
true;
492 queueIt = it->second.second.erase (queueIt);
517 for (
auto& item : it->second.second)
524 it->second.second.clear ();
535 it->second.second.clear ();
551 if (!mpdu->GetHeader ().IsQosData ())
557 Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
558 uint8_t tid = mpdu->GetHeader ().GetQosTid ();
566 uint16_t currStartingSeq = it->second.first.GetStartingSequence ();
577 NS_LOG_DEBUG (
"Schedule a Block Ack Request for agreement (" << recipient <<
", " << +tid <<
")");
597 Bar request (bar, recipient, tid, it->second.first.IsImmediateBlockAck ());
600 for (std::list<Bar>::const_iterator i =
m_bars.begin (); i !=
m_bars.end (); i++)
602 if (i->recipient == recipient && i->tid == tid)
605 m_bars.insert (i, request);
609 m_bars.push_back (request);
625 if (!it->second.first.IsEstablished ())
630 it->second.first.SetStartingSequence (startingSeq);
639 if (!it->second.first.IsRejected ())
652 if (!it->second.first.IsNoReply ())
666 if (!it->second.first.IsReset ())
699 uint32_t packets =
m_queue->GetNPacketsByTidAndAddress (tid, recipient) +
719 else if (it->second.first.GetTimeout () > 0 && it->second.first.m_inactivityEvent.IsExpired ())
752 uint16_t startingSeq = agreementIt->second.first.GetStartingSequence ();
759 uint16_t itSeq = (*it)->GetHeader ().GetSequenceNumber ();
766 NS_LOG_DEBUG (
"Removing frame with seqnum = " << itSeq);
784 uint16_t currStartingSeq = agreementIt->second.first.GetStartingSequence ();
787 "The new starting sequence number is an old sequence number");
789 if (startingSeq == currStartingSeq)
800 while (it != agreementIt->second.second.end ())
802 uint16_t itSeq = (*it)->GetHeader ().GetSequenceNumber ();
807 NS_LOG_DEBUG (
"Removing frame with seqnum = " << itSeq);
808 it = agreementIt->second.second.erase (it);
817 agreementIt->second.first.SetStartingSequence (startingSeq);
864 NS_ASSERT (mpdu->GetHeader ().IsQosData ());
866 uint8_t tid = mpdu->GetHeader ().GetQosTid ();
867 Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
872 uint16_t startingSeq = agreementIt->second.first.GetStartingSequence ();
881 WifiMacQueue::ConstIterator it =
m_retryPackets->PeekByTidAndAddress (tid, recipient);
885 if (mpdu->GetHeader ().GetSequenceControl () == (*it)->GetHeader ().GetSequenceControl ())
887 NS_LOG_DEBUG (
"Packet already in the retransmit queue");
893 if (mpduDist < dist ||
894 (mpduDist == dist && mpdu->GetHeader ().GetFragmentNumber () < (*it)->GetHeader ().GetFragmentNumber ()))
911 size = it->second.first.GetBufferSize ();
923 seqNum = it->second.first.GetStartingSequence ();
void SetUnblockDestinationCallback(Callback< void, Mac48Address, uint8_t > callback)
Set unblock destination callback.
Simulation virtual time values and global simulation resolution.
void NotifyGotBlockAck(const CtrlBAckResponseHeader *blockAck, Mac48Address recipient, double rxSnr, WifiMode txMode, double dataSnr)
#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)
Maintains the state and information about transmitted MPDUs with ack policy block ack for an originat...
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
TracedCallback< Time, Mac48Address, uint8_t, OriginatorBlockAckAgreement::State > m_agreementState
The trace source fired when a state transition occured.
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...
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.
#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. ...
void ScheduleBlockAckReq(Mac48Address recipient, uint8_t tid)
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
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 NotifyDiscardedMpdu(Ptr< const WifiMacQueueItem > mpdu)
Ptr< WifiMacQueue > GetRetransmitQueue(void)
void NotifyAgreementEstablished(Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
void UpdateAgreement(const MgtAddBaResponseHeader *respHdr, Mac48Address recipient)
uint16_t GetTimeout(void) const
Return the timeout.
void SetQueue(const Ptr< WifiMacQueue > queue)
void SetBlockAckType(BlockAckType bAckType)
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.
void NotifyAgreementRejected(Mac48Address recipient, uint8_t tid)
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
bool ExistsAgreement(Mac48Address recipient, uint8_t tid) const
std::list< Ptr< WifiMacQueueItem > >::const_iterator PacketQueueCI
typedef for a const iterator for PacketQueue.
Ptr< MacTxMiddle > m_txMiddle
the MacTxMiddle
void SetBlockDestinationCallback(Callback< void, Mac48Address, uint8_t > callback)
Set block destination callback.
void DestroyAgreement(Mac48Address recipient, uint8_t tid)
void SetState(State state)
Set the current state.
void SetTxOkCallback(TxOk callback)
bool HasBar(Bar &bar, bool remove=true)
Returns true if the BAR is scheduled.
std::string GetUniqueName(void) const
uint16_t GetRecipientBufferSize(Mac48Address recipient, uint8_t tid) const
This function returns the buffer size negociated with the recipient.
void InsertInRetryQueue(Ptr< WifiMacQueueItem > mpdu)
void SetStartingSequence(uint16_t seq)
Set starting sequence number.
Mac48Address recipient
recipient
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
block ack 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 SetStartingSequence(Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
Set the starting sequence number for the agreement with recipient equal to recipient and TID equal to...
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 NotifyMpduTransmission(Mac48Address recipient, uint8_t tid, uint16_t nextSeqNumber, WifiMacHeader::QosAckPolicy policy)
void SetDelayedBlockAck(void)
Set Block ACK policy to delayed ACK.
EventId m_inactivityEvent
inactivity event
bool NeedBarRetransmission(uint8_t tid, uint16_t seqNumber, Mac48Address recipient)
This function returns true if the lifetime of the packets a BAR refers to didn't expire yet otherwise...
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
bool HasPackets(void) const
Returns true if there are packets that need of retransmission or at least a BAR is scheduled...
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.
void SetTxMiddle(const Ptr< MacTxMiddle > txMiddle)
Set the MacTxMiddle.
void SetBlockAckThreshold(uint8_t nPackets)
BlockAckType m_blockAckType
block ack type
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Ptr< const Packet > bar
block ack request
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.
void ReportAmpduTxStatus(Mac48Address address, uint8_t tid, uint8_t nSuccessfulMpdus, uint8_t nFailedMpdus, double rxSnr, double dataSnr)
Typically called per A-MPDU, either when a Block ACK was successfully received or when a BlockAckTime...
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< 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.
void AddHeader(const Header &header)
Add header to this packet.
Ptr< WifiMacQueue > m_queue
queue
BlockAckType
The different block ACK policies.