22 #include "ns3/assert.h" 
   23 #include "ns3/simulator.h" 
   24 #include "ns3/fatal-error.h" 
   59     recipient (recipient),
 
   63   NS_LOG_FUNCTION (
this << bar << recipient << static_cast<uint32_t> (tid) << immediate);
 
   90   NS_LOG_FUNCTION (
this << recipient << static_cast<uint32_t> (tid) << state);
 
   92   it = 
m_agreements.find (std::make_pair (recipient, tid));
 
   98           return it->second.first.IsInactive ();
 
  100           return it->second.first.IsEstablished ();
 
  102           return it->second.first.IsPending ();
 
  104           return it->second.first.IsUnsuccessful ();
 
  116   std::pair<Mac48Address, uint8_t> key (recipient, reqHdr->
GetTid ());
 
  121   agreement.SetBufferSize (64);
 
  122   agreement.SetWinEnd ((agreement.GetStartingSequence () + agreement.GetBufferSize () - 1) % 4096);
 
  128       agreement.SetImmediateBlockAck ();
 
  132       agreement.SetDelayedBlockAck ();
 
  136   std::pair<OriginatorBlockAckAgreement, PacketQueue> value (agreement, queue);
 
  150           if ((*i)->hdr.GetAddr1 () == recipient && (*i)->hdr.GetQosTid () == tid)
 
  161       for (std::list<Bar>::iterator i = 
m_bars.begin (); i != 
m_bars.end (); )
 
  163           if (i->recipient == recipient && i->tid == tid)
 
  179   uint8_t tid = respHdr->
GetTid ();
 
  217   Item item (packet, hdr, tStamp);
 
  221   for (; queueIt != it->second.second.end (); )
 
  223       if (((hdr.
GetSequenceNumber () - queueIt->hdr.GetSequenceNumber () + 4096) % 4096) > 2047)
 
  225           queueIt = it->second.second.insert (queueIt, item);
 
  233   if (queueIt == it->second.second.end ())
 
  235       it->second.second.push_back (item);
 
  262           if ((*it)->hdr.IsQosData ())
 
  264               tid = (*it)->hdr.GetQosTid ();
 
  268               NS_FATAL_ERROR (
"Packet in blockAck manager retry queue is not Qos Data");
 
  270           recipient = (*it)->hdr.GetAddr1 ();
 
  273           if (
QosUtilsIsOldPacket (agreement->second.first.GetStartingSequence (),(*it)->hdr.GetSequenceNumber ()))
 
  276               NS_LOG_DEBUG (
"The Retry packet have sequence number < WinStartO --> Discard " << (*it)->hdr.GetSequenceNumber () << 
" " << agreement->second.first.GetStartingSequence ());
 
  277               agreement->second.second.erase ((*it));
 
  281           else if ((*it)->hdr.GetSequenceNumber () > (agreement->second.first.GetStartingSequence () + 63) % 4096)
 
  283               agreement->second.first.SetStartingSequence ((*it)->hdr.GetSequenceNumber ());
 
  285           packet = (*it)->packet->
