A Discrete-Event Network Simulator
API
block-ack-manager.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009, 2010 MIRKO BANCHI
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mirko Banchi <mk.banchi@gmail.com>
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/simulator.h"
23 #include "block-ack-manager.h"
24 #include "wifi-utils.h"
25 #include "ctrl-headers.h"
26 #include "mgt-headers.h"
27 #include "wifi-mac-queue.h"
28 #include "qos-utils.h"
29 #include "wifi-tx-vector.h"
30 
31 namespace ns3 {
32 
33 NS_LOG_COMPONENT_DEFINE ("BlockAckManager");
34 
36 {
37  NS_LOG_FUNCTION (this);
38 }
39 
40 Bar::Bar (Ptr<const WifiMacQueueItem> bar, uint8_t tid, bool skipIfNoDataQueued)
41  : bar (bar),
42  tid (tid),
43  skipIfNoDataQueued (skipIfNoDataQueued)
44 {
45  NS_LOG_FUNCTION (this << *bar << +tid << skipIfNoDataQueued);
46 }
47 
49 
50 TypeId
52 {
53  static TypeId tid = TypeId ("ns3::BlockAckManager")
54  .SetParent<Object> ()
55  .SetGroupName ("Wifi")
56  .AddConstructor<BlockAckManager> ()
57  .AddTraceSource ("AgreementState",
58  "The state of the ADDBA handshake",
60  "ns3::BlockAckManager::AgreementStateTracedCallback")
61  ;
62  return tid;
63 }
64 
66 {
67  NS_LOG_FUNCTION (this);
68 }
69 
71 {
72  NS_LOG_FUNCTION (this);
73 }
74 
75 void
77 {
78  NS_LOG_FUNCTION (this);
79  m_agreements.clear ();
80  m_bars.clear ();
81  m_queue = nullptr;
82 }
83 
84 bool
85 BlockAckManager::ExistsAgreement (Mac48Address recipient, uint8_t tid) const
86 {
87  NS_LOG_FUNCTION (this << recipient << +tid);
88  return (m_agreements.find (std::make_pair (recipient, tid)) != m_agreements.end ());
89 }
90 
91 bool
94 {
95  AgreementsCI it;
96  it = m_agreements.find (std::make_pair (recipient, tid));
97  if (it != m_agreements.end ())
98  {
99  switch (state)
100  {
102  return it->second.first.IsEstablished ();
104  return it->second.first.IsPending ();
106  return it->second.first.IsRejected ();
108  return it->second.first.IsNoReply ();
110  return it->second.first.IsReset ();
111  default:
112  NS_FATAL_ERROR ("Invalid state for block ack agreement");
113  }
114  }
115  return false;
116 }
117 
118 void
119 BlockAckManager::CreateAgreement (const MgtAddBaRequestHeader *reqHdr, Mac48Address recipient, bool htSupported)
120 {
121  NS_LOG_FUNCTION (this << reqHdr << recipient << htSupported);
122  std::pair<Mac48Address, uint8_t> key (recipient, reqHdr->GetTid ());
123  OriginatorBlockAckAgreement agreement (recipient, reqHdr->GetTid ());
124  agreement.SetStartingSequence (reqHdr->GetStartingSequence ());
125  /* For now we assume that originator doesn't use this field. Use of this field
126  is mandatory only for recipient */
127  agreement.SetBufferSize (reqHdr->GetBufferSize());
128  agreement.SetTimeout (reqHdr->GetTimeout ());
129  agreement.SetAmsduSupport (reqHdr->IsAmsduSupported ());
130  agreement.SetHtSupported (htSupported);
131  if (reqHdr->IsImmediateBlockAck ())
132  {
133  agreement.SetImmediateBlockAck ();
134  }
135  else
136  {
137  agreement.SetDelayedBlockAck ();
138  }
139  uint8_t tid = reqHdr->GetTid ();
142  PacketQueue queue;
143  std::pair<OriginatorBlockAckAgreement, PacketQueue> value (agreement, queue);
144  if (ExistsAgreement (recipient, tid))
145  {
146  // Delete agreement if it exists and in RESET state
148  m_agreements.erase (key);
149  }
150  m_agreements.insert (std::make_pair (key, value));
151  m_blockPackets (recipient, reqHdr->GetTid ());
152 }
153 
154 void
156 {
157  NS_LOG_FUNCTION (this << recipient << +tid);
158  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
159  if (it != m_agreements.end ())
160  {
161  m_agreements.erase (it);
162  //remove scheduled BAR
163  for (std::list<Bar>::const_iterator i = m_bars.begin (); i != m_bars.end (); )
164  {
165  if (i->bar->GetHeader ().GetAddr1 () == recipient && i->tid == tid)
166  {
167  i = m_bars.erase (i);
168  }
169  else
170  {
171  i++;
172  }
173  }
174  }
175 }
176 
177 void
179  uint16_t startingSeq)
180 {
181  NS_LOG_FUNCTION (this << respHdr << recipient << startingSeq);
182  uint8_t tid = respHdr->GetTid ();
183  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
184  if (it != m_agreements.end ())
185  {
186  OriginatorBlockAckAgreement& agreement = it->second.first;
187  agreement.SetBufferSize (respHdr->GetBufferSize () + 1);
188  agreement.SetTimeout (respHdr->GetTimeout ());
189  agreement.SetAmsduSupport (respHdr->IsAmsduSupported ());
190  agreement.SetStartingSequence (startingSeq);
191  agreement.InitTxWindow ();
192  if (respHdr->IsImmediateBlockAck ())
193  {
194  agreement.SetImmediateBlockAck ();
195  }
196  else
197  {
198  agreement.SetDelayedBlockAck ();
199  }
200  if (!it->second.first.IsEstablished ())
201  {
203  }
205  if (agreement.GetTimeout () != 0)
206  {
207  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
210  this,
211  recipient, tid);
212  }
213  }
214  m_unblockPackets (recipient, tid);
215 }
216 
217 void
219 {
220  NS_LOG_FUNCTION (this << *mpdu);
221  NS_ASSERT (mpdu->GetHeader ().IsQosData ());
222 
223  uint8_t tid = mpdu->GetHeader ().GetQosTid ();
224  Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
225 
226  AgreementsI agreementIt = m_agreements.find (std::make_pair (recipient, tid));
227  NS_ASSERT (agreementIt != m_agreements.end ());
228 
229  uint16_t mpduDist = agreementIt->second.first.GetDistance (mpdu->GetHeader ().GetSequenceNumber ());
230 
231  if (mpduDist >= SEQNO_SPACE_HALF_SIZE)
232  {
233  NS_LOG_DEBUG ("Got an old packet. Do nothing");
234  return;
235  }
236 
237  // store the packet and keep the list sorted in increasing order of sequence number
238  // with respect to the starting sequence number
239  auto it = agreementIt->second.second.rbegin ();
240  while (it != agreementIt->second.second.rend ())
241  {
242  if (mpdu->GetHeader ().GetSequenceControl () == (*it)->GetHeader ().GetSequenceControl ())
243  {
244  NS_LOG_DEBUG ("Packet already in the queue of the BA agreement");
245  return;
246  }
247 
248  uint16_t dist = agreementIt->second.first.GetDistance ((*it)->GetHeader ().GetSequenceNumber ());
249 
250  if (mpduDist > dist ||
251  (mpduDist == dist && mpdu->GetHeader ().GetFragmentNumber () > (*it)->GetHeader ().GetFragmentNumber ()))
252  {
253  break;
254  }
255 
256  it++;
257  }
258  agreementIt->second.second.insert (std::prev (it.base ()), mpdu);
259  agreementIt->second.first.NotifyTransmittedMpdu (mpdu);
260  mpdu->SetInFlight ();
261 }
262 
264 BlockAckManager::GetBar (bool remove, uint8_t tid, Mac48Address address)
265 {
266  Time now = Simulator::Now ();
268  // remove all expired MPDUs from the head of the MAC queue, so that
269  // BlockAckRequest frames (if needed) are scheduled
270  m_queue->IsEmpty ();
271 
272  auto nextBar = m_bars.begin ();
273 
274  while (nextBar != m_bars.end ())
275  {
276  Mac48Address recipient = nextBar->bar->GetHeader ().GetAddr1 ();
277 
278  if (address != Mac48Address::GetBroadcast () && tid != 8
279  && (!nextBar->bar->GetHeader ().IsBlockAckReq ()
280  || address != recipient || tid != nextBar->tid))
281  {
282  // we can only return a BAR addressed to the given station and for the given TID
283  nextBar++;
284  continue;
285  }
286  if (nextBar->bar->GetHeader ().IsBlockAckReq ())
287  {
288  AgreementsI it = m_agreements.find (std::make_pair (recipient, nextBar->tid));
289  if (it == m_agreements.end ())
290  {
291  // BA agreement was torn down; remove this BAR and continue
292  nextBar = m_bars.erase (nextBar);
293  continue;
294  }
295  if (nextBar->skipIfNoDataQueued
296  && m_queue->PeekByTidAndAddress (nextBar->tid, recipient) == nullptr)
297  {
298  // skip this BAR as there is no data queued
299  nextBar++;
300  continue;
301  }
302  // remove expired outstanding MPDUs and update the starting sequence number
303  for (auto mpduIt = it->second.second.begin (); mpduIt != it->second.second.end (); )
304  {
305  if (!(*mpduIt)->IsQueued ())
306  {
307  // the MPDU is no longer in the EDCA queue
308  mpduIt = it->second.second.erase (mpduIt);
309  continue;
310  }
311 
312  if ((*mpduIt)->GetTimeStamp () + m_queue->GetMaxDelay () <= now)
313  {
314  // MPDU expired
315  it->second.first.NotifyDiscardedMpdu (*mpduIt);
316  // Remove from the EDCA queue and fire the Expired trace source, but the
317  // consequent call to NotifyDiscardedMpdu does nothing (in particular,
318  // does not schedule a BAR) because we have advanced the transmit window
319  // and hence this MPDU became an old packet
320  m_queue->TtlExceeded (*mpduIt, now);
321  mpduIt = it->second.second.erase (mpduIt);
322  }
323  else
324  {
325  // MPDUs are typically in increasing order of remaining lifetime
326  break;
327  }
328  }
329  // update BAR if the starting sequence number changed
330  CtrlBAckRequestHeader reqHdr;
331  nextBar->bar->GetPacket ()->PeekHeader (reqHdr);
332  if (reqHdr.GetStartingSequence () != it->second.first.GetStartingSequence ())
333  {
334  reqHdr.SetStartingSequence (it->second.first.GetStartingSequence ());
335  Ptr<Packet> packet = Create<Packet> ();
336  packet->AddHeader (reqHdr);
337  nextBar->bar = Create<const WifiMacQueueItem> (packet, nextBar->bar->GetHeader ());
338  }
339  }
340 
341  bar = nextBar->bar;
342  if (remove)
343  {
344  m_bars.erase (nextBar);
345  }
346  break;
347  }
348  return bar;
349 }
350 
351 uint32_t
353 {
354  NS_LOG_FUNCTION (this << recipient << +tid);
355  AgreementsCI it = m_agreements.find (std::make_pair (recipient, tid));
356  if (it == m_agreements.end ())
357  {
358  return 0;
359  }
360  return it->second.second.size ();
361 }
362 
363 void
365 {
366  NS_LOG_FUNCTION (this << +nPackets);
367  m_blockAckThreshold = nPackets;
368 }
369 
372  const AgreementsI& it, const Time& now)
373 {
374  NS_LOG_FUNCTION (this << **mpduIt << +static_cast<uint8_t> (status));
375 
376  if (!(*mpduIt)->IsQueued ())
377  {
378  // MPDU is not in the EDCA queue (e.g., its lifetime expired and it was
379  // removed by another method), remove from the queue of in flight MPDUs
380  NS_LOG_DEBUG ("MPDU is not stored in the EDCA queue, drop MPDU");
381  return it->second.second.erase (mpduIt);
382  }
383 
384  if (status == ACKNOWLEDGED)
385  {
386  // the MPDU has to be dequeued from the EDCA queue
387  m_queue->DequeueIfQueued (*mpduIt);
388  return it->second.second.erase (mpduIt);
389  }
390 
391  WifiMacHeader& hdr = (*mpduIt)->GetHeader ();
392 
393  NS_ASSERT (hdr.GetAddr1 () == it->first.first);
394  NS_ASSERT (hdr.IsQosData () && hdr.GetQosTid () == it->first.second);
395 
396  if (it->second.first.GetDistance (hdr.GetSequenceNumber ()) >= SEQNO_SPACE_HALF_SIZE)
397  {
398  NS_LOG_DEBUG ("Old packet. Remove from the EDCA queue, too");
400  {
401  m_droppedOldMpduCallback (*mpduIt);
402  }
403  m_queue->Remove (*mpduIt, false);
404  return it->second.second.erase (mpduIt);
405  }
406 
407  auto nextIt = std::next (mpduIt);
408 
409  if (m_queue->TtlExceeded (*mpduIt, now))
410  {
411  // WifiMacQueue::TtlExceeded() has removed the MPDU from the EDCA queue
412  // and fired the Expired trace source, which called NotifyDiscardedMpdu,
413  // which removed this MPDU from the in flight queue as well
414  NS_LOG_DEBUG ("MSDU lifetime expired, drop MPDU");
415  return nextIt;
416  }
417 
418  if (status == STAY_INFLIGHT)
419  {
420  // the MPDU has to stay in flight, do nothing
421  return ++mpduIt;
422  }
423 
424  NS_ASSERT (status == TO_RETRANSMIT);
425  (*mpduIt)->GetHeader ().SetRetry ();
426  (*mpduIt)->ResetInFlight (); // no longer in flight; will be if retransmitted
427 
428  return it->second.second.erase (mpduIt);
429 }
430 
431 void
433 {
434  NS_LOG_FUNCTION (this << *mpdu);
435  NS_ASSERT (mpdu->GetHeader ().IsQosData ());
436 
437  Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
438  uint8_t tid = mpdu->GetHeader ().GetQosTid ();
440 
441  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
442  NS_ASSERT (it != m_agreements.end ());
443 
444  it->second.first.NotifyAckedMpdu (mpdu);
445 
446  // remove the acknowledged frame from the queue of outstanding packets
447  for (auto queueIt = it->second.second.begin (); queueIt != it->second.second.end (); ++queueIt)
448  {
449  if ((*queueIt)->GetHeader ().GetSequenceNumber () == mpdu->GetHeader ().GetSequenceNumber ())
450  {
452  break;
453  }
454  }
455 }
456 
457 void
459 {
460  NS_LOG_FUNCTION (this << *mpdu);
461  NS_ASSERT (mpdu->GetHeader ().IsQosData ());
462 
463  Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
464  uint8_t tid = mpdu->GetHeader ().GetQosTid ();
466 
467  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
468  NS_ASSERT (it != m_agreements.end ());
469 
470  // remove the frame from the queue of outstanding packets (it will be re-inserted
471  // if retransmitted)
472  for (auto queueIt = it->second.second.begin (); queueIt != it->second.second.end (); ++queueIt)
473  {
474  if ((*queueIt)->GetHeader ().GetSequenceNumber () == mpdu->GetHeader ().GetSequenceNumber ())
475  {
477  break;
478  }
479  }
480 }
481 
482 std::pair<uint16_t,uint16_t>
484  const std::set<uint8_t>& tids, size_t index)
485 {
486  NS_LOG_FUNCTION (this << blockAck << recipient << index);
487  uint16_t nSuccessfulMpdus = 0;
488  uint16_t nFailedMpdus = 0;
489 
490  NS_ABORT_MSG_IF (blockAck.IsBasic (), "Basic Block Ack is not supported");
491  NS_ABORT_MSG_IF (blockAck.IsMultiTid (), "Multi-TID Block Ack is not supported");
492 
493  uint8_t tid = blockAck.GetTidInfo (index);
494  // If this is a Multi-STA Block Ack with All-ack context (TID equal to 14),
495  // use the TID passed by the caller.
496  if (tid == 14)
497  {
498  NS_ASSERT (blockAck.GetAckType (index) && tids.size () == 1);
499  tid = *tids.begin ();
500  }
502  {
503  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
504 
505  if (it->second.first.m_inactivityEvent.IsRunning ())
506  {
507  /* Upon reception of a BlockAck frame, the inactivity timer at the
508  originator must be reset.
509  For more details see section 11.5.3 in IEEE802.11e standard */
510  it->second.first.m_inactivityEvent.Cancel ();
511  Time timeout = MicroSeconds (1024 * it->second.first.GetTimeout ());
512  it->second.first.m_inactivityEvent = Simulator::Schedule (timeout,
514  this,
515  recipient, tid);
516  }
517 
518  NS_ASSERT (blockAck.IsCompressed () || blockAck.IsExtendedCompressed () || blockAck.IsMultiSta ());
519  Time now = Simulator::Now ();
520 
521  for (auto queueIt = it->second.second.begin (); queueIt != it->second.second.end (); )
522  {
523  uint16_t currentSeq = (*queueIt)->GetHeader ().GetSequenceNumber ();
524  if (blockAck.IsPacketReceived (currentSeq, index))
525  {
526  it->second.first.NotifyAckedMpdu (*queueIt);
527  nSuccessfulMpdus++;
528  if (!m_txOkCallback.IsNull ())
529  {
530  m_txOkCallback (*queueIt);
531  }
532  queueIt = HandleInFlightMpdu (queueIt, ACKNOWLEDGED, it, now);
533  }
534  else
535  {
536  nFailedMpdus++;
537  if (!m_txFailedCallback.IsNull ())
538  {
539  m_txFailedCallback (*queueIt);
540  }
541  queueIt = HandleInFlightMpdu (queueIt, TO_RETRANSMIT, it, now);
542  }
543  }
544  }
545  return {nSuccessfulMpdus, nFailedMpdus};
546 }
547 
548 void
550 {
551  NS_LOG_FUNCTION (this << recipient << +tid);
553  {
554  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
555  Time now = Simulator::Now ();
556 
557  // remove all packets from the queue of outstanding packets (they will be
558  // re-inserted if retransmitted)
559  for (auto mpduIt = it->second.second.begin (); mpduIt != it->second.second.end (); )
560  {
561  mpduIt = HandleInFlightMpdu (mpduIt, TO_RETRANSMIT, it, now);
562  }
563  }
564 }
565 
566 void
568 {
569  NS_LOG_FUNCTION (this << *mpdu);
570 
571  if (!mpdu->GetHeader ().IsQosData ())
572  {
573  NS_LOG_DEBUG ("Not a QoS Data frame");
574  return;
575  }
576 
577  if (!mpdu->GetHeader ().IsRetry () && !mpdu->IsInFlight ())
578  {
579  NS_LOG_DEBUG ("This frame has never been transmitted");
580  return;
581  }
582 
583  Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
584  uint8_t tid = mpdu->GetHeader ().GetQosTid ();
586  {
587  NS_LOG_DEBUG ("No established Block Ack agreement");
588  return;
589  }
590 
591  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
592  uint16_t currStartingSeq = it->second.first.GetStartingSequence ();
593  if (QosUtilsIsOldPacket (currStartingSeq, mpdu->GetHeader ().GetSequenceNumber ()))
594  {
595  NS_LOG_DEBUG ("Discarded an old frame");
596  return;
597  }
598 
599  // actually advance the transmit window
600  it->second.first.NotifyDiscardedMpdu (mpdu);
601 
602  // remove old MPDUs from the EDCA queue and from the in flight queue
603  // (including the given MPDU which became old after advancing the transmit window)
604  for (auto mpduIt = it->second.second.begin (); mpduIt != it->second.second.end (); )
605  {
606  if (it->second.first.GetDistance ((*mpduIt)->GetHeader ().GetSequenceNumber ()) >= SEQNO_SPACE_HALF_SIZE)
607  {
608  m_queue->DequeueIfQueued (*mpduIt);
610  {
611  m_droppedOldMpduCallback (*mpduIt);
612  }
613  mpduIt = it->second.second.erase (mpduIt);
614  }
615  else
616  {
617  break; // MPDUs are in increasing order of sequence number in the in flight queue
618  }
619  }
620 
621  // schedule a BlockAckRequest
622  NS_LOG_DEBUG ("Schedule a Block Ack Request for agreement (" << recipient << ", " << +tid << ")");
623  Ptr<Packet> bar = Create<Packet> ();
624  bar->AddHeader (GetBlockAckReqHeader (recipient, tid));
625 
626  WifiMacHeader hdr;
628  hdr.SetAddr1 (recipient);
629  hdr.SetAddr2 (mpdu->GetHeader ().GetAddr2 ());
630  hdr.SetAddr3 (mpdu->GetHeader ().GetAddr3 ());
631  hdr.SetDsNotTo ();
632  hdr.SetDsNotFrom ();
633  hdr.SetNoRetry ();
634  hdr.SetNoMoreFragments ();
635 
636  ScheduleBar (Create<const WifiMacQueueItem> (bar, hdr));
637 }
638 
641 {
642  NS_LOG_FUNCTION (this << recipient << +tid);
643  AgreementsCI it = m_agreements.find (std::make_pair (recipient, tid));
644  NS_ASSERT (it != m_agreements.end ());
645 
646  CtrlBAckRequestHeader reqHdr;
647  reqHdr.SetType ((*it).second.first.GetBlockAckReqType ());
648  reqHdr.SetTidInfo (tid);
649  reqHdr.SetStartingSequence ((*it).second.first.GetStartingSequence ());
650  return reqHdr;
651 }
652 
653 void
655 {
656  NS_LOG_FUNCTION (this << *bar);
657  NS_ASSERT (bar->GetHeader ().IsBlockAckReq () || bar->GetHeader ().IsTrigger ());
658 
659  uint8_t tid = 0;
660  if (bar->GetHeader ().IsBlockAckReq ())
661  {
662  CtrlBAckRequestHeader reqHdr;
663  bar->GetPacket ()->PeekHeader (reqHdr);
664  tid = reqHdr.GetTidInfo ();
665  }
666 #ifdef NS3_BUILD_PROFILE_DEBUG
667  else
668  {
669  CtrlTriggerHeader triggerHdr;
670  bar->GetPacket ()->PeekHeader (triggerHdr);
671  NS_ASSERT (triggerHdr.IsMuBar ());
672  }
673 #endif
674  Bar request (bar, tid, skipIfNoDataQueued);
675 
676  // if a BAR for the given agreement is present, replace it with the new one
677  std::list<Bar>::const_iterator i = m_bars.end ();
678 
679  if (bar->GetHeader ().IsBlockAckReq ())
680  {
681  for (i = m_bars.begin (); i != m_bars.end (); i++)
682  {
683  if (i->bar->GetHeader ().IsBlockAckReq ()
684  && i->bar->GetHeader ().GetAddr1 () == bar->GetHeader ().GetAddr1 () && i->tid == tid)
685  {
686  i = m_bars.erase (i);
687  break;
688  }
689  }
690  }
691 
692  if (bar->GetHeader ().IsRetry ())
693  {
694  m_bars.push_front (request);
695  }
696  else
697  {
698  m_bars.insert (i, request);
699  }
700 }
701 
702 void
704 {
705  NS_LOG_FUNCTION (this << recipient << +tid);
706  m_blockAckInactivityTimeout (recipient, tid, true);
707 }
708 
709 void
710 BlockAckManager::NotifyAgreementEstablished (Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
711 {
712  NS_LOG_FUNCTION (this << recipient << +tid << startingSeq);
713  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
714  NS_ASSERT (it != m_agreements.end ());
715  if (!it->second.first.IsEstablished ())
716  {
718  }
719  it->second.first.SetState (OriginatorBlockAckAgreement::ESTABLISHED);
720  it->second.first.SetStartingSequence (startingSeq);
721 }
722 
723 void
725 {
726  NS_LOG_FUNCTION (this << recipient << +tid);
727  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
728  NS_ASSERT (it != m_agreements.end ());
729  if (!it->second.first.IsRejected ())
730  {
732  }
733  it->second.first.SetState (OriginatorBlockAckAgreement::REJECTED);
734 }
735 
736 void
738 {
739  NS_LOG_FUNCTION (this << recipient << +tid);
740  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
741  NS_ASSERT (it != m_agreements.end ());
742  if (!it->second.first.IsNoReply ())
743  {
745  }
746  it->second.first.SetState (OriginatorBlockAckAgreement::NO_REPLY);
747  m_unblockPackets (recipient, tid);
748 }
749 
750 void
752 {
753  NS_LOG_FUNCTION (this << recipient << +tid);
754  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
755  NS_ASSERT (it != m_agreements.end ());
756  if (!it->second.first.IsReset ())
757  {
759  }
760  it->second.first.SetState (OriginatorBlockAckAgreement::RESET);
761 }
762 
763 void
765 {
766  NS_LOG_FUNCTION (this << queue);
767  m_queue = queue;
768 }
769 
770 bool
771 BlockAckManager::SwitchToBlockAckIfNeeded (Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
772 {
773  NS_LOG_FUNCTION (this << recipient << +tid << startingSeq);
775  if (!ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::REJECTED) && ExistsAgreement (recipient, tid))
776  {
777  uint32_t packets = m_queue->GetNPacketsByTidAndAddress (tid, recipient) +
778  GetNBufferedPackets (recipient, tid);
779  if (packets >= m_blockAckThreshold)
780  {
781  NotifyAgreementEstablished (recipient, tid, startingSeq);
782  return true;
783  }
784  }
785  return false;
786 }
787 
789 {
791  {
792  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
793  NS_ASSERT (it != m_agreements.end ());
794 
795  Time now = Simulator::Now ();
796 
797  // A BAR needs to be retransmitted if there is at least a non-expired in flight MPDU
798  for (auto mpduIt = it->second.second.begin (); mpduIt != it->second.second.end (); )
799  {
800  // remove MPDU if old or with expired lifetime
801  mpduIt = HandleInFlightMpdu (mpduIt, STAY_INFLIGHT, it, now);
802 
803  if (mpduIt != it->second.second.begin ())
804  {
805  // the MPDU has not been removed
806  return true;
807  }
808  }
809  }
810 
811  // If the inactivity timer has expired, QosTxop::SendDelbaFrame has been called and
812  // has destroyed the agreement, hence we get here and correctly return false
813  return false;
814 }
815 
816 void
818 {
819  NS_LOG_FUNCTION (this << &callback);
820  m_blockAckInactivityTimeout = callback;
821 }
822 
823 void
825 {
826  NS_LOG_FUNCTION (this << &callback);
827  m_blockPackets = callback;
828 }
829 
830 void
832 {
833  NS_LOG_FUNCTION (this << &callback);
834  m_unblockPackets = callback;
835 }
836 
837 void
839 {
840  m_txOkCallback = callback;
841 }
842 
843 void
845 {
846  m_txFailedCallback = callback;
847 }
848 
849 void
851 {
852  m_droppedOldMpduCallback = callback;
853 }
854 
855 uint16_t
857 {
858  uint16_t size = 0;
859  AgreementsCI it = m_agreements.find (std::make_pair (recipient, tid));
860  if (it != m_agreements.end ())
861  {
862  size = it->second.first.GetBufferSize ();
863  }
864  return size;
865 }
866 
868 BlockAckManager::GetBlockAckReqType (Mac48Address recipient, uint8_t tid) const
869 {
870  AgreementsCI it = m_agreements.find (std::make_pair (recipient, tid));
871  NS_ABORT_MSG_IF (it == m_agreements.end (), "No established Block Ack agreement");
872  return it->second.first.GetBlockAckReqType ();
873 }
874 
876 BlockAckManager::GetBlockAckType (Mac48Address recipient, uint8_t tid) const
877 {
878  AgreementsCI it = m_agreements.find (std::make_pair (recipient, tid));
879  NS_ABORT_MSG_IF (it == m_agreements.end (), "No established Block Ack agreement");
880  return it->second.first.GetBlockAckType ();
881 }
882 
883 uint16_t
885 {
886  uint16_t seqNum = 0;
887  AgreementsCI it = m_agreements.find (std::make_pair (recipient, tid));
888  if (it != m_agreements.end ())
889  {
890  seqNum = it->second.first.GetStartingSequence ();
891  }
892  return seqNum;
893 }
894 
895 } //namespace ns3
ns3::BlockAckManager::GetBlockAckReqHeader
CtrlBAckRequestHeader GetBlockAckReqHeader(Mac48Address recipient, uint8_t tid) const
Definition: block-ack-manager.cc:640
ns3::TypeId
a unique identifier for an interface.
Definition: type-id.h:59
NS_LOG_COMPONENT_DEFINE
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ns3::BlockAckManager::GetNBufferedPackets
uint32_t GetNBufferedPackets(Mac48Address recipient, uint8_t tid) const
Definition: block-ack-manager.cc:352
ns3::BlockAckManager::SwitchToBlockAckIfNeeded
bool SwitchToBlockAckIfNeeded(Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
Definition: block-ack-manager.cc:771
ns3::BlockAckAgreement::SetHtSupported
void SetHtSupported(bool htSupported)
Enable or disable HT support.
Definition: block-ack-agreement.cc:156
ns3::BlockAckManager::CreateAgreement
void CreateAgreement(const MgtAddBaRequestHeader *reqHdr, Mac48Address recipient, bool htSupported=true)
Definition: block-ack-manager.cc:119
ns3::MgtAddBaResponseHeader::IsImmediateBlockAck
bool IsImmediateBlockAck(void) const
Return whether the Block Ack policy is immediate Block Ack.
Definition: mgt-headers.cc:1762
ns3::BlockAckManager::NotifyAgreementReset
void NotifyAgreementReset(Mac48Address recipient, uint8_t tid)
Definition: block-ack-manager.cc:751
NS_OBJECT_ENSURE_REGISTERED
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
NS_ASSERT
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
ns3::CtrlBAckResponseHeader::IsBasic
bool IsBasic(void) const
Check if the current BA policy is Basic Block Ack.
Definition: ctrl-headers.cc:540
ns3::WifiMacHeader::SetNoMoreFragments
void SetNoMoreFragments(void)
Un-set the More Fragment bit in the Frame Control Field.
Definition: wifi-mac-header.cc:322
ns3::Bar
BlockAckRequest frame information.
Definition: block-ack-manager.h:49
ns3::MgtAddBaResponseHeader::GetBufferSize
uint16_t GetBufferSize(void) const
Return the buffer size.
Definition: mgt-headers.cc:1774
ns3::Packet::AddHeader
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
ns3::Callback
Callback template class.
Definition: callback.h:1279
ns3::Simulator::Now
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::BlockAckManager::SetTxOkCallback
void SetTxOkCallback(TxOk callback)
Definition: block-ack-manager.cc:838
ns3::BlockAckManager::DestroyAgreement
void DestroyAgreement(Mac48Address recipient, uint8_t tid)
Definition: block-ack-manager.cc:155
ns3::CtrlBAckResponseHeader::IsPacketReceived
bool IsPacketReceived(uint16_t seq, std::size_t index=0) const
Check if the packet with the given sequence number was acknowledged in this BlockAck response.
Definition: ctrl-headers.cc:939
ns3::Bar::bar
Ptr< const WifiMacQueueItem > bar
BlockAckRequest or MU-BAR Trigger Frame.
Definition: block-ack-manager.h:59
ns3::Callback::IsNull
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
qos-utils.h
ns3::CtrlBAckResponseHeader::IsExtendedCompressed
bool IsExtendedCompressed(void) const
Check if the current BA policy is Extended Compressed Block Ack.
Definition: ctrl-headers.cc:552
ns3::OriginatorBlockAckAgreement::NO_REPLY
@ NO_REPLY
Definition: originator-block-ack-agreement.h:105
ns3::CtrlBAckRequestHeader
Headers for BlockAckRequest.
Definition: ctrl-headers.h:49
ns3::MicroSeconds
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
ns3::BlockAckManager::SetQueue
void SetQueue(const Ptr< WifiMacQueue > queue)
Definition: block-ack-manager.cc:764
ns3::WifiMacHeader::SetDsNotFrom
void SetDsNotFrom(void)
Un-set the From DS bit in the Frame Control field.
Definition: wifi-mac-header.cc:90
ns3::BlockAckManager::NeedBarRetransmission
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...
Definition: block-ack-manager.cc:788
ns3::BlockAckManager
Manages all block ack agreements for an originator station.
Definition: block-ack-manager.h:70
ns3::CtrlTriggerHeader::IsMuBar
bool IsMuBar(void) const
Check if this is a MU-BAR Trigger frame.
Definition: ctrl-headers.cc:1780
ns3::BlockAckManager::NotifyMissedBlockAck
void NotifyMissedBlockAck(Mac48Address recipient, uint8_t tid)
Definition: block-ack-manager.cc:549
ns3::BlockAckManager::AgreementsCI
std::map< std::pair< Mac48Address, uint8_t >, std::pair< OriginatorBlockAckAgreement, PacketQueue > >::const_iterator AgreementsCI
typedef for a const iterator for Agreements.
Definition: block-ack-manager.h:459
ns3::MgtAddBaRequestHeader
Implement the header for management frames of type Add Block Ack request.
Definition: mgt-headers.h:1018
ns3::BlockAckManager::NotifyAgreementEstablished
void NotifyAgreementEstablished(Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
Definition: block-ack-manager.cc:710
ns3::Mac48Address
an EUI-48 address
Definition: mac48-address.h:44
ns3::WifiMacHeader::SetNoRetry
void SetNoRetry(void)
Un-set the Retry bit in the Frame Control field.
Definition: wifi-mac-header.cc:347
ns3::BlockAckManager::UpdateAgreement
void UpdateAgreement(const MgtAddBaResponseHeader *respHdr, Mac48Address recipient, uint16_t startingSeq)
Definition: block-ack-manager.cc:178
ns3::BlockAckManager::GetBar
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.
Definition: block-ack-manager.cc:264
ns3::WifiMacHeader::GetAddr1
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
Definition: wifi-mac-header.cc:424
ns3::BlockAckManager::PacketQueueI
std::list< Ptr< WifiMacQueueItem > >::iterator PacketQueueI
typedef for an iterator for PacketQueue.
Definition: block-ack-manager.h:440
ns3::WifiMacHeader::SetAddr3
void SetAddr3(Mac48Address address)
Fill the Address 3 field with the given address.
Definition: wifi-mac-header.cc:120
ns3::OriginatorBlockAckAgreement::PENDING
@ PENDING
Definition: originator-block-ack-agreement.h:103
ns3::Simulator::Schedule
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
ns3::WifiMacHeader::GetSequenceControl
uint16_t GetSequenceControl(void) const
Return the raw Sequence Control field.
Definition: wifi-mac-header.cc:771
ns3::BlockAckManager::NotifyAgreementNoReply
void NotifyAgreementNoReply(Mac48Address recipient, uint8_t tid)
Definition: block-ack-manager.cc:737
ns3::BlockAckManager::m_unblockPackets
Callback< void, Mac48Address, uint8_t > m_unblockPackets
unblock packets callback
Definition: block-ack-manager.h:492
ns3::WifiMacQueueItem::GetHeader
const WifiMacHeader & GetHeader(void) const
Get the header stored in this item.
Definition: wifi-mac-queue-item.cc:72
ns3::OriginatorBlockAckAgreement::REJECTED
@ REJECTED
Definition: originator-block-ack-agreement.h:107
ns3::TypeId::SetParent
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
ns3::MakeTraceSourceAccessor
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Definition: trace-source-accessor.h:202
ns3::BlockAckManager::m_bars
std::list< Bar > m_bars
list of BARs
Definition: block-ack-manager.h:486
ns3::Bar::skipIfNoDataQueued
bool skipIfNoDataQueued
do not send if there is no data queued (unused if MU-BAR)
Definition: block-ack-manager.h:61
ns3::BlockAckAgreement::SetImmediateBlockAck
void SetImmediateBlockAck(void)
Set block ack policy to immediate Ack.
Definition: block-ack-agreement.cc:79
ns3::BlockAckManager::ExistsAgreementInState
bool ExistsAgreementInState(Mac48Address recipient, uint8_t tid, OriginatorBlockAckAgreement::State state) const
Definition: block-ack-manager.cc:92
ns3::OriginatorBlockAckAgreement::InitTxWindow
void InitTxWindow(void)
Initialize the originator's transmit window by setting its size and starting sequence number equal to...
Definition: originator-block-ack-agreement.cc:95
ns3::BlockAckManager::ExistsAgreement
bool ExistsAgreement(Mac48Address recipient, uint8_t tid) const
Definition: block-ack-manager.cc:85
wifi-mac-queue.h
ns3::WifiMacHeader::SetAddr1
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
Definition: wifi-mac-header.cc:108
ns3::BlockAckAgreement::GetTimeout
uint16_t GetTimeout(void) const
Return the timeout.
Definition: block-ack-agreement.cc:119
ns3::MgtAddBaRequestHeader::IsAmsduSupported
bool IsAmsduSupported(void) const
Return whether A-MSDU capability is supported.
Definition: mgt-headers.cc:1600
ns3::WifiMacHeader
Implements the IEEE 802.11 MAC header.
Definition: wifi-mac-header.h:85
ns3::CtrlBAckResponseHeader::IsMultiSta
bool IsMultiSta(void) const
Check if the BlockAck frame variant is Multi-STA Block Ack.
Definition: ctrl-headers.cc:564
mgt-headers.h
ns3::BlockAckManager::m_droppedOldMpduCallback
DroppedOldMpdu m_droppedOldMpduCallback
the dropped MPDU callback
Definition: block-ack-manager.h:495
ns3::Ptr
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
ns3::BlockAckManager::SetUnblockDestinationCallback
void SetUnblockDestinationCallback(Callback< void, Mac48Address, uint8_t > callback)
Set unblock destination callback.
Definition: block-ack-manager.cc:831
NS_FATAL_ERROR
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
ns3::Mac48Address::GetBroadcast
static Mac48Address GetBroadcast(void)
Definition: mac48-address.cc:170
ns3::CtrlBAckRequestHeader::SetStartingSequence
void SetStartingSequence(uint16_t seq)
Set the starting sequence number from the given raw sequence control field.
Definition: ctrl-headers.cc:220
ns3::OriginatorBlockAckAgreement::SetState
void SetState(State state)
Set the current state.
Definition: originator-block-ack-agreement.cc:42
ns3::MgtAddBaResponseHeader::GetTid
uint8_t GetTid(void) const
Return the Traffic ID (TID).
Definition: mgt-headers.cc:1756
ctrl-headers.h
ns3::CtrlBAckResponseHeader::IsMultiTid
bool IsMultiTid(void) const
Check if the current BA policy is Multi-TID Block Ack.
Definition: ctrl-headers.cc:558
ns3::BlockAckReqType
The different BlockAckRequest variants.
Definition: block-ack-type.h:75
prev
uint32_t prev
Definition: tcp-bbr-example.cc:67
ns3::BlockAckManager::~BlockAckManager
~BlockAckManager()
Definition: block-ack-manager.cc:70
ns3::BlockAckManager::m_blockAckInactivityTimeout
Callback< void, Mac48Address, uint8_t, bool > m_blockAckInactivityTimeout
BlockAck inactivity timeout callback.
Definition: block-ack-manager.h:490
ns3::CtrlBAckRequestHeader::SetTidInfo
void SetTidInfo(uint8_t tid)
Set Traffic ID (TID).
Definition: ctrl-headers.cc:214
ns3::BlockAckManager::MpduStatus
MpduStatus
Enumeration for the statuses of a buffered MPDU.
Definition: block-ack-manager.h:85
ns3::QosUtilsIsOldPacket
bool QosUtilsIsOldPacket(uint16_t startingSeq, uint16_t seqNumber)
This function checks if packet with sequence number seqNumber is an "old" packet.
Definition: qos-utils.cc:178
ns3::MgtAddBaRequestHeader::GetStartingSequence
uint16_t GetStartingSequence(void) const
Return the starting sequence number.
Definition: mgt-headers.cc:1606
ns3::BlockAckManager::SetDroppedOldMpduCallback
void SetDroppedOldMpduCallback(DroppedOldMpdu callback)
Definition: block-ack-manager.cc:850
ns3::BlockAckManager::SetBlockAckInactivityCallback
void SetBlockAckInactivityCallback(Callback< void, Mac48Address, uint8_t, bool > callback)
Set block ack inactivity callback.
Definition: block-ack-manager.cc:817
ns3::BlockAckManager::STAY_INFLIGHT
@ STAY_INFLIGHT
Definition: block-ack-manager.h:86
ns3::Object
A base class which provides memory management and object aggregation.
Definition: object.h:88
ns3::BlockAckManager::DoDispose
void DoDispose() override
Destructor implementation.
Definition: block-ack-manager.cc:76
ns3::OriginatorBlockAckAgreement::State
State
Represents the state for this agreement.
Definition: originator-block-ack-agreement.h:102
wifi-tx-vector.h
ns3::BlockAckType
The different BlockAck variants.
Definition: block-ack-type.h:34
ns3::OriginatorBlockAckAgreement::ESTABLISHED
@ ESTABLISHED
Definition: originator-block-ack-agreement.h:104
ns3::CtrlTriggerHeader
Headers for Trigger frames.
Definition: ctrl-headers.h:886
ns3::MgtAddBaRequestHeader::IsImmediateBlockAck
bool IsImmediateBlockAck(void) const
Return whether the Block Ack policy is immediate Block Ack.
Definition: mgt-headers.cc:1582
ns3::BlockAckManager::m_blockPackets
Callback< void, Mac48Address, uint8_t > m_blockPackets
block packets callback
Definition: block-ack-manager.h:491
ns3::WifiMacHeader::IsQosData
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
Definition: wifi-mac-header.cc:565
first.address
address
Definition: first.py:44
ns3::MgtAddBaResponseHeader::GetTimeout
uint16_t GetTimeout(void) const
Return the timeout.
Definition: mgt-headers.cc:1768
ns3::MgtAddBaResponseHeader::IsAmsduSupported
bool IsAmsduSupported(void) const
Return whether A-MSDU capability is supported.
Definition: mgt-headers.cc:1780
ns3::BlockAckManager::SetTxFailedCallback
void SetTxFailedCallback(TxFailed callback)
Definition: block-ack-manager.cc:844
ns3::OriginatorBlockAckAgreement
Maintains the state and information about transmitted MPDUs with Ack Policy set to Block Ack for an o...
Definition: originator-block-ack-agreement.h:59
ns3::MgtAddBaRequestHeader::GetTid
uint8_t GetTid(void) const
Return the Traffic ID (TID).
Definition: mgt-headers.cc:1576
ns3::Time
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
ns3::WifiMacHeader::GetSequenceNumber
uint16_t GetSequenceNumber(void) const
Return the sequence number of the header.
Definition: wifi-mac-header.cc:777
ns3::BlockAckManager::GetBlockAckReqType
BlockAckReqType GetBlockAckReqType(Mac48Address recipient, uint8_t tid) const
This function returns the type of Block Acks sent to the recipient.
Definition: block-ack-manager.cc:868
ns3::BlockAckManager::HandleInFlightMpdu
PacketQueueI HandleInFlightMpdu(PacketQueueI mpduIt, MpduStatus status, const AgreementsI &it, const Time &now)
Handle the given in flight MPDU based on its given status.
Definition: block-ack-manager.cc:371
ns3::BlockAckManager::GetRecipientBufferSize
uint16_t GetRecipientBufferSize(Mac48Address recipient, uint8_t tid) const
This function returns the buffer size negotiated with the recipient.
Definition: block-ack-manager.cc:856
NS_ABORT_MSG_IF
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
ns3::MgtAddBaRequestHeader::GetTimeout
uint16_t GetTimeout(void) const
Return the timeout.
Definition: mgt-headers.cc:1588
ns3::WifiMacHeader::GetFragmentNumber
uint8_t GetFragmentNumber(void) const
Return the fragment number of the header.
Definition: wifi-mac-header.cc:783
ns3::BlockAckAgreement::SetStartingSequence
void SetStartingSequence(uint16_t seq)
Set starting sequence number.
Definition: block-ack-agreement.cc:63
ns3::MgtAddBaResponseHeader
Implement the header for management frames of type Add Block Ack response.
Definition: mgt-headers.h:1150
ns3::BlockAckAgreement::SetAmsduSupport
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support.
Definition: block-ack-agreement.cc:93
ns3::BlockAckManager::NotifyGotAck
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...
Definition: block-ack-manager.cc:432
ns3::WifiMacQueueItem::SetInFlight
void SetInFlight(void)
Mark this MPDU as being in flight (only used if Block Ack agreement established).
Definition: wifi-mac-queue-item.cc:225
ns3::WifiMacHeader::SetAddr2
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
Definition: wifi-mac-header.cc:114
ns3::WifiMacHeader::GetQosTid
uint8_t GetQosTid(void) const
Return the Traffic ID of a QoS header.
Definition: wifi-mac-header.cc:862
ns3::BlockAckManager::StorePacket
void StorePacket(Ptr< WifiMacQueueItem > mpdu)
Definition: block-ack-manager.cc:218
ns3::WIFI_MAC_CTL_BACKREQ
@ WIFI_MAC_CTL_BACKREQ
Definition: wifi-mac-header.h:43
ns3::CtrlBAckResponseHeader::GetAckType
bool GetAckType(std::size_t index) const
For Multi-STA Block Acks, get the Ack Type subfield of the Per AID TID Info subfield identified by th...
Definition: ctrl-headers.cc:597
ns3::CtrlBAckResponseHeader::GetTidInfo
uint8_t GetTidInfo(std::size_t index=0) const
For Block Ack variants other than Multi-STA Block Ack, get the TID_INFO subfield of the BA Control fi...
Definition: ctrl-headers.cc:510
timeout
ns3::Time timeout
Definition: openflow-switch.cc:52
NS_LOG_DEBUG
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
wifi-utils.h
ns3::BlockAckManager::ACKNOWLEDGED
@ ACKNOWLEDGED
Definition: block-ack-manager.h:88
ns3::BlockAckManager::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: block-ack-manager.cc:51
ns3::Bar::Bar
Bar()
Definition: block-ack-manager.cc:35
ns3::BlockAckAgreement::SetDelayedBlockAck
void SetDelayedBlockAck(void)
Set block ack policy to delayed Ack.
Definition: block-ack-agreement.cc:86
ns3::BlockAckAgreement::m_inactivityEvent
EventId m_inactivityEvent
inactivity event
Definition: block-ack-agreement.h:186
ns3::BlockAckManager::PacketQueue
std::list< Ptr< WifiMacQueueItem > > PacketQueue
typedef for a list of WifiMacQueueItem.
Definition: block-ack-manager.h:436
ns3::BlockAckManager::m_txOkCallback
TxOk m_txOkCallback
transmit OK callback
Definition: block-ack-manager.h:493
ns3::SEQNO_SPACE_HALF_SIZE
const uint16_t SEQNO_SPACE_HALF_SIZE
Size of the half the space of sequence numbers (used to determine old packets)
Definition: wifi-utils.h:134
ns3::BlockAckManager::SetBlockAckThreshold
void SetBlockAckThreshold(uint8_t nPackets)
Definition: block-ack-manager.cc:364
ns3::BlockAckManager::BlockAckManager
BlockAckManager()
Definition: block-ack-manager.cc:65
ns3::BlockAckManager::NotifyGotBlockAck
std::pair< uint16_t, uint16_t > NotifyGotBlockAck(const CtrlBAckResponseHeader &blockAck, Mac48Address recipient, const std::set< uint8_t > &tids, size_t index=0)
Definition: block-ack-manager.cc:483
ns3::BlockAckManager::TO_RETRANSMIT
@ TO_RETRANSMIT
Definition: block-ack-manager.h:87
ns3::BlockAckManager::m_agreementState
TracedCallback< Time, Mac48Address, uint8_t, OriginatorBlockAckAgreement::State > m_agreementState
The trace source fired when a state transition occurred.
Definition: block-ack-manager.h:500
NS_LOG_FUNCTION
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Definition: log-macros-enabled.h:244
ns3::BlockAckManager::NotifyDiscardedMpdu
void NotifyDiscardedMpdu(Ptr< const WifiMacQueueItem > mpdu)
Definition: block-ack-manager.cc:567
ns3::BlockAckAgreement::SetTimeout
void SetTimeout(uint16_t timeout)
Set timeout.
Definition: block-ack-agreement.cc:56
ns3::BlockAckManager::SetBlockDestinationCallback
void SetBlockDestinationCallback(Callback< void, Mac48Address, uint8_t > callback)
Set block destination callback.
Definition: block-ack-manager.cc:824
ns3::MgtAddBaRequestHeader::GetBufferSize
uint16_t GetBufferSize(void) const
Return the buffer size.
Definition: mgt-headers.cc:1594
ns3::WifiMacHeader::SetType
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
Definition: wifi-mac-header.cc:132
ns3::BlockAckManager::GetBlockAckType
BlockAckType GetBlockAckType(Mac48Address recipient, uint8_t tid) const
This function returns the type of Block Acks sent by the recipient.
Definition: block-ack-manager.cc:876
ns3::WifiMacHeader::SetDsNotTo
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
Definition: wifi-mac-header.cc:102
ns3::Bar::tid
uint8_t tid
TID (unused if MU-BAR)
Definition: block-ack-manager.h:60
ns3::CtrlBAckRequestHeader::GetStartingSequence
uint16_t GetStartingSequence(void) const
Return the starting sequence number.
Definition: ctrl-headers.cc:239
ns3::CtrlBAckResponseHeader::IsCompressed
bool IsCompressed(void) const
Check if the current BA policy is Compressed Block Ack.
Definition: ctrl-headers.cc:546
ns3::BlockAckManager::m_txFailedCallback
TxFailed m_txFailedCallback
transmit failed callback
Definition: block-ack-manager.h:494
ns3::BlockAckManager::m_blockAckThreshold
uint8_t m_blockAckThreshold
block ack threshold
Definition: block-ack-manager.h:488
ns3::BlockAckManager::ScheduleBar
void ScheduleBar(Ptr< const WifiMacQueueItem > bar, bool skipIfNoDataQueued=false)
Definition: block-ack-manager.cc:654
ns3::OriginatorBlockAckAgreement::RESET
@ RESET
Definition: originator-block-ack-agreement.h:106
block-ack-manager.h
ns3::BlockAckManager::GetOriginatorStartingSequence
uint16_t GetOriginatorStartingSequence(Mac48Address recipient, uint8_t tid) const
This function returns the starting sequence number of the transmit window.
Definition: block-ack-manager.cc:884
ns3::BlockAckManager::AgreementsI
std::map< std::pair< Mac48Address, uint8_t >, std::pair< OriginatorBlockAckAgreement, PacketQueue > >::iterator AgreementsI
typedef for an iterator for Agreements.
Definition: block-ack-manager.h:454
ns3::BlockAckManager::m_queue
Ptr< WifiMacQueue > m_queue
queue
Definition: block-ack-manager.h:489
ns3::BlockAckManager::NotifyAgreementRejected
void NotifyAgreementRejected(Mac48Address recipient, uint8_t tid)
Definition: block-ack-manager.cc:724
ns3::BlockAckManager::NotifyMissedAck
void NotifyMissedAck(Ptr< WifiMacQueueItem > mpdu)
Invoked upon missed reception of an Ack frame after the transmission of a QoS data frame sent under a...
Definition: block-ack-manager.cc:458
ns3::CtrlBAckRequestHeader::GetTidInfo
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
Definition: ctrl-headers.cc:232
ns3::CtrlBAckRequestHeader::SetType
void SetType(BlockAckReqType type)
Set the BlockAckRequest type.
Definition: ctrl-headers.cc:202
ns3::BlockAckManager::InactivityTimeout
void InactivityTimeout(Mac48Address recipient, uint8_t tid)
Inactivity timeout function.
Definition: block-ack-manager.cc:703
ns3::CtrlBAckResponseHeader
Headers for BlockAck response.
Definition: ctrl-headers.h:202
ns3::BlockAckAgreement::SetBufferSize
void SetBufferSize(uint16_t bufferSize)
Set buffer size.
Definition: block-ack-agreement.cc:47
ns3::BlockAckManager::m_agreements
Agreements m_agreements
This data structure contains, for each block ack agreement (recipient, TID), a set of packets for whi...
Definition: block-ack-manager.h:484