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"
35 #include "msdu-aggregator.h"
36 #include "mpdu-aggregator.h"
37 #include "ctrl-headers.h"
38 #include "wifi-phy.h"
39 #include "wifi-psdu.h"
40 #include "ns3/ht-frame-exchange-manager.h"
41 #include "wifi-tx-parameters.h"
42 
43 #undef NS_LOG_APPEND_CONTEXT
44 #define NS_LOG_APPEND_CONTEXT if (m_mac != 0) { std::clog << "[mac=" << m_mac->GetAddress () << "] "; }
45 
46 namespace ns3 {
47 
48 NS_LOG_COMPONENT_DEFINE ("QosTxop");
49 
51 
52 TypeId
54 {
55  static TypeId tid = TypeId ("ns3::QosTxop")
56  .SetParent<ns3::Txop> ()
57  .SetGroupName ("Wifi")
58  .AddConstructor<QosTxop> ()
59  .AddAttribute ("UseExplicitBarAfterMissedBlockAck",
60  "Specify whether explicit BlockAckRequest should be sent upon missed BlockAck Response.",
61  BooleanValue (true),
64  .AddAttribute ("AddBaResponseTimeout",
65  "The timeout to wait for ADDBA response after the Ack to "
66  "ADDBA request is received.",
67  TimeValue (MilliSeconds (1)),
70  MakeTimeChecker ())
71  .AddAttribute ("FailedAddBaTimeout",
72  "The timeout after a failed BA agreement. During this "
73  "timeout, the originator resumes sending packets using normal "
74  "MPDU. After that, BA agreement is reset and the originator "
75  "will retry BA negotiation.",
76  TimeValue (MilliSeconds (200)),
79  MakeTimeChecker ())
80  .AddAttribute ("BlockAckManager",
81  "The BlockAckManager object.",
82  PointerValue (),
84  MakePointerChecker<BlockAckManager> ())
85  .AddTraceSource ("TxopTrace",
86  "Trace source for TXOP start and duration times",
88  "ns3::TracedValueCallback::Time")
89  ;
90  return tid;
91 }
92 
94  : Txop (CreateObject<WifiMacQueue> (ac)),
95  m_ac (ac),
96  m_startTxop (Seconds (0)),
97  m_txopDuration (Seconds (0)),
98  m_muCwMin (0),
99  m_muCwMax (0),
100  m_muAifsn (0),
101  m_muEdcaTimer (Seconds (0)),
102  m_muEdcaTimerStartTime (Seconds (0))
103 {
104  NS_LOG_FUNCTION (this);
105  m_qosBlockedDestinations = Create<QosBlockedDestinations> ();
106  m_baManager = CreateObject<BlockAckManager> ();
107  m_baManager->SetQueue (m_queue);
110  m_queue->TraceConnectWithoutContext ("Expired", MakeCallback (&BlockAckManager::NotifyDiscardedMpdu, m_baManager));
111 }
112 
114 {
115  NS_LOG_FUNCTION (this);
116 }
117 
118 void
120 {
121  NS_LOG_FUNCTION (this);
122  if (m_baManager != 0)
123  {
124  m_baManager->Dispose ();
125  }
126  m_baManager = 0;
128  m_qosFem = 0;
129  Txop::DoDispose ();
130 }
131 
132 uint8_t
133 QosTxop::GetQosQueueSize (uint8_t tid, Mac48Address receiver) const
134 {
135  uint32_t bufferSize = m_queue->GetNBytes (tid, receiver);
136  // A queue size value of 254 is used for all sizes greater than 64 768 octets.
137  uint8_t queueSize = static_cast<uint8_t> (std::ceil (std::min (bufferSize, 64769u) / 256.0));
138  NS_LOG_DEBUG ("Buffer size=" << bufferSize << " Queue Size=" << +queueSize);
139  return queueSize;
140 }
141 
142 void
144 {
145  NS_LOG_FUNCTION (this << qosFem);
146  m_qosFem = qosFem;
147 }
148 
149 void
151 {
152  NS_LOG_FUNCTION (this << &callback);
153  Txop::SetDroppedMpduCallback (callback);
154  m_baManager->SetDroppedOldMpduCallback (callback.Bind (WIFI_MAC_DROP_QOS_OLD_PACKET));
155 }
156 
157 void
158 QosTxop::SetMuCwMin (uint16_t cwMin)
159 {
160  NS_LOG_FUNCTION (this << cwMin);
161  m_muCwMin = cwMin;
162 }
163 
164 void
165 QosTxop::SetMuCwMax (uint16_t cwMax)
166 {
167  NS_LOG_FUNCTION (this << cwMax);
168  m_muCwMax = cwMax;
169 }
170 
171 void
172 QosTxop::SetMuAifsn (uint8_t aifsn)
173 {
174  NS_LOG_FUNCTION (this << +aifsn);
175  m_muAifsn = aifsn;
176 }
177 
178 void
180 {
181  NS_LOG_FUNCTION (this << timer);
182  m_muEdcaTimer = timer;
183 }
184 
185 void
187 {
188  NS_LOG_FUNCTION (this);
190  if (EdcaDisabled ())
191  {
192  NS_LOG_DEBUG ("Disable EDCA for " << m_muEdcaTimer.As (Time::MS));
193  m_channelAccessManager->DisableEdcaFor (this, m_muEdcaTimer);
194  }
195 }
196 
197 bool
199 {
202 }
203 
204 bool
206 {
207  return (MuEdcaTimerRunning () && m_muAifsn == 0);
208 }
209 
210 uint32_t
211 QosTxop::GetMinCw (void) const
212 {
213  if (!MuEdcaTimerRunning ())
214  {
215  return m_cwMin;
216  }
217  NS_ASSERT (!EdcaDisabled ());
218  return m_muCwMin;
219 }
220 
221 uint32_t
222 QosTxop::GetMaxCw (void) const
223 {
224  if (!MuEdcaTimerRunning ())
225  {
226  return m_cwMax;
227  }
228  NS_ASSERT (!EdcaDisabled ());
229  return m_muCwMax;
230 }
231 
232 uint8_t
233 QosTxop::GetAifsn (void) const
234 {
235  if (!MuEdcaTimerRunning ())
236  {
237  return m_aifsn;
238  }
239  return m_muAifsn;
240 }
241 
244 {
245  return m_baManager;
246 }
247 
248 bool
250 {
251  return m_baManager->ExistsAgreementInState (address, tid, OriginatorBlockAckAgreement::ESTABLISHED);
252 }
253 
254 uint16_t
256 {
257  return m_baManager->GetRecipientBufferSize (address, tid);
258 }
259 
260 uint16_t
262 {
263  return m_baManager->GetOriginatorStartingSequence (address, tid);
264 }
265 
267 QosTxop::PrepareBlockAckRequest (Mac48Address recipient, uint8_t tid) const
268 {
269  NS_LOG_FUNCTION (this << recipient << +tid);
270  NS_ASSERT (QosUtilsMapTidToAc (tid) == m_ac);
271 
272  CtrlBAckRequestHeader reqHdr = m_baManager->GetBlockAckReqHeader (recipient, tid);
273  Ptr<Packet> bar = Create<Packet> ();
274  bar->AddHeader (reqHdr);
275 
276  WifiMacHeader hdr;
278  hdr.SetAddr1 (recipient);
279  hdr.SetAddr2 (m_mac->GetAddress ());
280  hdr.SetDsNotTo ();
281  hdr.SetDsNotFrom ();
282  hdr.SetNoRetry ();
283  hdr.SetNoMoreFragments ();
284 
285  return Create<const WifiMacQueueItem> (bar, hdr);
286 }
287 
288 void
289 QosTxop::ScheduleBar (Ptr<const WifiMacQueueItem> bar, bool skipIfNoDataQueued)
290 {
291  m_baManager->ScheduleBar (bar, skipIfNoDataQueued);
292 }
293 
294 bool
296 {
298 }
299 
300 bool
302 {
303  // check if the BA manager has anything to send, so that expired
304  // frames (if any) are removed and a BlockAckRequest is scheduled to advance
305  // the starting sequence number of the transmit (and receiver) window
306  bool baManagerHasPackets = (m_baManager->GetBar (false) != 0);
307  // remove MSDUs with expired lifetime starting from the head of the queue
308  // TODO Add a WifiMacQueue method that serves this purpose; IsEmpty () can
309  // then reuse such method.
310  m_queue->IsEmpty ();
311  bool queueIsNotEmpty = (m_queue->PeekFirstAvailable (m_qosBlockedDestinations) != nullptr);
312 
313  bool ret = (baManagerHasPackets || queueIsNotEmpty);
314  NS_LOG_FUNCTION (this << baManagerHasPackets << queueIsNotEmpty);
315  return ret;
316 }
317 
318 uint16_t
320 {
321  return m_txMiddle->GetNextSequenceNumberFor (hdr);
322 }
323 
324 uint16_t
326 {
327  return m_txMiddle->PeekNextSequenceNumberFor (hdr);
328 }
329 
330 bool
332 {
333  NS_LOG_FUNCTION (this << *mpdu);
334 
335  if (!mpdu->GetHeader ().IsQosData ())
336  {
337  return false;
338  }
339 
340  Mac48Address recipient = mpdu->GetHeader ().GetAddr1 ();
341  uint8_t tid = mpdu->GetHeader ().GetQosTid ();
342 
343  if (!GetBaAgreementEstablished (recipient, tid))
344  {
345  return false;
346  }
347 
348  if (QosUtilsIsOldPacket (GetBaStartingSequence (recipient, tid),
349  mpdu->GetHeader ().GetSequenceNumber ()))
350  {
351  return true;
352  }
353  return false;
354 }
355 
358 {
359  NS_LOG_FUNCTION (this << +tid << recipient << item);
360 
361  // lambda to peek the next frame
362  auto peek = [this, &tid, &recipient, &item] () -> Ptr<const WifiMacQueueItem>
363  {
364  if (tid == 8 && recipient.IsBroadcast ()) // undefined TID and recipient
365  {
366  return m_queue->PeekFirstAvailable (m_qosBlockedDestinations, item);
367  }
368  if (m_qosBlockedDestinations->IsBlocked (recipient, tid))
369  {
370  return nullptr;
371  }
372  return m_queue->PeekByTidAndAddress (tid, recipient, item);
373  };
374 
375  item = peek ();
376  // remove old packets (must be retransmissions or in flight, otherwise they did
377  // not get a sequence number assigned)
378  while (item != nullptr && !item->IsFragment ())
379  {
380  if ((item->GetHeader ().IsRetry () || item->IsInFlight ())
381  && IsQosOldPacket (item))
382  {
383  NS_LOG_DEBUG ("Removing an old packet from EDCA queue: " << *item);
385  {
387  }
388  auto oldItem = item;
389  item = peek ();
390  m_queue->Remove (oldItem);
391  }
392  else if (item->IsInFlight ())
393  {
394  NS_LOG_DEBUG ("Skipping in flight MPDU: " << *item);
395  item = peek ();
396  }
397  else if (item->GetHeader ().HasData ()
398  && !m_mac->CanForwardPacketsTo (item->GetHeader ().GetAddr1 ()))
399  {
400  NS_LOG_DEBUG ("Skipping frame that cannot be forwarded: " << *item);
401  item = peek ();
402  }
403  else
404  {
405  break;
406  }
407  }
408  if (item != nullptr)
409  {
410  NS_ASSERT (!item->IsInFlight ());
411  WifiMacHeader& hdr = item->GetItem ()->GetHeader ();
412 
413  // peek the next sequence number and check if it is within the transmit window
414  // in case of QoS data frame
415  uint16_t sequence = (hdr.IsRetry () ? hdr.GetSequenceNumber ()
416  : m_txMiddle->PeekNextSequenceNumberFor (&hdr));
417  if (hdr.IsQosData ())
418  {
419  Mac48Address recipient = hdr.GetAddr1 ();
420  uint8_t tid = hdr.GetQosTid ();
421 
422  if (GetBaAgreementEstablished (recipient, tid)
423  && !IsInWindow (sequence, GetBaStartingSequence (recipient, tid), GetBaBufferSize (recipient, tid)))
424  {
425  NS_LOG_DEBUG ("Packet beyond the end of the current transmit window");
426  return nullptr;
427  }
428  }
429 
430  // Assign a sequence number if this is not a fragment nor a retransmission
431  if (!item->IsFragment () && !hdr.IsRetry ())
432  {
433  hdr.SetSequenceNumber (sequence);
434  }
435  NS_LOG_DEBUG ("Packet peeked from EDCA queue: " << *item);
436  return item;
437  }
438 
439  return nullptr;
440 }
441 
444  Time availableTime, bool initialFrame)
445 {
446  NS_ASSERT (peekedItem != 0);
447  NS_ASSERT (m_qosFem != 0);
448  NS_LOG_FUNCTION (this << *peekedItem << &txParams << availableTime << initialFrame);
449 
450  Mac48Address recipient = peekedItem->GetHeader ().GetAddr1 ();
451 
452  // The TXOP limit can be exceeded by the TXOP holder if it does not transmit more
453  // than one Data or Management frame in the TXOP and the frame is not in an A-MPDU
454  // consisting of more than one MPDU (Sec. 10.22.2.8 of 802.11-2016)
455  Time actualAvailableTime = (initialFrame && txParams.GetSize (recipient) == 0
456  ? Time::Min () : availableTime);
457 
458  if (!m_qosFem->TryAddMpdu (peekedItem, txParams, actualAvailableTime))
459  {
460  return nullptr;
461  }
462 
463  NS_ASSERT (peekedItem->IsQueued ());
465 
466  // If it is a non-broadcast QoS Data frame and it is not a retransmission nor a fragment,
467  // attempt A-MSDU aggregation
468  if (peekedItem->GetHeader ().IsQosData ())
469  {
470  uint8_t tid = peekedItem->GetHeader ().GetQosTid ();
471 
472  // we should not be asked to dequeue an MPDU that is beyond the transmit window.
473  // Note that PeekNextMpdu() temporarily assigns the next available sequence number
474  // to the peeked frame
475  NS_ASSERT (!GetBaAgreementEstablished (recipient, tid)
476  || IsInWindow (peekedItem->GetHeader ().GetSequenceNumber (),
477  GetBaStartingSequence (recipient, tid),
478  GetBaBufferSize (recipient, tid)));
479 
480  // try A-MSDU aggregation
481  if (m_mac->GetHtSupported () && !recipient.IsBroadcast ()
482  && !peekedItem->GetHeader ().IsRetry () && !peekedItem->IsFragment ()
483  && !peekedItem->IsInFlight ())
484  {
485  Ptr<HtFrameExchangeManager> htFem = StaticCast<HtFrameExchangeManager> (m_qosFem);
486  mpdu = htFem->GetMsduAggregator ()->GetNextAmsdu (peekedItem, txParams, availableTime);
487  }
488 
489  if (mpdu != 0)
490  {
491  NS_LOG_DEBUG ("Prepared an MPDU containing an A-MSDU");
492  }
493  // else aggregation was not attempted or failed
494  }
495 
496  if (mpdu == 0)
497  {
498  mpdu = peekedItem->GetItem ();
499  }
500 
501  // Assign a sequence number if this is not a fragment nor a retransmission
502  AssignSequenceNumber (mpdu);
503  NS_LOG_DEBUG ("Got MPDU from EDCA queue: " << *mpdu);
504 
505  return mpdu;
506 }
507 
508 void
510 {
511  NS_LOG_FUNCTION (this << *mpdu);
512 
513  if (!mpdu->IsFragment () && !mpdu->GetHeader ().IsRetry () && !mpdu->IsInFlight ())
514  {
515  uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&mpdu->GetHeader ());
516  mpdu->GetHeader ().SetSequenceNumber (sequence);
517  }
518 }
519 
521 QosTxop::GetBlockAckReqType (Mac48Address recipient, uint8_t tid) const
522 {
523  return m_baManager->GetBlockAckReqType (recipient, tid);
524 }
525 
527 QosTxop::GetBlockAckType (Mac48Address recipient, uint8_t tid) const
528 {
529  return m_baManager->GetBlockAckType (recipient, tid);
530 }
531 
532 void
534 {
535  NS_LOG_FUNCTION (this << txopDuration);
536 
537  NS_ASSERT (txopDuration != Time::Min ());
539  m_txopDuration = txopDuration;
541 }
542 
543 bool
545 {
546  NS_LOG_FUNCTION (this << !m_startTxop.IsZero ());
547  return (!m_startTxop.IsZero ());
548 }
549 
550 void
552 {
553  NS_LOG_FUNCTION (this);
554 
556  {
557  NS_LOG_DEBUG ("Terminating TXOP. Duration = " << Simulator::Now () - m_startTxop);
559  }
560  m_startTxop = Seconds (0);
562 }
563 
564 Time
566 {
568  Time remainingTxop = m_txopDuration;
569  remainingTxop -= (Simulator::Now () - m_startTxop);
570  if (remainingTxop.IsStrictlyNegative ())
571  {
572  remainingTxop = Seconds (0);
573  }
574  NS_LOG_FUNCTION (this << remainingTxop);
575  return remainingTxop;
576 }
577 
578 void
580 {
581  NS_LOG_FUNCTION (this << packet << &hdr);
582  WifiMacTrailer fcs;
583  m_queue->PushFront (Create<WifiMacQueueItem> (packet, hdr));
585  {
586  m_channelAccessManager->RequestAccess (this);
587  }
588 }
589 
590 void
592 {
593  NS_LOG_FUNCTION (this << respHdr << recipient);
594  uint8_t tid = respHdr->GetTid ();
595  if (respHdr->GetStatusCode ().IsSuccess ())
596  {
597  NS_LOG_DEBUG ("block ack agreement established with " << recipient << " tid " << +tid);
598  // A (destination, TID) pair is "blocked" (i.e., no more packets are sent)
599  // when an Add BA Request is sent to the destination. However, when the
600  // Add BA Request timer expires, the (destination, TID) pair is "unblocked"
601  // and packets to the destination are sent again (under normal ack policy).
602  // Thus, there may be a packet needing to be retransmitted when the
603  // Add BA Response is received. In this case, the starting sequence number
604  // shall be set equal to the sequence number of such packet.
605  uint16_t startingSeq = m_txMiddle->GetNextSeqNumberByTidAndAddress (tid, recipient);
606  auto peekedItem = m_queue->PeekByTidAndAddress (tid, recipient);
607  if (peekedItem != nullptr && peekedItem->GetHeader ().IsRetry ())
608  {
609  startingSeq = peekedItem->GetHeader ().GetSequenceNumber ();
610  }
611  m_baManager->UpdateAgreement (respHdr, recipient, startingSeq);
612  }
613  else
614  {
615  NS_LOG_DEBUG ("discard ADDBA response" << recipient);
616  m_baManager->NotifyAgreementRejected (recipient, tid);
617  }
618 
620  {
621  m_channelAccessManager->RequestAccess (this);
622  }
623 }
624 
625 void
627 {
628  NS_LOG_FUNCTION (this << delBaHdr << recipient);
629  NS_LOG_DEBUG ("received DELBA frame from=" << recipient);
630  m_baManager->DestroyAgreement (recipient, delBaHdr->GetTid ());
631 }
632 
633 void
635 {
636  NS_ASSERT (mpdu->GetHeader ().IsQosData ());
637  // If there is an established BA agreement, store the packet in the queue of outstanding packets
638  if (GetBaAgreementEstablished (mpdu->GetHeader ().GetAddr1 (), mpdu->GetHeader ().GetQosTid ()))
639  {
640  m_baManager->StorePacket (mpdu);
641  }
642 }
643 
644 void
645 QosTxop::SetBlockAckThreshold (uint8_t threshold)
646 {
647  NS_LOG_FUNCTION (this << +threshold);
648  m_blockAckThreshold = threshold;
649  m_baManager->SetBlockAckThreshold (threshold);
650 }
651 
652 void
654 {
655  NS_LOG_FUNCTION (this << timeout);
657 }
658 
659 uint8_t
661 {
662  NS_LOG_FUNCTION (this);
663  return m_blockAckThreshold;
664 }
665 
666 uint16_t
668 {
670 }
671 
672 void
674 {
675  NS_LOG_FUNCTION (this);
676  ResetCw ();
677  GenerateBackoff ();
678 }
679 
680 void
682 {
683  NS_LOG_FUNCTION (this << recipient << +tid);
684  // If agreement is still pending, ADDBA response is not received
685  if (m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::PENDING))
686  {
687  m_baManager->NotifyAgreementNoReply (recipient, tid);
689  GenerateBackoff ();
691  {
692  m_channelAccessManager->RequestAccess (this);
693  }
694  }
695 }
696 
697 void
698 QosTxop::ResetBa (Mac48Address recipient, uint8_t tid)
699 {
700  NS_LOG_FUNCTION (this << recipient << +tid);
701  // This function is scheduled when waiting for an ADDBA response. However,
702  // before this function is called, a DELBA request may arrive, which causes
703  // the agreement to be deleted. Hence, check if an agreement exists before
704  // notifying that the agreement has to be reset.
705  if (m_baManager->ExistsAgreement (recipient, tid)
706  && !m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED))
707  {
708  m_baManager->NotifyAgreementReset (recipient, tid);
709  }
710 }
711 
712 void
714 {
715  NS_LOG_FUNCTION (this << addBaResponseTimeout);
716  m_addBaResponseTimeout = addBaResponseTimeout;
717 }
718 
719 Time
721 {
722  return m_addBaResponseTimeout;
723 }
724 
725 void
727 {
728  NS_LOG_FUNCTION (this << failedAddBaTimeout);
729  m_failedAddBaTimeout = failedAddBaTimeout;
730 }
731 
732 Time
734 {
735  return m_failedAddBaTimeout;
736 }
737 
738 bool
739 QosTxop::IsQosTxop (void) const
740 {
741  return true;
742 }
743 
744 AcIndex
746 {
747  return m_ac;
748 }
749 
750 } //namespace ns3
#define min(a, b)
Definition: 80211b.c:42
void NotifyDiscardedMpdu(Ptr< const WifiMacQueueItem > mpdu)
AttributeValue implementation for Boolean.
Definition: boolean.h:37
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
Callback< R, T2, T3, T4, T5, T6, T7, T8, T9 > Bind(T a)
Bind the first arguments.
Definition: callback.h:1329
Headers for BlockAckRequest.
Definition: ctrl-headers.h:49
an EUI-48 address
Definition: mac48-address.h:44
bool IsBroadcast(void) const
Implement the header for management frames of type Add Block Ack response.
Definition: mgt-headers.h:1150
uint8_t GetTid(void) const
Return the Traffic ID (TID).
StatusCode GetStatusCode(void) const
Return the status code.
Implement the header for management frames of type Delete Block Ack.
Definition: mgt-headers.h:1271
uint8_t GetTid(void) const
Return the Traffic ID (TID).
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
void Unblock(Mac48Address dest, uint8_t tid)
Un-block the given destination address and TID (e.g.
void Block(Mac48Address dest, uint8_t tid)
Block the given destination address and TID from sending (e.g.
Handle packet fragmentation and retransmissions for QoS data frames as well as MSDU aggregation (A-MS...
Definition: qos-txop.h:72
Time m_muEdcaTimer
the MU EDCA Timer
Definition: qos-txop.h:479
QosTxop(AcIndex ac=AC_UNDEF)
Constructor.
Definition: qos-txop.cc:93
uint32_t m_muCwMax
the MU CW maximum
Definition: qos-txop.h:477
uint32_t m_muCwMin
the MU CW minimum
Definition: qos-txop.h:476
uint8_t m_blockAckThreshold
the block ack threshold (use BA mechanism if number of packets in queue reaches this value.
Definition: qos-txop.h:466
TracedCallback< Time, Time > m_txopTrace
TXOP trace callback.
Definition: qos-txop.h:482
virtual bool IsTxopStarted(void) const
Return true if a TXOP has started.
Definition: qos-txop.cc:544
void SetMuCwMax(uint16_t cwMax)
Set the maximum contention window size to use while the MU EDCA Timer is running.
Definition: qos-txop.cc:165
Time m_failedAddBaTimeout
timeout after failed BA agreement
Definition: qos-txop.h:473
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:325
void SetQosFrameExchangeManager(const Ptr< QosFrameExchangeManager > qosFem)
Set the Frame Exchange Manager associated with this QoS STA.
Definition: qos-txop.cc:143
bool IsQosTxop(void) const override
Check for QoS TXOP.
Definition: qos-txop.cc:739
void DoInitialize(void) override
Initialize() implementation.
Definition: qos-txop.cc:673
Time m_startTxop
the start TXOP time
Definition: qos-txop.h:470
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:533
void NotifyChannelReleased(void) override
Called by the FrameExchangeManager to notify the completion of the transmissions.
Definition: qos-txop.cc:551
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:509
void AddBaResponseTimeout(Mac48Address recipient, uint8_t tid)
Callback when ADDBA response is not received after timeout.
Definition: qos-txop.cc:681
void SetMuEdcaTimer(Time timer)
Set the MU EDCA Timer.
Definition: qos-txop.cc:179
uint16_t GetBaBufferSize(Mac48Address address, uint8_t tid) const
Definition: qos-txop.cc:255
uint8_t m_muAifsn
the MU AIFSN
Definition: qos-txop.h:478
Time m_txopDuration
the duration of a TXOP
Definition: qos-txop.h:471
void DoDispose(void) override
Destructor implementation.
Definition: qos-txop.cc:119
bool HasFramesToTransmit(void) override
Check if the Txop has frames to transmit.
Definition: qos-txop.cc:301
virtual Time GetRemainingTxop(void) const
Return the remaining duration in the current TXOP.
Definition: qos-txop.cc:565
virtual ~QosTxop()
Definition: qos-txop.cc:113
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:331
uint8_t GetBlockAckThreshold(void) const
Return the current threshold for block ack mechanism.
Definition: qos-txop.cc:660
uint16_t GetNextSequenceNumberFor(const WifiMacHeader *hdr)
Return the next sequence number for the given header.
Definition: qos-txop.cc:319
AcIndex m_ac
the access category
Definition: qos-txop.h:462
bool MuEdcaTimerRunning(void) const
Return true if the MU EDCA Timer is running, false otherwise.
Definition: qos-txop.cc:198
void SetDroppedMpduCallback(DroppedMpdu callback) override
Definition: qos-txop.cc:150
bool m_useExplicitBarAfterMissedBlockAck
flag whether explicit BlockAckRequest should be sent upon missed BlockAck Response
Definition: qos-txop.h:474
Time GetFailedAddBaTimeout(void) const
Get the timeout for failed BA agreement.
Definition: qos-txop.cc:733
void CompleteMpduTx(Ptr< WifiMacQueueItem > mpdu)
Stores an MPDU (part of an A-MPDU) in block ack agreement (i.e.
Definition: qos-txop.cc:634
Ptr< const WifiMacQueueItem > PrepareBlockAckRequest(Mac48Address recipient, uint8_t tid) const
Definition: qos-txop.cc:267
uint8_t GetQosQueueSize(uint8_t tid, Mac48Address receiver) const
Get the value for the Queue Size subfield of the QoS Control field of a QoS data frame of the given T...
Definition: qos-txop.cc:133
bool GetBaAgreementEstablished(Mac48Address address, uint8_t tid) const
Definition: qos-txop.cc:249
uint32_t GetMinCw(void) const override
Return the minimum contention window size from the EDCA Parameter Set or the MU EDCA Parameter Set,...
Definition: qos-txop.cc:211
void ResetBa(Mac48Address recipient, uint8_t tid)
Reset BA agreement after BA negotiation failed.
Definition: qos-txop.cc:698
void PushFront(Ptr< const Packet > packet, const WifiMacHeader &hdr)
Definition: qos-txop.cc:579
Time GetAddBaResponseTimeout(void) const
Get the timeout for ADDBA response.
Definition: qos-txop.cc:720
void StartMuEdcaTimerNow(void)
Start the MU EDCA Timer.
Definition: qos-txop.cc:186
BlockAckType GetBlockAckType(Mac48Address recipient, uint8_t tid) const
Definition: qos-txop.cc:527
uint8_t GetAifsn(void) const override
Return the number of slots that make up an AIFS according to the EDCA Parameter Set or the MU EDCA Pa...
Definition: qos-txop.cc:233
Ptr< WifiMacQueueItem > GetNextMpdu(Ptr< const WifiMacQueueItem > peekedItem, WifiTxParameters &txParams, Time availableTime, bool initialFrame)
Prepare the frame to transmit starting from the MPDU that has been previously peeked by calling PeekN...
Definition: qos-txop.cc:443
uint16_t GetBlockAckInactivityTimeout(void) const
Get the BlockAck inactivity timeout.
Definition: qos-txop.cc:667
Ptr< BlockAckManager > GetBaManager(void)
Get the Block Ack Manager associated with this QosTxop.
Definition: qos-txop.cc:243
bool UseExplicitBarAfterMissedBlockAck(void) const
Return true if an explicit BlockAckRequest is sent after a missed BlockAck.
Definition: qos-txop.cc:295
bool EdcaDisabled(void) const
Return true if the EDCA is disabled (the MU EDCA Timer is running and the MU AIFSN is zero),...
Definition: qos-txop.cc:205
void SetFailedAddBaTimeout(Time failedAddBaTimeout)
Set the timeout for failed BA agreement.
Definition: qos-txop.cc:726
uint16_t m_blockAckInactivityTimeout
the BlockAck inactivity timeout value (in TUs, i.e.
Definition: qos-txop.h:469
void SetMuAifsn(uint8_t aifsn)
Set the number of slots that make up an AIFS while the MU EDCA Timer is running.
Definition: qos-txop.cc:172
AcIndex GetAccessCategory(void) const
Get the access category of this object.
Definition: qos-txop.cc:745
uint32_t GetMaxCw(void) const override
Return the maximum contention window size from the EDCA Parameter Set or the MU EDCA Parameter Set,...
Definition: qos-txop.cc:222
void GotAddBaResponse(const MgtAddBaResponseHeader *respHdr, Mac48Address recipient)
Event handler when an ADDBA response is received.
Definition: qos-txop.cc:591
Time m_muEdcaTimerStartTime
last start time of the MU EDCA Timer
Definition: qos-txop.h:480
void SetBlockAckThreshold(uint8_t threshold)
Set threshold for block ack mechanism.
Definition: qos-txop.cc:645
void GotDelBaFrame(const MgtDelBaHeader *delBaHdr, Mac48Address recipient)
Event handler when a DELBA frame is received.
Definition: qos-txop.cc:626
void SetBlockAckInactivityTimeout(uint16_t timeout)
Set the BlockAck inactivity timeout.
Definition: qos-txop.cc:653
BlockAckReqType GetBlockAckReqType(Mac48Address recipient, uint8_t tid) const
Definition: qos-txop.cc:521
void SetAddBaResponseTimeout(Time addBaResponseTimeout)
Set the timeout to wait for ADDBA response.
Definition: qos-txop.cc:713
static TypeId GetTypeId(void)
Get the type ID.
Definition: qos-txop.cc:53
Ptr< QosFrameExchangeManager > m_qosFem
the QoS Frame Exchange Manager
Definition: qos-txop.h:463
uint16_t GetBaStartingSequence(Mac48Address address, uint8_t tid) const
Definition: qos-txop.cc:261
void SetMuCwMin(uint16_t cwMin)
Set the minimum contention window size to use while the MU EDCA Timer is running.
Definition: qos-txop.cc:158
Ptr< const WifiMacQueueItem > PeekNextMpdu(uint8_t tid=8, Mac48Address recipient=Mac48Address::GetBroadcast(), Ptr< const WifiMacQueueItem > item=nullptr)
Peek the next frame to transmit to the given receiver and of the given TID from the EDCA queue.
Definition: qos-txop.cc:357
Ptr< QosBlockedDestinations > m_qosBlockedDestinations
the QoS blocked destinations
Definition: qos-txop.h:464
Time m_addBaResponseTimeout
timeout for ADDBA response
Definition: qos-txop.h:472
void ScheduleBar(Ptr< const WifiMacQueueItem > bar, bool skipIfNoDataQueued=false)
Definition: qos-txop.cc:289
Ptr< BlockAckManager > m_baManager
the block ack manager
Definition: qos-txop.h:465
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
bool IsSuccess(void) const
Return whether the status code is success.
Definition: status-code.cc:42
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
Definition: nstime.h:332
static Time Min()
Minimum representable Time Not to be confused with Min(Time,Time).
Definition: nstime.h:273
@ MS
millisecond
Definition: nstime.h:115
bool IsStrictlyNegative(void) const
Exactly equivalent to t < 0.
Definition: nstime.h:324
bool IsZero(void) const
Exactly equivalent to t == 0.
Definition: nstime.h:300
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:418
AttributeValue implementation for Time.
Definition: nstime.h:1308
Handle packet fragmentation and retransmissions for data and management frames.
Definition: txop.h:65
Ptr< WifiMac > m_mac
the wifi MAC
Definition: txop.h:325
Ptr< WifiMacQueue > m_queue
the wifi MAC queue
Definition: txop.h:323
virtual void NotifyChannelReleased(void)
Called by the FrameExchangeManager to notify the completion of the transmissions.
Definition: txop.cc:355
ChannelAccessStatus m_access
channel access status
Definition: txop.h:332
@ NOT_REQUESTED
Definition: txop.h:94
uint8_t m_aifsn
the AIFSN
Definition: txop.h:341
uint32_t m_cwMin
the minimum contention window
Definition: txop.h:328
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:348
DroppedMpdu m_droppedMpduCallback
the dropped MPDU callback
Definition: txop.h:322
Ptr< ChannelAccessManager > m_channelAccessManager
the channel access manager
Definition: txop.h:321
virtual void SetDroppedMpduCallback(DroppedMpdu callback)
Definition: txop.cc:143
void ResetCw(void)
Update the value of the CW variable to take into account a transmission success or a transmission abo...
Definition: txop.cc:191
Ptr< MacTxMiddle > m_txMiddle
the MacTxMiddle
Definition: txop.h:324
uint32_t m_cwMax
the maximum contention window
Definition: txop.h:329
virtual void GenerateBackoff(void)
Generate a new backoff now.
Definition: txop.cc:376
void DoDispose(void) override
Destructor implementation.
Definition: txop.cc:111
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Implements the IEEE 802.11 MAC header.
void SetDsNotFrom(void)
Un-set the From DS bit in the Frame Control field.
uint8_t GetQosTid(void) const
Return the Traffic ID of a QoS header.
void SetNoRetry(void)
Un-set the Retry bit in the Frame Control field.
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
void SetNoMoreFragments(void)
Un-set the More Fragment bit in the Frame Control Field.
uint16_t GetSequenceNumber(void) const
Return the sequence number of the header.
void SetSequenceNumber(uint16_t seq)
Set the sequence number of the header.
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
bool IsRetry(void) const
Return if the Retry bit is set.
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
This queue implements the timeout procedure described in (Section 9.19.2.6 "Retransmit procedures" pa...
Implements the IEEE 802.11 MAC trailer.
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism,...
uint32_t GetSize(Mac48Address receiver) const
Get the size in bytes of the (A-)MPDU addressed to the given receiver.
#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
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
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
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
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:1309
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:576
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
Definition: qos-utils.cc:126
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
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:71
address
Definition: first.py:44
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:522
@ WIFI_MAC_CTL_BACKREQ
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:1648
bool IsInWindow(uint16_t seq, uint16_t winstart, uint16_t winsize)
Definition: wifi-utils.cc:116
@ WIFI_MAC_DROP_QOS_OLD_PACKET
Definition: wifi-mac.h:70
ns3::Time timeout
The different BlockAckRequest variants.
The different BlockAck variants.