21 #include "ns3/assert.h"
22 #include "ns3/simulator.h"
23 #include "ns3/fatal-error.h"
25 #include "block-ack-manager.h"
26 #include "mgt-headers.h"
27 #include "ctrl-headers.h"
28 #include "wifi-mac-header.h"
29 #include "edca-txop-n.h"
31 #include "wifi-mac-queue.h"
32 #include "mac-tx-middle.h"
38 BlockAckManager::Item::Item ()
43 BlockAckManager::Item::Item (Ptr<const Packet> packet,
const WifiMacHeader &hdr, Time tStamp)
56 Bar::Bar (Ptr<const Packet> bar, Mac48Address recipient, uint8_t tid,
bool immediate)
58 recipient (recipient),
62 NS_LOG_FUNCTION (
this << bar << recipient << static_cast<uint32_t> (tid) << immediate);
65 BlockAckManager::BlockAckManager ()
70 BlockAckManager::~BlockAckManager ()
89 NS_LOG_FUNCTION (
this << recipient << static_cast<uint32_t> (tid) << state);
91 it =
m_agreements.find (std::make_pair (recipient, tid));
96 case OriginatorBlockAckAgreement::INACTIVE:
97 return it->second.first.IsInactive ();
98 case OriginatorBlockAckAgreement::ESTABLISHED:
99 return it->second.first.IsEstablished ();
100 case OriginatorBlockAckAgreement::PENDING:
101 return it->second.first.IsPending ();
102 case OriginatorBlockAckAgreement::UNSUCCESSFUL:
103 return it->second.first.IsUnsuccessful ();
115 std::pair<Mac48Address, uint8_t> key (recipient, reqHdr->GetTid ());
117 agreement.SetStartingSequence (reqHdr->GetStartingSequence ());
120 agreement.SetBufferSize (0);
121 agreement.SetTimeout (reqHdr->GetTimeout ());
122 agreement.SetAmsduSupport (reqHdr->IsAmsduSupported ());
123 if (reqHdr->IsImmediateBlockAck ())
125 agreement.SetImmediateBlockAck ();
129 agreement.SetDelayedBlockAck ();
131 agreement.SetState (OriginatorBlockAckAgreement::PENDING);
132 PacketQueue queue (0);
133 std::pair<OriginatorBlockAckAgreement, PacketQueue> value (agreement, queue);
135 m_blockPackets (recipient, reqHdr->GetTid ());
142 AgreementsI it =
m_agreements.find (std::make_pair (recipient, tid));
147 if ((*i)->hdr.GetAddr1 () == recipient && (*i)->hdr.GetQosTid () == tid)
158 for (std::list<Bar>::iterator i = m_bars.begin (); i != m_bars.end ();)
160 if (i->recipient == recipient && i->tid == tid)
162 i = m_bars.erase (i);
176 uint8_t tid = respHdr->GetTid ();
177 AgreementsI it =
m_agreements.find (std::make_pair (recipient, tid));
181 agreement.SetBufferSize (respHdr->GetBufferSize () + 1);
182 agreement.SetTimeout (respHdr->GetTimeout ());
183 agreement.SetAmsduSupport (respHdr->IsAmsduSupported ());
184 if (respHdr->IsImmediateBlockAck ())
186 agreement.SetImmediateBlockAck ();
190 agreement.SetDelayedBlockAck ();
192 agreement.SetState (OriginatorBlockAckAgreement::ESTABLISHED);
193 if (agreement.GetTimeout () != 0)
197 &BlockAckManager::InactivityTimeout,
202 m_unblockPackets (recipient, tid);
211 uint8_t tid = hdr.GetQosTid ();
214 Item item (packet, hdr, tStamp);
215 AgreementsI it =
m_agreements.find (std::make_pair (recipient, tid));
217 it->second.second.push_back (item);
230 packet = queueIt->packet;
233 NS_LOG_INFO (
"Retry packet seq=" << hdr.GetSequenceNumber ());
234 uint8_t tid = hdr.GetQosTid ();
240 hdr.SetQosAckPolicy (WifiMacHeader::BLOCK_ACK);
251 hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
252 AgreementsI i =
m_agreements.find (std::make_pair (recipient, tid));
253 i->second.second.erase (queueIt);
260 BlockAckManager::HasBar (
struct Bar &bar)
263 if (m_bars.size () > 0)
265 bar = m_bars.front ();
283 uint32_t nPackets = 0;
286 AgreementsCI it =
m_agreements.find (std::make_pair (recipient, tid));
287 PacketQueueCI queueIt = (*it).second.second.begin ();
288 uint16_t currentSeq = 0;
289 while (queueIt != (*it).second.second.end ())
291 currentSeq = (*queueIt).hdr.GetSequenceNumber ();
294 while (queueIt != (*it).second.second.end () && (*queueIt).hdr.GetSequenceNumber () == currentSeq)
308 uint32_t nPackets = 0;
309 uint16_t currentSeq = 0;
312 std::list<PacketQueueI>::const_iterator it =
m_retryPackets.begin ();
315 if ((*it)->hdr.GetAddr1 () == recipient && (*it)->hdr.GetQosTid () == tid)
317 currentSeq = (*it)->hdr.GetSequenceNumber ();
320 while (it !=
m_retryPackets.end () && (*it)->hdr.GetSequenceNumber () == currentSeq)
334 m_blockAckThreshold = nPackets;
341 uint16_t sequenceFirstLost = 0;
342 if (!blockAck->IsMultiTid ())
344 uint8_t tid = blockAck->GetTidInfo ();
347 bool foundFirstLost =
false;
348 AgreementsI it =
m_agreements.find (std::make_pair (recipient, tid));
349 PacketQueueI queueEnd = it->second.second.end ();
351 if (it->second.first.m_inactivityEvent.IsRunning ())
356 it->second.first.m_inactivityEvent.Cancel ();
359 &BlockAckManager::InactivityTimeout,
363 if (blockAck->IsBasic ())
365 for (PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd;)
367 if (blockAck->IsFragmentReceived ((*queueIt).hdr.GetSequenceNumber (),
368 (*queueIt).hdr.GetFragmentNumber ()))
370 queueIt = it->second.second.erase (queueIt);
376 foundFirstLost =
true;
377 sequenceFirstLost = (*queueIt).hdr.GetSequenceNumber ();
378 (*it).second.first.SetStartingSequence (sequenceFirstLost);
385 else if (blockAck->IsCompressed ())
387 for (PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd;)
389 if (blockAck->IsPacketReceived ((*queueIt).hdr.GetSequenceNumber ()))
391 uint16_t currentSeq = (*queueIt).hdr.GetSequenceNumber ();
392 while (queueIt != queueEnd
393 && (*queueIt).hdr.GetSequenceNumber () == currentSeq)
395 queueIt = it->second.second.erase (queueIt);
402 foundFirstLost =
true;
403 sequenceFirstLost = (*queueIt).hdr.GetSequenceNumber ();
404 (*it).second.first.SetStartingSequence (sequenceFirstLost);
411 uint16_t newSeq = m_txMiddle->GetNextSeqNumberByTidAndAddress (tid, recipient);
415 it->second.first.SetState (OriginatorBlockAckAgreement::INACTIVE);
430 m_blockAckType = bAckType;
442 AgreementsI it =
m_agreements.find (std::make_pair (recipient, tid));
445 if ((*it).second.first.IsBlockAckRequestNeeded ()
447 && m_queue->GetNPacketsByTidAndAddress (tid, WifiMacHeader::ADDR1, recipient) == 0))
450 agreement.CompleteExchange ();
453 if (m_blockAckType == BASIC_BLOCK_ACK || m_blockAckType == COMPRESSED_BLOCK_ACK)
455 reqHdr.SetType (m_blockAckType);
456 reqHdr.SetTidInfo (agreement.GetTid ());
457 reqHdr.SetStartingSequence (agreement.GetStartingSequence ());
459 else if (m_blockAckType == MULTI_TID_BLOCK_ACK)
475 BlockAckManager::InactivityTimeout (
Mac48Address recipient, uint8_t tid)
478 m_blockAckInactivityTimeout (recipient, tid,
true);
484 NS_LOG_FUNCTION (
this << recipient << static_cast<uint32_t> (tid) << startingSeq);
485 AgreementsI it =
m_agreements.find (std::make_pair (recipient, tid));
488 it->second.first.SetState (OriginatorBlockAckAgreement::ESTABLISHED);
489 it->second.first.SetStartingSequence (startingSeq);
496 AgreementsI it =
m_agreements.find (std::make_pair (recipient, tid));
500 it->second.first.SetState (OriginatorBlockAckAgreement::UNSUCCESSFUL);
507 NS_LOG_FUNCTION (
this << recipient << static_cast<uint32_t> (tid) << nextSeqNumber);
509 AgreementsI it =
m_agreements.find (std::make_pair (recipient, tid));
519 nextSeq = nextSeqNumber;
521 it->second.first.NotifyMpduTransmission (nextSeq);
525 Bar request (bar, recipient, tid, it->second.first.IsImmediateBlockAck ());
526 m_bars.push_back (request);
540 NS_LOG_FUNCTION (
this << recipient << static_cast<uint32_t> (tid) << startingSeq);
544 uint32_t packets = m_queue->GetNPacketsByTidAndAddress (tid, WifiMacHeader::ADDR1, recipient) +
546 if (packets >= m_blockAckThreshold)
570 if (next.hdr.GetSequenceNumber () == sequenceNumber)
586 size = next.packet->
GetSize ();
597 if (j->second.second.empty ())
602 PacketQueueI end = j->second.second.begin ();
603 for (PacketQueueI i = j->second.second.begin (); i != j->second.second.end (); i++)
605 if (i->timestamp + m_maxDelay > now)
615 if ((*it)->hdr.GetAddr1 () == j->second.first.GetPeer ()
616 && (*it)->hdr.GetQosTid () == j->second.first.GetTid ()
617 && (*it)->hdr.GetSequenceNumber () == i->hdr.GetSequenceNumber ())
628 j->second.second.erase (j->second.second.begin (), end);
629 j->second.first.SetStartingSequence (end->hdr.GetSequenceNumber ());
637 m_maxDelay = maxDelay;
644 m_blockAckInactivityTimeout = callback;
648 BlockAckManager::SetBlockDestinationCallback (Callback<void, Mac48Address, uint8_t> callback)
651 m_blockPackets = callback;
655 BlockAckManager::SetUnblockDestinationCallback (Callback<void, Mac48Address, uint8_t> callback)
658 m_unblockPackets = callback;
662 BlockAckManager::SetTxMiddle (MacTxMiddle* txMiddle)
665 m_txMiddle = txMiddle;
672 std::list<PacketQueueI>::const_iterator it =
m_retryPackets.begin ();
675 if ((*it)->hdr.GetAddr1 () == recipient && (*it)->hdr.GetQosTid () == tid)
677 return (*it)->hdr.GetSequenceNumber ();
#define NS_LOG_FUNCTION(parameters)
void NotifyGotBlockAck(const CtrlBAckResponseHeader *blockAck, Mac48Address recipient)
void CreateAgreement(const MgtAddBaRequestHeader *reqHdr, Mac48Address recipient)
void StorePacket(Ptr< const Packet > packet, const WifiMacHeader &hdr, Time tStamp)
#define NS_ASSERT(condition)
#define NS_LOG_COMPONENT_DEFINE(name)
uint32_t GetSize(void) const
void SetBlockAckType(enum BlockAckType bAckType)
bool HasPackets(void) const
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
#define NS_FATAL_ERROR(msg)
fatal error handling
Ptr< Packet > ScheduleBlockAckReqIfNeeded(Mac48Address recipient, uint8_t tid)
void SetQueue(Ptr< WifiMacQueue > queue)
void NotifyAgreementEstablished(Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
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)
bool HasOtherFragments(uint16_t sequenceNumber) const
std::list< PacketQueueI > m_retryPackets
void DestroyAgreement(Mac48Address recipient, uint8_t tid)
bool ExistsAgreementInState(Mac48Address recipient, uint8_t tid, enum OriginatorBlockAckAgreement::State state) const
Ptr< const Packet > GetNextPacket(WifiMacHeader &hdr)
void SetMaxPacketDelay(Time maxDelay)
bool SwitchToBlockAckIfNeeded(Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
uint32_t GetNBufferedPackets(Mac48Address recipient, uint8_t tid) const
void CleanupBuffers(void)
void SetBlockAckThreshold(uint8_t nPackets)
bool ExistsAgreement(Mac48Address recipient, uint8_t tid) const
Time MicroSeconds(uint64_t us)
create ns3::Time instances in units of microseconds.
void NotifyMpduTransmission(Mac48Address recipient, uint8_t tid, uint16_t nextSeqNumber)
void AddHeader(const Header &header)
void TearDownBlockAck(Mac48Address recipient, uint8_t tid)