Copy ();
 
  295               NS_FATAL_ERROR (
"Packet in blockAck manager retry queue is not Qos Data");
 
  298           if (!agreement->second.first.IsHtSupported ()
 
  315               i->second.second.erase (*it);
 
  337       if (!(*it)->hdr.IsQosData ())
 
  339           NS_FATAL_ERROR (
"Packet in blockAck manager retry queue is not Qos Data");
 
  341       if ((*it)->hdr.GetAddr1 () == recipient && (*it)->hdr.GetQosTid () == tid)
 
  343           if (
QosUtilsIsOldPacket (agreement->second.first.GetStartingSequence (),(*it)->hdr.GetSequenceNumber ()))
 
  346               NS_LOG_DEBUG (
"The Retry packet have sequence number < WinStartO --> Discard " << (*it)->hdr.GetSequenceNumber () << 
" " << agreement->second.first.GetStartingSequence ());
 
  347               agreement->second.second.erase ((*it));
 
  352           else if ((*it)->hdr.GetSequenceNumber () > (agreement->second.first.GetStartingSequence () + 63) % 4096)
 
  354               agreement->second.first.SetStartingSequence ((*it)->hdr.GetSequenceNumber ());
 
  356           packet = (*it)->packet->
Copy ();
 
  359           *tstamp = (*it)->timestamp;
 
  362           if (!agreement->second.first.IsHtSupported ()
 
  393       if (!(*it)->hdr.IsQosData ())
 
  395           NS_FATAL_ERROR (
"Packet in blockAck manager retry queue is not Qos Data");
 
  397       if ((*it)->hdr.GetAddr1 () == recipient && (*it)->hdr.GetQosTid () == tid && (*it)->hdr.GetSequenceNumber () == seqnumber)
 
  404           i->second.second.erase ((*it));
 
  438   uint32_t nPackets = 0;
 
  443       uint16_t currentSeq = 0;
 
  444       while (queueIt != (*it).second.second.end ())
 
  446           currentSeq = (*queueIt).hdr.GetSequenceNumber ();
 
  449           while (queueIt != (*it).second.second.end () && (*queueIt).hdr.GetSequenceNumber () == currentSeq)
 
  463   uint32_t nPackets = 0;
 
  464   uint16_t currentSeq = 0;
 
  467       std::list<PacketQueueI>::const_iterator it = 
m_retryPackets.begin ();
 
  470           if (!(*it)->hdr.IsQosData ())
 
  472               NS_FATAL_ERROR (
"Packet in blockAck manager retry queue is not Qos Data");
 
  474           if ((*it)->hdr.GetAddr1 () == recipient && (*it)->hdr.GetQosTid () == tid)
 
  476               currentSeq = (*it)->hdr.GetSequenceNumber ();
 
  479               while (it != 
m_retryPackets.end () && (*it)->hdr.GetSequenceNumber () == currentSeq)
 
  511   std::list<PacketQueueI>::const_iterator it = 
m_retryPackets.begin ();
 
  515       if (!(*it)->hdr.IsQosData ())
 
  517           NS_FATAL_ERROR (
"Packet in blockAck manager retry queue is not Qos Data");
 
  519       if ((*it)->hdr.GetAddr1 () == recipient && (*it)->hdr.GetQosTid () == tid && currentSeq == (*it)->hdr.GetSequenceNumber ())
 
  532   uint16_t sequenceFirstLost = 0;
 
  538           bool foundFirstLost = 
false;
 
  542           if (it->second.first.m_inactivityEvent.IsRunning ())
 
  547               it->second.first.m_inactivityEvent.Cancel ();
 
  556               for (
PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd; )
 
  559                                                     (*queueIt).hdr.GetFragmentNumber ()))
 
  561                       queueIt = it->second.second.erase (queueIt);
 
  567                           foundFirstLost = 
true;
 
  568                           sequenceFirstLost = (*queueIt).hdr.GetSequenceNumber ();
 
  569                           (*it).second.first.SetStartingSequence (sequenceFirstLost);
 
  572                       if (!
AlreadyExists ((*queueIt).hdr.GetSequenceNumber (),recipient,tid))
 
  583               for (
PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd; )
 
  587                       uint16_t currentSeq = (*queueIt).hdr.GetSequenceNumber ();
 
  588                       while (queueIt != queueEnd
 
  589                              && (*queueIt).hdr.GetSequenceNumber () == currentSeq)
 
  597                           queueIt = it->second.second.erase (queueIt);
 
  604                           foundFirstLost = 
