A Discrete-Event Network Simulator
API
qos-txop.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2006, 2009 INRIA
4  * Copyright (c) 2009 MIRKO BANCHI
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20  * Mirko Banchi <mk.banchi@gmail.com>
21  * Stefano Avallone <stavalli@unina.it>
22  */
23 
24 #include "ns3/log.h"
25 #include "ns3/pointer.h"
26 #include "ns3/simulator.h"
27 #include "ns3/random-variable-stream.h"
28 #include "qos-txop.h"
29 #include "channel-access-manager.h"
30 #include "mac-tx-middle.h"
31 #include "mgt-headers.h"
32 #include "wifi-mac-trailer.h"
33 #include "wifi-mac-queue.h"
36 #include "msdu-aggregator.h"
37 #include "mpdu-aggregator.h"
38 #include "ctrl-headers.h"
39 #include "wifi-phy.h"
40 #include "wifi-psdu.h"
41 #include "ns3/ht-frame-exchange-manager.h"
42 #include "wifi-tx-parameters.h"
43 
44 #undef NS_LOG_APPEND_CONTEXT
45 #define NS_LOG_APPEND_CONTEXT if (m_stationManager != 0 && m_stationManager->GetMac () != 0) { std::clog << "[mac=" << m_stationManager->GetMac ()->GetAddress () << "] "; }
46 
47 namespace ns3 {
48 
49 NS_LOG_COMPONENT_DEFINE ("QosTxop");
50 
52 
53 TypeId
55 {
56  static TypeId tid = TypeId ("ns3::QosTxop")
57  .SetParent<ns3::Txop> ()
58  .SetGroupName ("Wifi")
59  .AddConstructor<QosTxop> ()
60  .AddAttribute ("UseExplicitBarAfterMissedBlockAck",
61  "Specify whether explicit BlockAckRequest should be sent upon missed BlockAck Response.",
62  BooleanValue (true),
65  .AddAttribute ("AddBaResponseTimeout",
66  "The timeout to wait for ADDBA response after the Ack to "
67  "ADDBA request is received.",
68  TimeValue (MilliSeconds (1)),
71  MakeTimeChecker ())
72  .AddAttribute ("FailedAddBaTimeout",
73  "The timeout after a failed BA agreement. During this "
74  "timeout, the originator resumes sending packets using normal "
75  "MPDU. After that, BA agreement is reset and the originator "
76  "will retry BA negotiation.",
77  TimeValue (MilliSeconds (200)),
80  MakeTimeChecker ())
81  .AddAttribute ("BlockAckManager",
82  "The BlockAckManager object.",
83  PointerValue (),
85  MakePointerChecker<BlockAckManager> ())
86  .AddTraceSource ("TxopTrace",
87  "Trace source for TXOP start and duration times",
89  "ns3::TracedValueCallback::Time")
90  ;
91  return tid;
92 }
93 
95  : m_startTxop (Seconds (0)),
96  m_txopDuration (Seconds (0))
97 {
98  NS_LOG_FUNCTION (this);
99  m_qosBlockedDestinations = Create<QosBlockedDestinations> ();
100  m_baManager = CreateObject<BlockAckManager> ();
101  m_baManager->SetQueue (m_queue);
104 }
105 
107 {
108  NS_LOG_FUNCTION (this);
109 }
110 
111 void
113 {
114  NS_LOG_FUNCTION (this);
115  m_baManager = 0;
117  m_qosFem = 0;
118  Txop::DoDispose ();
119 }
120 
121 void
123 {
124  NS_LOG_FUNCTION (this << *mpdu);
125 
126  WifiMacHeader& hdr = mpdu->GetHeader ();
127  NS_ASSERT (hdr.IsQosData ());
128 
129  uint32_t bufferSize = m_queue->GetNBytes (hdr.GetQosTid (), hdr.GetAddr1 ())
130  + m_baManager->GetRetransmitQueue ()->GetNBytes (hdr.GetQosTid (), hdr.GetAddr1 ());
131  // A queue size value of 254 is used for all sizes greater than 64 768 octets.
132  uint8_t queueSize = static_cast<uint8_t> (std::ceil (std::min (bufferSize, 64769u) / 256.0));
133  NS_LOG_DEBUG ("Buffer size=" << bufferSize << " Queue Size=" << +queueSize);
134  hdr.SetQosQueueSize (queueSize);
135 }
136 
137 void
139 {
140  NS_LOG_FUNCTION (this << qosFem);
141  m_qosFem = qosFem;
142 }
143 
144 void
146 {
147  NS_LOG_FUNCTION (this << &callback);
148  Txop::SetDroppedMpduCallback (callback);
149  m_baManager->GetRetransmitQueue ()->TraceConnectWithoutContext ("Expired",
152 }
153 
156 {
157  return m_baManager;
158 }
159 
160 bool
162 {
163  return m_baManager->ExistsAgreementInState (address, tid, OriginatorBlockAckAgreement::ESTABLISHED);
164 }
165 
166 uint16_t
168 {
169  return m_baManager->GetRecipientBufferSize (address, tid);
170 }
171 
172 uint16_t
174 {
175  return m_baManager->GetOriginatorStartingSequence (address, tid);
176 }
177 
179 QosTxop::PrepareBlockAckRequest (Mac48Address recipient, uint8_t tid) const
180 {
181  NS_LOG_FUNCTION (this << recipient << +tid);
182  NS_ASSERT (QosUtilsMapTidToAc (tid) == m_ac);
183 
184  CtrlBAckRequestHeader reqHdr = m_baManager->GetBlockAckReqHeader (recipient, tid);
185  Ptr<Packet> bar = Create<Packet> ();
186  bar->AddHeader (reqHdr);
187 
188  WifiMacHeader hdr;
190  hdr.SetAddr1 (recipient);
191  hdr.SetAddr2 (m_stationManager->GetMac ()->GetAddress ());
192  hdr.SetDsNotTo ();
193  hdr.SetDsNotFrom ();
194  hdr.SetNoRetry ();
195  hdr.SetNoMoreFragments ();
196 
197  return Create<const WifiMacQueueItem> (bar, hdr);
198 }
199 
200 void
201 QosTxop::ScheduleBar (Ptr<const WifiMacQueueItem> bar, bool skipIfNoDataQueued)
202 {
203  m_baManager->ScheduleBar (bar, skipIfNoDataQueued);
204 }
205 
206 void
208 {
209  Txop::SetWifiRemoteStationManager (remoteManager);
210  NS_LOG_FUNCTION (this << remoteManager);
211  m_baManager->SetWifiRemoteStationManager (m_stationManager);
212 }
213 
214 bool
216 {
218 }
219 
220 bool
222 {
223  // check if the BA manager retransmit queue is empty, so that expired
224  // frames (if any) are removed and a BlockAckRequest is scheduled to advance
225  // the starting sequence number of the transmit (and receiver) window
226  bool baManagerHasPackets = m_baManager->HasPackets ();
227  // remove MSDUs with expired lifetime starting from the head of the queue
228  // TODO Add a WifiMacQueue method that serves this purpose; IsEmpty () can
229  // then reuse such method.
230  m_queue->IsEmpty ();
231  bool queueIsNotEmpty = (m_queue->PeekFirstAvailable (m_qosBlockedDestinations) != m_queue->end ());
232 
233  bool ret = (baManagerHasPackets || queueIsNotEmpty);
234  NS_LOG_FUNCTION (this << baManagerHasPackets << queueIsNotEmpty);
235  return ret;
236 }
237 
238 uint16_t
240 {
241  return m_txMiddle->GetNextSequenceNumberFor (hdr);
242 }
243 
244 uint16_t
246 {
247  return m_txMiddle->PeekNextSequenceNumberFor (hdr);
248 }
249 
250 bool
252 {
253  NS_LOG_FUNCTION (this << *mpdu);
254 
255  if (!mpdu->GetHeader ().IsQosData ())
256  {
257  return false;
258  }
259 
260  Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
261  uint8_t tid = mpdu->GetHeader ().GetQosTid ();
262 
263  if (!GetBaAgreementEstablished (recipient, tid))
264  {
265  return false;
266  }
267 
268  if (QosUtilsIsOldPacket (GetBaStartingSequence (recipient, tid),
269  mpdu->GetHeader ().GetSequenceNumber ()))
270  {
271  return true;
272  }
273  return false;
274 }
275 
277 QosTxop::PeekNextMpdu (uint8_t tid, Mac48Address recipient)
278 {
279  return PeekNextMpdu ({nullptr, WifiMacQueue::EMPTY}, tid, recipient);
280 }
281 
284 {
285  NS_LOG_FUNCTION (this << +tid << recipient);
286 
287  // lambda to peek the next frame
288  auto peek = [this, &tid, &recipient, &queueIt] () -> WifiMacQueue::ConstIterator
289  {
290  if (tid == 8 && recipient.IsBroadcast ()) // undefined TID and recipient
291  {
292  return queueIt.queue->PeekFirstAvailable (m_qosBlockedDestinations, queueIt.it);
293  }
294  if (m_qosBlockedDestinations->IsBlocked (recipient, tid))
295  {
296  return queueIt.queue->end ();
297  }
298  return queueIt.queue->PeekByTidAndAddress (tid, recipient, queueIt.it);
299  };
300 
301  if (queueIt.queue == nullptr && queueIt.it == WifiMacQueue::EMPTY)
302  {
303  // check if there is a packet in the BlockAckManager retransmit queue
304  queueIt.queue = PeekPointer (m_baManager->GetRetransmitQueue ());
305  }
306 
307  if (queueIt.queue == PeekPointer (m_baManager->GetRetransmitQueue ()))
308  {
309  queueIt.it = peek ();
310  // remove old packets
311  while (queueIt.it != m_baManager->GetRetransmitQueue ()->end () && IsQosOldPacket (*queueIt.it))
312  {
313  NS_LOG_DEBUG ("Removing an old packet from BlockAckManager retransmit queue: " << **queueIt.it);
314  queueIt.it = m_baManager->GetRetransmitQueue ()->Remove (queueIt.it);
315  queueIt.it = peek ();
316  }
317  if (queueIt.it != m_baManager->GetRetransmitQueue ()->end ())
318  {
319  NS_LOG_DEBUG ("Packet peeked from BlockAckManager retransmit queue: " << **queueIt.it);
320  return *queueIt.it;
321  }
322  // otherwise, check if there is a packet in the EDCA queue
323  queueIt = {PeekPointer (m_queue), WifiMacQueue::EMPTY};
324  }
325 
326  queueIt.it = peek ();
327  if (queueIt.it != m_queue->end ())
328  {
329  // peek the next sequence number and check if it is within the transmit window
330  // in case of QoS data frame
331  uint16_t sequence = m_txMiddle->PeekNextSequenceNumberFor (&(*queueIt.it)->GetHeader ());
332  if ((*queueIt.it)->GetHeader ().IsQosData ())
333  {
334  Mac48Address recipient = (*queueIt.it)->GetHeader ().GetAddr1 ();
335  uint8_t tid = (*queueIt.it)->GetHeader ().GetQosTid ();
336 
337  if (GetBaAgreementEstablished (recipient, tid)
338  && !IsInWindow (sequence, GetBaStartingSequence (recipient, tid), GetBaBufferSize (recipient, tid)))
339  {
340  NS_LOG_DEBUG ("Packet beyond the end of the current transmit window");
341  return 0;
342  }
343  }
344 
345  WifiMacHeader& hdr = (*queueIt.it)->GetHeader ();
346  // Assign a sequence number if this is not a fragment nor a retransmission
347  if (!(*queueIt.it)->IsFragment () && !hdr.IsRetry ())
348  {
349  hdr.SetSequenceNumber (sequence);
350  }
351  NS_LOG_DEBUG ("Packet peeked from EDCA queue: " << **queueIt.it);
352  return *queueIt.it;
353  }
354 
355  return 0;
356 }
357 
360  Time availableTime, bool initialFrame, WifiMacQueueItem::QueueIteratorPair& queueIt)
361 {
362  NS_ASSERT (peekedItem != 0);
363  NS_ASSERT (m_qosFem != 0);
364  NS_LOG_FUNCTION (this << *peekedItem << &txParams << availableTime << initialFrame);
365 
366  Mac48Address recipient = peekedItem->GetHeader ().GetAddr1 ();
367 
368  // The TXOP limit can be exceeded by the TXOP holder if it does not transmit more
369  // than one Data or Management frame in the TXOP and the frame is not in an A-MPDU
370  // consisting of more than one MPDU (Sec. 10.22.2.8 of 802.11-2016)
371  Time actualAvailableTime = (initialFrame && txParams.GetSize (recipient) == 0
372  ? Time::Min () : availableTime);
373 
374  if (!m_qosFem->TryAddMpdu (peekedItem, txParams, actualAvailableTime))
375  {
376  return nullptr;
377  }
378 
379  NS_ASSERT (peekedItem->IsQueued ());
380  NS_ASSERT_MSG (peekedItem->GetQueueIteratorPairs ().size () == 1,
381  "An item in the MAC queue cannot contain an A-MSDU");
382  WifiMacQueueItem::QueueIteratorPair peekedIt = peekedItem->GetQueueIteratorPairs ().front ();
383  NS_ASSERT ((*peekedIt.it)->GetPacket () == peekedItem->GetPacket ());
384 
385  if (peekedIt.queue == PeekPointer (m_baManager->GetRetransmitQueue ()))
386  {
387  // the packet can only have been peeked from the block ack manager retransmit
388  // queue if:
389  // - the peeked packet is a QoS Data frame AND
390  // - the peeked packet is not a broadcast frame AND
391  // - an agreement has been established
392  NS_ASSERT (peekedItem->GetHeader ().IsQosData () && !recipient.IsBroadcast ());
393  uint8_t tid = peekedItem->GetHeader ().GetQosTid ();
394  NS_ASSERT (GetBaAgreementEstablished (recipient, tid));
395  // we should not be asked to dequeue an old packet
397  peekedItem->GetHeader ().GetSequenceNumber ()));
398  // we should not be asked to dequeue an MPDU that is beyond the transmit window
399  NS_ASSERT (IsInWindow (peekedItem->GetHeader ().GetSequenceNumber (),
400  GetBaStartingSequence (recipient, tid),
401  GetBaBufferSize (recipient, tid)));
402  // A-MSDU aggregation cannot be done on a retransmitted MPDU, hence return
403  // the peeked MPDU
404  NS_LOG_DEBUG ("Got MPDU from BA manager queue: " << *peekedItem);
405 
406  queueIt = peekedIt;
407  queueIt.it++;
408 
409  return *peekedIt.it;
410  }
411 
412  // The MPDU has been peeked from the EDCA queue.
413  NS_ASSERT (peekedIt.queue == PeekPointer (m_queue));
415 
416  // If it is a non-broadcast QoS Data frame and it is not a retransmission nor a fragment,
417  // attempt A-MSDU aggregation
418  if (peekedItem->GetHeader ().IsQosData ())
419  {
420  uint8_t tid = peekedItem->GetHeader ().GetQosTid ();
421 
422  // we should not be asked to dequeue an MPDU that is beyond the transmit window.
423  // Note that PeekNextMpdu() temporarily assigns the next available sequence number
424  // to the peeked frame
425  NS_ASSERT (!GetBaAgreementEstablished (recipient, tid)
426  || IsInWindow (peekedItem->GetHeader ().GetSequenceNumber (),
427  GetBaStartingSequence (recipient, tid),
428  GetBaBufferSize (recipient, tid)));
429 
430  // try A-MSDU aggregation
431  if (m_stationManager->GetHtSupported () && !recipient.IsBroadcast ()
432  && !peekedItem->GetHeader ().IsRetry () && !peekedItem->IsFragment ())
433  {
434  Ptr<HtFrameExchangeManager> htFem = StaticCast<HtFrameExchangeManager> (m_qosFem);
435  mpdu = htFem->GetMsduAggregator ()->GetNextAmsdu (peekedItem, txParams, availableTime, peekedIt);
436  }
437 
438  if (mpdu != 0)
439  {
440  NS_LOG_DEBUG ("Prepared an MPDU containing an A-MSDU");
441  }
442  // else aggregation was not attempted or failed
443  }
444 
445  if (mpdu == 0)
446  {
447  mpdu = *peekedIt.it;
448  peekedIt.it++;
449  }
450 
451  // Assign a sequence number if this is not a fragment nor a retransmission
452  AssignSequenceNumber (mpdu);
453  NS_LOG_DEBUG ("Got MPDU from EDCA queue: " << *mpdu);
454  queueIt = peekedIt;
455 
456  return mpdu;
457 }
458 
459 void
461 {
462  NS_LOG_FUNCTION (this << *mpdu);
463 
464  if (!mpdu->IsFragment () && !mpdu->GetHeader ().IsRetry ())
465  {
466  uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&mpdu->GetHeader ());
467  mpdu->GetHeader ().SetSequenceNumber (sequence);
468  }
469 }
470 
472 QosTxop::GetBlockAckReqType (Mac48Address recipient, uint8_t tid) const
473 {
474  return m_baManager->GetBlockAckReqType (recipient, tid);
475 }
476 
478 QosTxop::GetBlockAckType (Mac48Address recipient, uint8_t tid) const
479 {
480  return m_baManager->GetBlockAckType (recipient, tid);
481 }
482 
483 void
485 {
486  NS_LOG_FUNCTION (this);
487 
488  // For internal collisions occurring with the EDCA access method, the appropriate
489  // retry counters (short retry counter for MSDU, A-MSDU, or MMPDU and QSRC[AC] or
490  // long retry counter for MSDU, A-MSDU, or MMPDU and QLRC[AC]) are incremented
491  // (Sec. 10.22.2.11.1 of 802.11-2016).
492  // We do not prepare the PSDU that the AC losing the internal collision would have
493  // sent. As an approximation, we consider the frame peeked from the queues of the AC.
495 
496  if (mpdu != nullptr)
497  {
499 
500  if (!mpdu->GetHeader ().GetAddr1 ().IsGroup () && !m_stationManager->NeedRetransmission (mpdu))
501  {
502  NS_LOG_DEBUG ("reset DCF");
505  {
507  }
508  ResetCw ();
509  // We have to discard mpdu, but first we have to determine whether mpdu
510  // is stored in the Block Ack Manager retransmit queue or in the AC queue
511  Mac48Address receiver = mpdu->GetHeader ().GetAddr1 ();
512  WifiMacQueue::ConstIterator testIt;
513  bool found = false;
514 
515  if (mpdu->GetHeader ().IsQosData ()
516  && GetBaAgreementEstablished (receiver, mpdu->GetHeader ().GetQosTid ()))
517  {
518  uint8_t tid = mpdu->GetHeader ().GetQosTid ();
519  testIt = m_baManager->GetRetransmitQueue ()->PeekByTidAndAddress (tid, receiver);
520 
521  if (testIt != m_baManager->GetRetransmitQueue ()->end ())
522  {
523  found = true;
524  // if not null, the test packet must equal the peeked packet
525  NS_ASSERT ((*testIt)->GetPacket () == mpdu->GetPacket ());
526  m_baManager->GetRetransmitQueue ()->Remove (testIt);
527  m_baManager->NotifyDiscardedMpdu (mpdu);
528  }
529  }
530 
531  if (!found)
532  {
533  if (mpdu->GetHeader ().IsQosData ())
534  {
535  uint8_t tid = mpdu->GetHeader ().GetQosTid ();
536  testIt = m_queue->PeekByTidAndAddress (tid, receiver);
537  NS_ASSERT (testIt != m_queue->end () && (*testIt)->GetPacket () == mpdu->GetPacket ());
538  m_queue->Remove (testIt);
539  }
540  else
541  {
542  // the peeked packet is a non-QoS Data frame (e.g., a DELBA Request), hence
543  // it was not peeked by TID, hence it must be the head of the queue
545  item = m_queue->DequeueFirstAvailable (m_qosBlockedDestinations);
546  NS_ASSERT (item != 0 && item->GetPacket () == mpdu->GetPacket ());
547  }
548  }
549  }
550  else
551  {
552  NS_LOG_DEBUG ("Update CW");
553  UpdateFailedCw ();
554  }
555  }
556 
557  GenerateBackoff ();
559  if (HasFramesToTransmit ())
560  {
561  m_channelAccessManager->RequestAccess (this);
562  }
563 }
564 
565 void
567 {
568  NS_LOG_FUNCTION (this << txopDuration);
569 
570  NS_ASSERT (txopDuration != Time::Min ());
572  m_txopDuration = txopDuration;
574 }
575 
576 bool
578 {
579  NS_LOG_FUNCTION (this << !m_startTxop.IsZero ());
580  return (!m_startTxop.IsZero ());
581 }
582 
583 void
585 {
586  NS_LOG_FUNCTION (this);
587 
589  {
590  NS_LOG_DEBUG ("Terminating TXOP. Duration = " << Simulator::Now () - m_startTxop);
592  }
593  m_startTxop = Seconds (0);
595 }
596 
597 Time
599 {
601  Time remainingTxop = m_txopDuration;
602  remainingTxop -= (Simulator::Now () - m_startTxop);
603  if (remainingTxop.IsStrictlyNegative ())
604  {
605  remainingTxop = Seconds (0);
606  }
607  NS_LOG_FUNCTION (this << remainingTxop);
608  return remainingTxop;
609 }
610 
611 void
613 {
614  NS_LOG_FUNCTION (this << +ac);
615  m_ac = ac;
616 }
617 
618 void
620 {
621  NS_LOG_FUNCTION (this << packet << &hdr);
622  WifiMacTrailer fcs;
623  m_queue->PushFront (Create<WifiMacQueueItem> (packet, hdr));
625  {
626  m_channelAccessManager->RequestAccess (this);
627  }
628 }
629 
630 void
632 {
633  NS_LOG_FUNCTION (this << respHdr << recipient);
634  uint8_t tid = respHdr->GetTid ();
635  if (respHdr->GetStatusCode ().IsSuccess ())
636  {
637  NS_LOG_DEBUG ("block ack agreement established with " << recipient << " tid " << +tid);
638  // A (destination, TID) pair is "blocked" (i.e., no more packets are sent)
639  // when an Add BA Request is sent to the destination. However, when the
640  // Add BA Request timer expires, the (destination, TID) pair is "unblocked"
641  // and packets to the destination are sent again (under normal ack policy).
642  // Thus, there may be a packet needing to be retransmitted when the
643  // Add BA Response is received. In this case, the starting sequence number
644  // shall be set equal to the sequence number of such packet.
645  uint16_t startingSeq = m_txMiddle->GetNextSeqNumberByTidAndAddress (tid, recipient);
646  WifiMacQueue::ConstIterator peekedIt = m_queue->PeekByTidAndAddress (tid, recipient);
647  if (peekedIt != m_queue->end () && (*peekedIt)->GetHeader ().IsRetry ())
648  {
649  startingSeq = (*peekedIt)->GetHeader ().GetSequenceNumber ();
650  }
651  m_baManager->UpdateAgreement (respHdr, recipient, startingSeq);
652  }
653  else
654  {
655  NS_LOG_DEBUG ("discard ADDBA response" << recipient);
656  m_baManager->NotifyAgreementRejected (recipient, tid);
657  }
658 
660  {
661  m_channelAccessManager->RequestAccess (this);
662  }
663 }
664 
665 void
667 {
668  NS_LOG_FUNCTION (this << delBaHdr << recipient);
669  NS_LOG_DEBUG ("received DELBA frame from=" << recipient);
670  m_baManager->DestroyAgreement (recipient, delBaHdr->GetTid ());
671 }
672 
673 void
675 {
676  NS_ASSERT (mpdu->GetHeader ().IsQosData ());
677  // If there is an established BA agreement, store the packet in the queue of outstanding packets
678  if (GetBaAgreementEstablished (mpdu->GetHeader ().GetAddr1 (), mpdu->GetHeader ().GetQosTid ()))
679  {
680  m_baManager->StorePacket (mpdu);
681  }
682 }
683 
684 void
685 QosTxop::SetBlockAckThreshold (uint8_t threshold)
686 {
687  NS_LOG_FUNCTION (this << +threshold);
688  m_blockAckThreshold = threshold;
689  m_baManager->SetBlockAckThreshold (threshold);
690 }
691 
692 void
694 {
695  NS_LOG_FUNCTION (this << timeout);
697 }
698 
699 uint8_t
701 {
702  NS_LOG_FUNCTION (this);
703  return m_blockAckThreshold;
704 }
705 
706 uint16_t
708 {
710 }
711 
712 void
714 {
715  NS_LOG_FUNCTION (this);
716  ResetCw ();
717  GenerateBackoff ();
718 }
719 
720 void
722 {
723  NS_LOG_FUNCTION (this << recipient << +tid);
724  // If agreement is still pending, ADDBA response is not received
725  if (m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::PENDING))
726  {
727  m_baManager->NotifyAgreementNoReply (recipient, tid);
729  GenerateBackoff ();
731  {
732  m_channelAccessManager->RequestAccess (this);
733  }
734  }
735 }
736 
737 void
738 QosTxop::ResetBa (Mac48Address recipient, uint8_t tid)
739 {
740  NS_LOG_FUNCTION (this << recipient << +tid);
741  // This function is scheduled when waiting for an ADDBA response. However,
742  // before this function is called, a DELBA request may arrive, which causes
743  // the agreement to be deleted. Hence, check if an agreement exists before
744  // notifying that the agreement has to be reset.
745  if (m_baManager->ExistsAgreement (recipient, tid)
746  && !m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED))
747  {
748  m_baManager->NotifyAgreementReset (recipient, tid);
749  }
750 }
751 
752 void
754 {
755  NS_LOG_FUNCTION (this << addBaResponseTimeout);
756  m_addBaResponseTimeout = addBaResponseTimeout;
757 }
758 
759 Time
761 {
762  return m_addBaResponseTimeout;
763 }
764 
765 void
767 {
768  NS_LOG_FUNCTION (this << failedAddBaTimeout);
769  m_failedAddBaTimeout = failedAddBaTimeout;
770 }
771 
772 Time
774 {
775  return m_failedAddBaTimeout;
776 }
777 
778 bool
779 QosTxop::IsQosTxop (void) const
780 {
781  return true;
782 }
783 
784 AcIndex
786 {
787  return m_ac;
788 }
789 
790 } //namespace ns3
AcIndex m_ac
the access category
Definition: qos-txop.h:410
void ScheduleBar(Ptr< const WifiMacQueueItem > bar, bool skipIfNoDataQueued=false)
Definition: qos-txop.cc:201
bool IsRetry(void) const
Return if the Retry bit is set.
bool IsSuccess(void) const
Return whether the status code is success.
Definition: status-code.cc:42
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
Ptr< const WifiMacQueueItem > PeekNextMpdu(uint8_t tid=8, Mac48Address recipient=Mac48Address::GetBroadcast())
Peek the next frame to transmit to the given receiver and of the given TID from the block ack manager...
Definition: qos-txop.cc:277
bool IsBroadcast(void) const
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
Ptr< WifiMac > GetMac(void) const
Return the WifiMac.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Ptr< MacTxMiddle > m_txMiddle
the MacTxMiddle
Definition: txop.h:334
void ResetBa(Mac48Address recipient, uint8_t tid)
Reset BA agreement after BA negotiation failed.
Definition: qos-txop.cc:738
AttributeValue implementation for Boolean.
Definition: boolean.h:36
void SetWifiRemoteStationManager(const Ptr< WifiRemoteStationManager > remoteManager) override
Set WifiRemoteStationsManager this Txop is associated to.
Definition: qos-txop.cc:207
void DoDispose(void) override
Destructor implementation.
Definition: qos-txop.cc:112
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
static Time Min()
Minimum representable Time Not to be confused with Min(Time,Time).
Definition: nstime.h:274
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:70
#define min(a, b)
Definition: 80211b.c:42
Time m_startTxop
the start TXOP time
Definition: qos-txop.h:419
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:85
Handle packet fragmentation and retransmissions for QoS data frames as well as MSDU aggregation (A-MS...
Definition: qos-txop.h:74
void SetNoMoreFragments(void)
Un-set the More Fragment bit in the Frame Control Field.
Ptr< ChannelAccessManager > m_channelAccessManager
the channel access manager
Definition: txop.h:331
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
void ReportFinalDataFailed(Ptr< const WifiMacQueueItem > mpdu)
Should be invoked after calling ReportDataFailed if NeedRetransmission returns false.
#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
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:411
Information needed to remove an MSDU from the queue.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ConstIterator it
iterator pointing to the MSDU in the queue
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
Ptr< BlockAckManager > GetBaManager(void)
Get the Block Ack Manager associated with this QosTxop.
Definition: qos-txop.cc:155
void ReportDataFailed(Ptr< const WifiMacQueueItem > mpdu)
Should be invoked whenever the AckTimeout associated to a transmission attempt expires.
void SetBlockAckInactivityTimeout(uint16_t timeout)
Set the BlockAck inactivity timeout.
Definition: qos-txop.cc:693
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
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
Definition: nstime.h:333
uint16_t GetBaStartingSequence(Mac48Address address, uint8_t tid) const
Definition: qos-txop.cc:173
void GotDelBaFrame(const MgtDelBaHeader *delBaHdr, Mac48Address recipient)
Event handler when a DELBA frame is received.
Definition: qos-txop.cc:666
virtual ~QosTxop()
Definition: qos-txop.cc:106
void SetQosQueueSize(uint8_t size)
Set the Queue Size subfield in the QoS control field.
ns3::Time timeout
virtual Time GetRemainingTxop(void) const
Return the remaining duration in the current TXOP.
Definition: qos-txop.cc:598
virtual void GenerateBackoff(void)
Generate a new backoff now.
Definition: txop.cc:370
void SetAccessCategory(AcIndex ac)
Set the access category of this EDCAF.
Definition: qos-txop.cc:612
The different BlockAckRequest variants.
static TypeId GetTypeId(void)
Get the type ID.
Definition: qos-txop.cc:54
uint8_t GetBlockAckThreshold(void) const
Return the current threshold for block ack mechanism.
Definition: qos-txop.cc:700
bool UseExplicitBarAfterMissedBlockAck(void) const
Return true if an explicit BlockAckRequest is sent after a missed BlockAck.
Definition: qos-txop.cc:215
Time m_failedAddBaTimeout
timeout after failed BA agreement
Definition: qos-txop.h:422
bool NeedRetransmission(Ptr< const WifiMacQueueItem > mpdu)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
ConstIterator PeekByTidAndAddress(uint8_t tid, Mac48Address dest, ConstIterator pos=EMPTY) const
Search and return, if present in the queue, the first packet having the receiver address equal to des...
uint8_t GetTid(void) const
Return the Traffic ID (TID).
bool IsQosTxop(void) const override
Check for QoS TXOP.
Definition: qos-txop.cc:779
void AssignSequenceNumber(Ptr< WifiMacQueueItem > mpdu) const
Assign a sequence number to the given MPDU, if it is not a fragment and it is not a retransmitted fra...
Definition: qos-txop.cc:460
void UpdateFailedCw(void)
Update the value of the CW variable to take into account a transmission failure.
Definition: txop.cc:195
Time GetAddBaResponseTimeout(void) const
Get the timeout for ADDBA response.
Definition: qos-txop.cc:760
Ptr< QosFrameExchangeManager > m_qosFem
the QoS Frame Exchange Manager
Definition: qos-txop.h:411
const WifiMacHeader & GetHeader(void) const
Get the header stored in this item.
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: pointer.h:227
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
bool IsZero(void) const
Exactly equivalent to t == 0.
Definition: nstime.h:301
AttributeValue implementation for Time.
Definition: nstime.h:1353
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
uint16_t GetBlockAckInactivityTimeout(void) const
Get the BlockAck inactivity timeout.
Definition: qos-txop.cc:707
void SetQosFrameExchangeManager(const Ptr< QosFrameExchangeManager > qosFem)
Set the Frame Exchange Manager associated with this QoS STA.
Definition: qos-txop.cc:138
void SetFailedAddBaTimeout(Time failedAddBaTimeout)
Set the timeout for failed BA agreement.
Definition: qos-txop.cc:766
bool GetHtSupported(void) const
Return whether the device has HT capability support enabled.
Ptr< BlockAckManager > m_baManager
the block ack manager
Definition: qos-txop.h:413
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
Definition: qos-utils.cc:126
uint8_t GetQosTid(void) const
Return the Traffic ID of a QoS header.
virtual void NotifyChannelReleased(void)
Called by the FrameExchangeManager to notify the completion of the transmissions. ...
Definition: txop.cc:349
void DoInitialize(void) override
Initialize() implementation.
Definition: qos-txop.cc:713
ChannelAccessStatus m_access
channel access status
Definition: txop.h:342
void GotAddBaResponse(const MgtAddBaResponseHeader *respHdr, Mac48Address recipient)
Event handler when an ADDBA response is received.
Definition: qos-txop.cc:631
static const ConstIterator EMPTY
Invalid iterator to signal an empty queue.
uint16_t GetNextSequenceNumberFor(const WifiMacHeader *hdr)
Return the next sequence number for the given header.
Definition: qos-txop.cc:239
void PushFront(Ptr< const Packet > packet, const WifiMacHeader &hdr)
Definition: qos-txop.cc:619
uint16_t PeekNextSequenceNumberFor(const WifiMacHeader *hdr)
Return the next sequence number for the Traffic ID and destination, but do not pick it (i...
Definition: qos-txop.cc:245
void SetAddBaResponseTimeout(Time addBaResponseTimeout)
Set the timeout to wait for ADDBA response.
Definition: qos-txop.cc:753
Ptr< const Packet > GetPacket(void) const
Get the packet stored in this item.
bool IsFragment(void) const
Return true if this item contains an MSDU fragment, false otherwise.
void SetNoRetry(void)
Un-set the Retry bit in the Frame Control field.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Time m_txopDuration
the duration of a TXOP
Definition: qos-txop.h:420
BlockAckType GetBlockAckType(Mac48Address recipient, uint8_t tid) const
Definition: qos-txop.cc:478
Hold objects of type Ptr<T>.
Definition: pointer.h:36
address
Definition: first.py:44
StatusCode GetStatusCode(void) const
Return the status code.
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
void CompleteMpduTx(Ptr< WifiMacQueueItem > mpdu)
Stores an MPDU (part of an A-MPDU) in block ack agreement (i.e.
Definition: qos-txop.cc:674
Ptr< WifiMacQueue > m_queue
the wifi MAC queue
Definition: txop.h:333
void NotifyChannelAccessed(Time txopDuration) override
Called by the FrameExchangeManager to notify that channel access has been granted for the given amoun...
Definition: qos-txop.cc:566
bool IsInWindow(uint16_t seq, uint16_t winstart, uint16_t winsize)
Definition: wifi-utils.cc:225
an EUI-48 address
Definition: mac48-address.h:43
void DoDispose(void) override
Destructor implementation.
Definition: txop.cc:107
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:1354
void SetDroppedMpduCallback(DroppedMpdu callback) override
Definition: qos-txop.cc:145
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
DroppedMpdu m_droppedMpduCallback
the dropped MPDU callback
Definition: txop.h:332
void SetBlockAckThreshold(uint8_t threshold)
Set threshold for block ack mechanism.
Definition: qos-txop.cc:685
uint8_t m_blockAckThreshold
the block ack threshold (use BA mechanism if number of packets in queue reaches this value...
Definition: qos-txop.h:414
AcIndex GetAccessCategory(void) const override
Get the access category.
Definition: qos-txop.cc:785
virtual void NotifyChannelAccessed(Time txopDuration=Seconds(0))
Called by the FrameExchangeManager to notify that channel access has been granted for the given amoun...
Definition: txop.cc:342
uint32_t GetSize(Mac48Address receiver) const
Get the size in bytes of the (A-)MPDU addressed to the given receiver.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
virtual void SetDroppedMpduCallback(DroppedMpdu callback)
Definition: txop.cc:139
BlockAckReqType GetBlockAckReqType(Mac48Address recipient, uint8_t tid) const
Definition: qos-txop.cc:472
bool IsQosOldPacket(Ptr< const WifiMacQueueItem > mpdu)
Check if the given MPDU is to be considered old according to the current starting sequence number of ...
Definition: qos-txop.cc:251
bool HasFramesToTransmit(void) override
Check if the Txop has frames to transmit.
Definition: qos-txop.cc:221
WifiMacQueue * queue
pointer to the queue where the MSDU is enqueued
void SetQosQueueSize(Ptr< WifiMacQueueItem > mpdu)
Set the Queue Size subfield of the QoS Control field of the given QoS data frame. ...
Definition: qos-txop.cc:122
The different BlockAck variants.
void SetSequenceNumber(uint16_t seq)
Set the sequence number of the header.
void NotifyChannelReleased(void) override
Called by the FrameExchangeManager to notify the completion of the transmissions. ...
Definition: qos-txop.cc:584
void Unblock(Mac48Address dest, uint8_t tid)
Un-block the given destination address and TID (e.g.
Implement the header for management frames of type Add Block Ack response.
Definition: mgt-headers.h:1122
Implement the header for management frames of type Delete Block Ack.
Definition: mgt-headers.h:1243
bool GetBaAgreementEstablished(Mac48Address address, uint8_t tid) const
Definition: qos-txop.cc:161
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
bool m_useExplicitBarAfterMissedBlockAck
flag whether explicit BlockAckRequest should be sent upon missed BlockAck Response ...
Definition: qos-txop.h:423
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Ptr< const WifiMacQueueItem > PrepareBlockAckRequest(Mac48Address recipient, uint8_t tid) const
Definition: qos-txop.cc:179
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism...
Ptr< QosBlockedDestinations > m_qosBlockedDestinations
the QoS blocked destinations
Definition: qos-txop.h:412
uint16_t GetBaBufferSize(Mac48Address address, uint8_t tid) const
Definition: qos-txop.cc:167
void Block(Mac48Address dest, uint8_t tid)
Block the given destination address and TID from sending (e.g.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
virtual void SetWifiRemoteStationManager(const Ptr< WifiRemoteStationManager > remoteManager)
Set WifiRemoteStationsManager this Txop is associated to.
Definition: txop.cc:132
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data...
TracedCallback< Time, Time > m_txopTrace
TXOP trace callback.
Definition: qos-txop.h:425
ConstIterator PeekFirstAvailable(const Ptr< QosBlockedDestinations > blockedPackets=nullptr, ConstIterator pos=EMPTY) const
Return first available packet for transmission.
uint8_t GetTid(void) const
Return the Traffic ID (TID).
Ptr< WifiMacQueueItem > GetNextMpdu(Ptr< const WifiMacQueueItem > peekedItem, WifiTxParameters &txParams, Time availableTime, bool initialFrame, WifiMacQueueItem::QueueIteratorPair &queueIt)
Prepare the frame to transmit starting from the MPDU that has been previously peeked by calling PeekN...
Definition: qos-txop.cc:359
Time GetFailedAddBaTimeout(void) const
Get the timeout for failed BA agreement.
Definition: qos-txop.cc:773
uint16_t m_blockAckInactivityTimeout
the BlockAck inactivity timeout value (in TUs, i.e.
Definition: qos-txop.h:418
Headers for BlockAckRequest.
Definition: ctrl-headers.h:48
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
Ptr< WifiRemoteStationManager > m_stationManager
the wifi remote station manager
Definition: txop.h:335
void ResetCw(void)
Update the value of the CW variable to take into account a transmission success or a transmission abo...
Definition: txop.cc:187
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
void AddBaResponseTimeout(Mac48Address recipient, uint8_t tid)
Callback when ADDBA response is not received after timeout.
Definition: qos-txop.cc:721
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
Implements the IEEE 802.11 MAC header.
Time m_addBaResponseTimeout
timeout for ADDBA response
Definition: qos-txop.h:421
Implements the IEEE 802.11 MAC trailer.
virtual bool IsTxopStarted(void) const
Return true if a TXOP has started.
Definition: qos-txop.cc:577
void NotifyInternalCollision(void) override
Notify the Txop that internal collision has occurred.
Definition: qos-txop.cc:484
void SetDsNotFrom(void)
Un-set the From DS bit in the Frame Control field.
Handle packet fragmentation and retransmissions for data and management frames.
Definition: txop.h:65