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  PacketQueueI it = agreementIt->second.second.begin ();
240  while (it != agreementIt->second.second.end ())
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 (it, 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) == m_queue->end ())
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  WifiMacQueue::ConstIterator queueIt = (*mpduIt)->GetQueueIterator ();
313 
314  if ((*mpduIt)->GetTimeStamp () + m_queue->GetMaxDelay () <= now)
315  {
316  // MPDU expired
317  it->second.first.NotifyDiscardedMpdu (*mpduIt);
318  // Remove from the EDCA queue and fire the Expired trace source, but the
319  // consequent call to NotifyDiscardedMpdu does nothing (in particular,
320  // does not schedule a BAR) because we have advanced the transmit window
321  // and hence this MPDU became an old packet
322  m_queue->TtlExceeded (queueIt, now);
323  mpduIt = it->second.second.erase (mpduIt);
324  }
325  else
326  {
327  // MPDUs are typically in increasing order of remaining lifetime
328  break;
329  }
330  }
331  // update BAR if the starting sequence number changed
332  CtrlBAckRequestHeader reqHdr;
333  nextBar->bar->GetPacket ()->PeekHeader (reqHdr);
334  if (reqHdr.GetStartingSequence () != it->second.first.GetStartingSequence ())
335  {
336  reqHdr.SetStartingSequence (it->second.first.GetStartingSequence ());
337  Ptr<Packet> packet = Create<Packet> ();
338  packet->AddHeader (reqHdr);
339  nextBar->bar = Create<const WifiMacQueueItem> (packet, nextBar->bar->GetHeader ());
340  }
341  }
342 
343  bar = nextBar->bar;
344  if (remove)
345  {
346  m_bars.erase (nextBar);
347  }
348  break;
349  }
350  return bar;
351 }
352 
353 uint32_t
355 {
356  NS_LOG_FUNCTION (this << recipient << +tid);
357  AgreementsCI it = m_agreements.find (std::make_pair (recipient, tid));
358  if (it == m_agreements.end ())
359  {
360  return 0;
361  }
362  return it->second.second.size ();
363 }
364 
365 void
367 {
368  NS_LOG_FUNCTION (this << +nPackets);
369  m_blockAckThreshold = nPackets;
370 }
371 
374  const AgreementsI& it, const Time& now)
375 {
376  NS_LOG_FUNCTION (this << **mpduIt << +static_cast<uint8_t> (status));
377 
378  if (!(*mpduIt)->IsQueued ())
379  {
380  // MPDU is not in the EDCA queue (e.g., its lifetime expired and it was
381  // removed by another method), remove from the queue of in flight MPDUs
382  NS_LOG_DEBUG ("MPDU is not stored in the EDCA queue, drop MPDU");
383  return it->second.second.erase (mpduIt);
384  }
385 
386  if (status == ACKNOWLEDGED)
387  {
388  // the MPDU has to be dequeued from the EDCA queue
389  m_queue->DequeueIfQueued (*mpduIt);
390  return it->second.second.erase (mpduIt);
391  }
392 
393  WifiMacHeader& hdr = (*mpduIt)->GetHeader ();
394  WifiMacQueue::ConstIterator queueIt = (*mpduIt)->GetQueueIterator ();
395 
396  NS_ASSERT (hdr.GetAddr1 () == it->first.first);
397  NS_ASSERT (hdr.IsQosData () && hdr.GetQosTid () == it->first.second);
398 
399  if (it->second.first.GetDistance (hdr.GetSequenceNumber ()) >= SEQNO_SPACE_HALF_SIZE)
400  {
401  NS_LOG_DEBUG ("Old packet. Remove from the EDCA queue, too");
403  {
404  m_droppedOldMpduCallback (*queueIt);
405  }
406  m_queue->Remove (queueIt);
407  return it->second.second.erase (mpduIt);
408  }
409 
410  auto nextIt = std::next (mpduIt);
411 
412  if (m_queue->TtlExceeded (queueIt, now))
413  {
414  // WifiMacQueue::TtlExceeded() has removed the MPDU from the EDCA queue
415  // and fired the Expired trace source, which called NotifyDiscardedMpdu,
416  // which removed this MPDU from the in flight queue as well
417  NS_LOG_DEBUG ("MSDU lifetime expired, drop MPDU");
418  return nextIt;
419  }
420 
421  if (status == STAY_INFLIGHT)
422  {
423  // the MPDU has to stay in flight, do nothing
424  return ++mpduIt;
425  }
426 
427  NS_ASSERT (status == TO_RETRANSMIT);
428  (*mpduIt)->GetHeader ().SetRetry ();
429  (*mpduIt)->ResetInFlight (); // no longer in flight; will be if retransmitted
430 
431  return it->second.second.erase (mpduIt);
432 }
433 
434 void
436 {
437  NS_LOG_FUNCTION (this << *mpdu);
438  NS_ASSERT (mpdu->GetHeader ().IsQosData ());
439 
440  Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
441  uint8_t tid = mpdu->GetHeader ().GetQosTid ();
443 
444  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
445  NS_ASSERT (it != m_agreements.end ());
446 
447  // remove the acknowledged frame from the queue of outstanding packets
448  for (auto queueIt = it->second.second.begin (); queueIt != it->second.second.end (); ++queueIt)
449  {
450  if ((*queueIt)->GetHeader ().GetSequenceNumber () == mpdu->GetHeader ().GetSequenceNumber ())
451  {
453  break;
454  }
455  }
456 
457  it->second.first.NotifyAckedMpdu (mpdu);
458 }
459 
460 void
462 {
463  NS_LOG_FUNCTION (this << *mpdu);
464  NS_ASSERT (mpdu->GetHeader ().IsQosData ());
465 
466  Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
467  uint8_t tid = mpdu->GetHeader ().GetQosTid ();
469 
470  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
471  NS_ASSERT (it != m_agreements.end ());
472 
473  // remove the frame from the queue of outstanding packets (it will be re-inserted
474  // if retransmitted)
475  for (auto queueIt = it->second.second.begin (); queueIt != it->second.second.end (); ++queueIt)
476  {
477  if ((*queueIt)->GetHeader ().GetSequenceNumber () == mpdu->GetHeader ().GetSequenceNumber ())
478  {
480  break;
481  }
482  }
483 }
484 
485 std::pair<uint16_t,uint16_t>
487  const std::set<uint8_t>& tids, size_t index)
488 {
489  NS_LOG_FUNCTION (this << blockAck << recipient << index);
490  uint16_t nSuccessfulMpdus = 0;
491  uint16_t nFailedMpdus = 0;
492 
493  NS_ABORT_MSG_IF (blockAck.IsBasic (), "Basic Block Ack is not supported");
494  NS_ABORT_MSG_IF (blockAck.IsMultiTid (), "Multi-TID Block Ack is not supported");
495 
496  uint8_t tid = blockAck.GetTidInfo (index);
497  // If this is a Multi-STA Block Ack with All-ack context (TID equal to 14),
498  // use the TID passed by the caller.
499  if (tid == 14)
500  {
501  NS_ASSERT (blockAck.GetAckType (index) && tids.size () == 1);
502  tid = *tids.begin ();
503  }
505  {
506  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
507 
508  if (it->second.first.m_inactivityEvent.IsRunning ())
509  {
510  /* Upon reception of a BlockAck frame, the inactivity timer at the
511  originator must be reset.
512  For more details see section 11.5.3 in IEEE802.11e standard */
513  it->second.first.m_inactivityEvent.Cancel ();
514  Time timeout = MicroSeconds (1024 * it->second.first.GetTimeout ());
515  it->second.first.m_inactivityEvent = Simulator::Schedule (timeout,
517  this,
518  recipient, tid);
519  }
520 
521  NS_ASSERT (blockAck.IsCompressed () || blockAck.IsExtendedCompressed () || blockAck.IsMultiSta ());
522  Time now = Simulator::Now ();
523 
524  for (auto queueIt = it->second.second.begin (); queueIt != it->second.second.end (); )
525  {
526  uint16_t currentSeq = (*queueIt)->GetHeader ().GetSequenceNumber ();
527  if (blockAck.IsPacketReceived (currentSeq, index))
528  {
529  it->second.first.NotifyAckedMpdu (*queueIt);
530  nSuccessfulMpdus++;
531  if (!m_txOkCallback.IsNull ())
532  {
533  m_txOkCallback (*queueIt);
534  }
535  queueIt = HandleInFlightMpdu (queueIt, ACKNOWLEDGED, it, now);
536  }
537  else
538  {
539  nFailedMpdus++;
540  if (!m_txFailedCallback.IsNull ())
541  {
542  m_txFailedCallback (*queueIt);
543  }
544  queueIt = HandleInFlightMpdu (queueIt, TO_RETRANSMIT, it, now);
545  }
546  }
547  }
548  return {nSuccessfulMpdus, nFailedMpdus};
549 }
550 
551 void
553 {
554  NS_LOG_FUNCTION (this << recipient << +tid);
556  {
557  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
558  Time now = Simulator::Now ();
559 
560  // remove all packets from the queue of outstanding packets (they will be
561  // re-inserted if retransmitted)
562  for (auto mpduIt = it->second.second.begin (); mpduIt != it->second.second.end (); )
563  {
564  mpduIt = HandleInFlightMpdu (mpduIt, TO_RETRANSMIT, it, now);
565  }
566  }
567 }
568 
569 void
571 {
572  NS_LOG_FUNCTION (this << *mpdu);
573 
574  if (!mpdu->GetHeader ().IsQosData ())
575  {
576  NS_LOG_DEBUG ("Not a QoS Data frame");
577  return;
578  }
579 
580  if (!mpdu->GetHeader ().IsRetry () && !mpdu->IsInFlight ())
581  {
582  NS_LOG_DEBUG ("This frame has never been transmitted");
583  return;
584  }
585 
586  Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
587  uint8_t tid = mpdu->GetHeader ().GetQosTid ();
589  {
590  NS_LOG_DEBUG ("No established Block Ack agreement");
591  return;
592  }
593 
594  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
595  uint16_t currStartingSeq = it->second.first.GetStartingSequence ();
596  if (QosUtilsIsOldPacket (currStartingSeq, mpdu->GetHeader ().GetSequenceNumber ()))
597  {
598  NS_LOG_DEBUG ("Discarded an old frame");
599  return;
600  }
601 
602  // actually advance the transmit window
603  it->second.first.NotifyDiscardedMpdu (mpdu);
604 
605  // remove old MPDUs from the EDCA queue and from the in flight queue
606  // (including the given MPDU which became old after advancing the transmit window)
607  for (auto mpduIt = it->second.second.begin (); mpduIt != it->second.second.end (); )
608  {
609  if (it->second.first.GetDistance ((*mpduIt)->GetHeader ().GetSequenceNumber ()) >= SEQNO_SPACE_HALF_SIZE)
610  {
611  m_queue->DequeueIfQueued (*mpduIt);
613  {
614  m_droppedOldMpduCallback (*mpduIt);
615  }
616  mpduIt = it->second.second.erase (mpduIt);
617  }
618  else
619  {
620  break; // MPDUs are in increasing order of sequence number in the in flight queue
621  }
622  }
623 
624  // schedule a BlockAckRequest
625  NS_LOG_DEBUG ("Schedule a Block Ack Request for agreement (" << recipient << ", " << +tid << ")");
626  Ptr<Packet> bar = Create<Packet> ();
627  bar->AddHeader (GetBlockAckReqHeader (recipient, tid));
628 
629  WifiMacHeader hdr;
631  hdr.SetAddr1 (recipient);
632  hdr.SetAddr2 (mpdu->GetHeader ().GetAddr2 ());
633  hdr.SetAddr3 (mpdu->GetHeader ().GetAddr3 ());
634  hdr.SetDsNotTo ();
635  hdr.SetDsNotFrom ();
636  hdr.SetNoRetry ();
637  hdr.SetNoMoreFragments ();
638 
639  ScheduleBar (Create<const WifiMacQueueItem> (bar, hdr));
640 }
641 
644 {
645  NS_LOG_FUNCTION (this << recipient << +tid);
646  AgreementsCI it = m_agreements.find (std::make_pair (recipient, tid));
647  NS_ASSERT (it != m_agreements.end ());
648 
649  CtrlBAckRequestHeader reqHdr;
650  reqHdr.SetType ((*it).second.first.GetBlockAckReqType ());
651  reqHdr.SetTidInfo (tid);
652  reqHdr.SetStartingSequence ((*it).second.first.GetStartingSequence ());
653  return reqHdr;
654 }
655 
656 void
658 {
659  NS_LOG_FUNCTION (this << *bar);
660  NS_ASSERT (bar->GetHeader ().IsBlockAckReq () || bar->GetHeader ().IsTrigger ());
661 
662  uint8_t tid = 0;
663  if (bar->GetHeader ().IsBlockAckReq ())
664  {
665  CtrlBAckRequestHeader reqHdr;
666  bar->GetPacket ()->PeekHeader (reqHdr);
667  tid = reqHdr.GetTidInfo ();
668  }
669 #ifdef NS3_BUILD_PROFILE_DEBUG
670  else
671  {
672  CtrlTriggerHeader triggerHdr;
673  bar->GetPacket ()->PeekHeader (triggerHdr);
674  NS_ASSERT (triggerHdr.IsMuBar ());
675  }
676 #endif
677  Bar request (bar, tid, skipIfNoDataQueued);
678 
679  // if a BAR for the given agreement is present, replace it with the new one
680  std::list<Bar>::const_iterator i = m_bars.end ();
681 
682  if (bar->GetHeader ().IsBlockAckReq ())
683  {
684  for (i = m_bars.begin (); i != m_bars.end (); i++)
685  {
686  if (i->bar->GetHeader ().IsBlockAckReq ()
687  && i->bar->GetHeader ().GetAddr1 () == bar->GetHeader ().GetAddr1 () && i->tid == tid)
688  {
689  i = m_bars.erase (i);
690  break;
691  }
692  }
693  }
694 
695  if (bar->GetHeader ().IsRetry ())
696  {
697  m_bars.push_front (request);
698  }
699  else
700  {
701  m_bars.insert (i, request);
702  }
703 }
704 
705 void
707 {
708  NS_LOG_FUNCTION (this << recipient << +tid);
709  m_blockAckInactivityTimeout (recipient, tid, true);
710 }
711 
712 void
713 BlockAckManager::NotifyAgreementEstablished (Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
714 {
715  NS_LOG_FUNCTION (this << recipient << +tid << startingSeq);
716  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
717  NS_ASSERT (it != m_agreements.end ());
718  if (!it->second.first.IsEstablished ())
719  {
721  }
722  it->second.first.SetState (OriginatorBlockAckAgreement::ESTABLISHED);
723  it->second.first.SetStartingSequence (startingSeq);
724 }
725 
726 void
728 {
729  NS_LOG_FUNCTION (this << recipient << +tid);
730  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
731  NS_ASSERT (it != m_agreements.end ());
732  if (!it->second.first.IsRejected ())
733  {
735  }
736  it->second.first.SetState (OriginatorBlockAckAgreement::REJECTED);
737 }
738 
739 void
741 {
742  NS_LOG_FUNCTION (this << recipient << +tid);
743  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
744  NS_ASSERT (it != m_agreements.end ());
745  if (!it->second.first.IsNoReply ())
746  {
748  }
749  it->second.first.SetState (OriginatorBlockAckAgreement::NO_REPLY);
750  m_unblockPackets (recipient, tid);
751 }
752 
753 void
755 {
756  NS_LOG_FUNCTION (this << recipient << +tid);
757  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
758  NS_ASSERT (it != m_agreements.end ());
759  if (!it->second.first.IsReset ())
760  {
762  }
763  it->second.first.SetState (OriginatorBlockAckAgreement::RESET);
764 }
765 
766 void
768 {
769  NS_LOG_FUNCTION (this << queue);
770  m_queue = queue;
771 }
772 
773 bool
774 BlockAckManager::SwitchToBlockAckIfNeeded (Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
775 {
776  NS_LOG_FUNCTION (this << recipient << +tid << startingSeq);
778  if (!ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::REJECTED) && ExistsAgreement (recipient, tid))
779  {
780  uint32_t packets = m_queue->GetNPacketsByTidAndAddress (tid, recipient) +
781  GetNBufferedPackets (recipient, tid);
782  if (packets >= m_blockAckThreshold)
783  {
784  NotifyAgreementEstablished (recipient, tid, startingSeq);
785  return true;
786  }
787  }
788  return false;
789 }
790 
792 {
794  {
795  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
796  NS_ASSERT (it != m_agreements.end ());
797 
798  Time now = Simulator::Now ();
799 
800  // A BAR needs to be retransmitted if there is at least a non-expired in flight MPDU
801  for (auto mpduIt = it->second.second.begin (); mpduIt != it->second.second.end (); )
802  {
803  // remove MPDU if old or with expired lifetime
804  mpduIt = HandleInFlightMpdu (mpduIt, STAY_INFLIGHT, it, now);
805 
806  if (mpduIt != it->second.second.begin ())
807  {
808  // the MPDU has not been removed
809  return true;
810  }
811  }
812  }
813 
814  // If the inactivity timer has expired, QosTxop::SendDelbaFrame has been called and
815  // has destroyed the agreement, hence we get here and correctly return false
816  return false;
817 }
818 
819 void
821 {
822  NS_LOG_FUNCTION (this << &callback);
823  m_blockAckInactivityTimeout = callback;
824 }
825 
826 void
828 {
829  NS_LOG_FUNCTION (this << &callback);
830  m_blockPackets = callback;
831 }
832 
833 void
835 {
836  NS_LOG_FUNCTION (this << &callback);
837  m_unblockPackets = callback;
838 }
839 
840 void
842 {
843  m_txOkCallback = callback;
844 }
845 
846 void
848 {
849  m_txFailedCallback = callback;
850 }
851 
852 void
854 {
855  m_droppedOldMpduCallback = callback;
856 }
857 
858 uint16_t
860 {
861  uint16_t size = 0;
862  AgreementsCI it = m_agreements.find (std::make_pair (recipient, tid));
863  if (it != m_agreements.end ())
864  {
865  size = it->second.first.GetBufferSize ();
866  }
867  return size;
868 }
869 
871 BlockAckManager::GetBlockAckReqType (Mac48Address recipient, uint8_t tid) const
872 {
873  AgreementsCI it = m_agreements.find (std::make_pair (recipient, tid));
874  NS_ABORT_MSG_IF (it == m_agreements.end (), "No established Block Ack agreement");
875  return it->second.first.GetBlockAckReqType ();
876 }
877 
879 BlockAckManager::GetBlockAckType (Mac48Address recipient, uint8_t tid) const
880 {
881  AgreementsCI it = m_agreements.find (std::make_pair (recipient, tid));
882  NS_ABORT_MSG_IF (it == m_agreements.end (), "No established Block Ack agreement");
883  return it->second.first.GetBlockAckType ();
884 }
885 
886 uint16_t
888 {
889  uint16_t seqNum = 0;
890  AgreementsCI it = m_agreements.find (std::make_pair (recipient, tid));
891  if (it != m_agreements.end ())
892  {
893  seqNum = it->second.first.GetStartingSequence ();
894  }
895  return seqNum;
896 }
897 
898 } //namespace ns3
ns3::BlockAckManager::GetBlockAckReqHeader
CtrlBAckRequestHeader GetBlockAckReqHeader(Mac48Address recipient, uint8_t tid) const
Definition: block-ack-manager.cc:643
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:354
ns3::BlockAckManager::SwitchToBlockAckIfNeeded
bool SwitchToBlockAckIfNeeded(Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
Definition: block-ack-manager.cc:774
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:754
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:841
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:767
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:791
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:552
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:713
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:557
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:740
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:65
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:834
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
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:853
ns3::BlockAckManager::SetBlockAckInactivityCallback
void SetBlockAckInactivityCallback(Callback< void, Mac48Address, uint8_t, bool > callback)
Set block ack inactivity callback.
Definition: block-ack-manager.cc:820
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:847
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:871
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:373
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:859
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:435
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:366
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:486
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:570
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:827
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:879
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:657
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:887
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:727
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:461
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:706
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