true;
 
  605                           sequenceFirstLost = (*queueIt).hdr.GetSequenceNumber ();
 
  606                           (*it).second.first.SetStartingSequence (sequenceFirstLost);
 
  614                       if (!
AlreadyExists ((*queueIt).hdr.GetSequenceNumber (),recipient,tid))
 
  626               it->second.first.CompleteExchange ();
 
  656   if ((*it).second.first.IsBlockAckRequestNeeded ()
 
  695   NS_LOG_FUNCTION (
this << recipient << static_cast<uint32_t> (tid) << startingSeq);
 
  700   it->second.first.SetStartingSequence (startingSeq);
 
  718   NS_LOG_FUNCTION (
this << recipient << static_cast<uint32_t> (tid) << nextSeqNumber);
 
  730       nextSeq = nextSeqNumber;
 
  732   it->second.first.NotifyMpduTransmission (nextSeq);
 
  738           Bar request (bar, recipient, tid, it->second.first.IsImmediateBlockAck ());
 
  739           m_bars.push_back (request);
 
  754   NS_LOG_FUNCTION (
this << recipient << static_cast<uint32_t> (tid) << startingSeq);
 
  811   if ((seqNumber + 63) < it->second.first.GetStartingSequence ())
 
  827       if (j->second.second.empty ())
 
  833       for (
PacketQueueI i = j->second.second.begin (); i != j->second.second.end (); i++)
 
  845                   if ((*it)->hdr.GetAddr1 () == j->second.first.GetPeer ()
 
  846                       && (*it)->hdr.GetQosTid () == j->second.first.GetTid ()
 
  847                       && (*it)->hdr.GetSequenceNumber () == i->hdr.GetSequenceNumber ())
 
  858       j->second.second.erase (j->second.second.begin (), end);
 
  859       j->second.first.SetStartingSequence (end->hdr.GetSequenceNumber ());
 
  902   std::list<PacketQueueI>::const_iterator it = 
m_retryPackets.begin ();
 
  905       if (!(*it)->hdr.IsQosData ())
 
  907           NS_FATAL_ERROR (
"Packet in blockAck manager retry queue is not Qos Data");
 
  909       if ((*it)->hdr.GetAddr1 () == recipient && (*it)->hdr.GetQosTid () == tid)
 
  911           return (*it)->hdr.GetSequenceNumber ();
 
  933   NS_LOG_INFO (
"Adding to retry queue " << (*item).hdr.GetSequenceNumber ());
 
  942           if (((item->hdr.GetSequenceNumber () - (*it)->hdr.GetSequenceNumber () + 4096) % 4096) > 2047)
 
void SetUnblockDestinationCallback(Callback< void, Mac48Address, uint8_t > callback)
 
uint8_t GetTid(void) const 
Return the Traffic ID (TID). 
 
Simulation virtual time values and global simulation resolution. 
 
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
 
std::list< Item > PacketQueue
typedef for a list of Item struct. 
 
Maintains the state and information about transmitted MPDUs with ack policy block ack for an originat...
 
uint16_t GetTimeout(void) const 
Return the timeout. 
 
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)
 
void ReportDataFailed(Mac48Address address, const WifiMacHeader *header)
Should be invoked whenever the AckTimeout associated to a transmission attempt expires. 
 
void StorePacket(Ptr< const Packet > packet, const WifiMacHeader &hdr, Time tStamp)
 
uint8_t m_blockAckThreshold
 
Agreements m_agreements
This data structure contains, for each block ack agreement (recipient, tid), a set of packets for whi...
 
bool IsNull(void) const 
Check for null implementation. 
 
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
 
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name. 
 
bool HasBar(struct Bar &bar)
 
uint32_t GetSize(void) const 
Returns the the size in bytes of the packet (including the zero-filled initial payload). 
 
void InactivityTimeout(Mac48Address, uint8_t)
 
std::map< std::pair< Mac48Address, uint8_t >, std::pair< OriginatorBlockAckAgreement, PacketQueue > >::iterator AgreementsI
typedef for an iterator for Agreements. 
 
void SetBlockAckType(enum BlockAckType bAckType)
 
#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. ...
 
bool HasPackets(void) const 
Returns true if there are packets that need of retransmission or at least a BAR is scheduled...
 
BlockAckType
Enumeration for different block ACK policies. 
 
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
 
uint16_t GetStartingSequence(void) const 
Return the starting squence number. 
 
Handles sequence numbering of IEEE 802.11 data frames. 
 
Ptr< const Packet > PeekNextPacket(WifiMacHeader &hdr, Mac48Address recipient, uint8_t tid, Time *timestamp)
 
void SetTxFailedCallback(TxFailed callback)
 
Ptr< Packet > ScheduleBlockAckReqIfNeeded(Mac48Address recipient, uint8_t tid)
 
void SetQueue(Ptr< WifiMacQueue > queue)
 
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)
 
uint32_t GetNRetryNeededPackets(Mac48Address recipient, uint8_t tid) const 
 
uint32_t GetNextPacketSize(void) const 
 
uint16_t GetSeqNumOfNextRetryPacket(Mac48Address recipient, uint8_t tid) const 
 
void NotifyAgreementUnsuccessful(Mac48Address recipient, uint8_t tid)
 
void SetWifiRemoteStationManager(Ptr< WifiRemoteStationManager > manager)
Set up WifiRemoteStationManager associated with this BlockAckManager. 
 
void InsertInRetryQueue(PacketQueueI item)
 
bool HasOtherFragments(uint16_t sequenceNumber) const 
 
std::list< PacketQueueI > m_retryPackets
This list contains all iterators to stored packets that need to be retransmitted. ...
 
void SetTxMiddle(MacTxMiddle *txMiddle)
 
void SetBlockDestinationCallback(Callback< void, Mac48Address, uint8_t > callback)
 
void DestroyAgreement(Mac48Address recipient, uint8_t tid)
 
void SetTxOkCallback(TxOk callback)
 
void ReportDataOk(Mac48Address address, const WifiMacHeader *header, double ackSnr, WifiMode ackMode, double dataSnr)
Should be invoked whenever we receive the Ack associated to a data packet we just sent...
 
void SetStartingSequence(uint16_t seq)
Set starting sequence number. 
 
Ptr< Packet > Copy(void) const 
performs a COW copy of the packet. 
 
Every class exported by the ns3 library is enclosed in the ns3 namespace. 
 
bool RemovePacket(uint8_t tid, Mac48Address recipient, uint16_t seqnumber)
Remove a packet after you peek in the queue and get it. 
 
Callback< void, Mac48Address, uint8_t, bool > m_blockAckInactivityTimeout
 
QosAckPolicy
ACK policy for QoS frames. 
 
bool ExistsAgreementInState(Mac48Address recipient, uint8_t tid, enum OriginatorBlockAckAgreement::State state) const 
 
Callback< void, Mac48Address, uint8_t > m_blockPackets
 
bool AlreadyExists(uint16_t currentSeq, Mac48Address recipient, uint8_t tid)
Checks if the packet already exists in the retransmit queue or not if it does then it doesn't add it ...
 
Ptr< const Packet > GetNextPacket(WifiMacHeader &hdr)
 
static Time Now(void)
Return the current simulation virtual time. 
 
void SetBlockAckInactivityCallback(Callback< void, Mac48Address, uint8_t, bool > callback)
 
void SetMaxPacketDelay(Time maxDelay)
 
void NotifyMpduTransmission(Mac48Address recipient, uint8_t tid, uint16_t nextSeqNumber, WifiMacHeader::QosAckPolicy policy)
 
bool HasHtSupported(void) const 
Return whether the device has HT capability support enabled. 
 
void SetDelayedBlockAck(void)
Set Block ACK policy to delayed ACK. 
 
EventId m_inactivityEvent
 
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 else it r...
 
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support. 
 
A struct for packet, Wifi header, and timestamp. 
 
bool SwitchToBlockAckIfNeeded(Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
 
std::list< Item >::const_iterator PacketQueueCI
typedef for a const iterator for PacketQueue. 
 
Callback< void, Mac48Address, uint8_t > m_unblockPackets
 
uint32_t GetNBufferedPackets(Mac48Address recipient, uint8_t tid) const 
 
enum BlockAckType m_blockAckType
 
void CleanupBuffers(void)
This method removes packets whose lifetime was exceeded. 
 
void SetBlockAckThreshold(uint8_t nPackets)
 
void CompleteAmpduExchange(Mac48Address recipient, uint8_t tid)
 
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG. 
 
State
Represents the state for this agreement. 
 
void NotifyGotBlockAck(const CtrlBAckResponseHeader *blockAck, Mac48Address recipient, WifiMode txMode)
 
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 SetState(enum State state)
 
bool ExistsAgreement(Mac48Address recipient, uint8_t tid) const 
 
TxFailed m_txFailedCallback
 
Ptr< WifiRemoteStationManager > m_stationManager
 
void SetBufferSize(uint16_t bufferSize)
Set buffer size. 
 
uint16_t GetNextSeqNumberByTidAndAddress(uint8_t tid, Mac48Address addr) const 
Return the next sequence number for the Traffic ID and destination. 
 
Ptr< const Packet > packet
 
void AddHeader(const Header &header)
Add header to this packet. 
 
void TearDownBlockAck(Mac48Address recipient, uint8_t tid)
 
Ptr< WifiMacQueue > m_queue
 
void CompleteExchange(void)
 
std::list< Item >::iterator PacketQueueI
typedef for an iterator for PacketQueue.