A Discrete-Event Network Simulator
API
edca-txop-n.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  */
22 
23 #include "ns3/log.h"
24 #include "ns3/pointer.h"
25 #include "edca-txop-n.h"
26 #include "dcf-manager.h"
27 #include "dcf-state.h"
28 #include "mac-tx-middle.h"
29 #include "wifi-mac-trailer.h"
30 #include "wifi-mac-queue.h"
32 #include "ns3/simulator.h"
33 
34 #undef NS_LOG_APPEND_CONTEXT
35 #define NS_LOG_APPEND_CONTEXT if (m_low != 0) { std::clog << "[mac=" << m_low->GetAddress () << "] "; }
36 
37 namespace ns3 {
38 
39 NS_LOG_COMPONENT_DEFINE ("EdcaTxopN");
40 
41 NS_OBJECT_ENSURE_REGISTERED (EdcaTxopN);
42 
43 TypeId
45 {
46  static TypeId tid = TypeId ("ns3::EdcaTxopN")
48  .SetGroupName ("Wifi")
49  .AddConstructor<EdcaTxopN> ()
50  .AddTraceSource ("BackoffTrace",
51  "Trace source for backoff values",
53  "ns3::TracedValue::Uint32Callback")
54  .AddTraceSource ("CwTrace",
55  "Trace source for contention window values",
57  "ns3::TracedValue::Uint32Callback")
58  .AddTraceSource ("TxopTrace",
59  "Trace source for txop start and duration times",
61  "ns3::TracedValueCallback::Time")
62  ;
63  return tid;
64 }
65 
67  : m_msduAggregator (0),
68  m_mpduAggregator (0),
69  m_typeOfStation (STA),
70  m_blockAckType (COMPRESSED_BLOCK_ACK),
71  m_startTxop (Seconds (0)),
72  m_isAccessRequestedForRts (false),
73  m_currentIsFragmented (false)
74 {
75  NS_LOG_FUNCTION (this);
76  m_qosBlockedDestinations = Create<QosBlockedDestinations> ();
77  m_baManager = CreateObject<BlockAckManager> ();
78  m_baManager->SetQueue (m_queue);
79  m_baManager->SetBlockAckType (m_blockAckType);
80  m_baManager->SetBlockDestinationCallback (MakeCallback (&QosBlockedDestinations::Block, m_qosBlockedDestinations));
81  m_baManager->SetUnblockDestinationCallback (MakeCallback (&QosBlockedDestinations::Unblock, m_qosBlockedDestinations));
82  m_baManager->SetMaxPacketDelay (m_queue->GetMaxDelay ());
83  m_baManager->SetTxOkCallback (MakeCallback (&EdcaTxopN::BaTxOk, this));
84  m_baManager->SetTxFailedCallback (MakeCallback (&EdcaTxopN::BaTxFailed, this));
85 }
86 
88 {
89  NS_LOG_FUNCTION (this);
90 }
91 
92 void
94 {
95  NS_LOG_FUNCTION (this);
96  m_baManager = 0;
98  m_msduAggregator = 0;
99  m_mpduAggregator = 0;
101 }
102 
103 bool
105 {
106  return m_baManager->ExistsAgreement (address, tid);
107 }
108 
109 uint32_t
111 {
112  return m_baManager->GetNBufferedPackets (address, tid);
113 }
114 
115 uint32_t
116 EdcaTxopN::GetNRetryNeededPackets (Mac48Address recipient, uint8_t tid) const
117 {
118  return m_baManager->GetNRetryNeededPackets (recipient, tid);
119 }
120 
121 void
123 {
124  m_baManager->CompleteAmpduExchange (recipient, tid);
125 }
126 
127 void
129 {
130  DcaTxop::SetWifiRemoteStationManager (remoteManager);
131  NS_LOG_FUNCTION (this << remoteManager);
132  m_baManager->SetWifiRemoteStationManager (m_stationManager);
133 }
134 
135 void
137 {
138  NS_LOG_FUNCTION (this << (uint16_t)type);
139  m_typeOfStation = type;
140 }
141 
144 {
145  NS_LOG_FUNCTION (this);
146  return m_typeOfStation;
147 }
148 
149 bool
151 {
152  NS_LOG_FUNCTION (this);
153  return !m_queue->IsEmpty () || m_currentPacket != 0 || m_baManager->HasPackets ();
154 }
155 
157 {
158  return m_txMiddle->GetNextSequenceNumberFor (hdr);
159 }
160 
162 {
164 }
165 
167 EdcaTxopN::PeekNextRetransmitPacket (WifiMacHeader &header,Mac48Address recipient, uint8_t tid, Time *timestamp)
168 {
169  return m_baManager->PeekNextPacketByTidAndAddress (header,recipient,tid, timestamp);
170 }
171 
172 void
173 EdcaTxopN::RemoveRetransmitPacket (uint8_t tid, Mac48Address recipient, uint16_t seqnumber)
174 {
175  m_baManager->RemovePacket (tid, recipient, seqnumber);
176 }
177 
178 void
180 {
181  NS_LOG_FUNCTION (this);
184  if (m_currentPacket == 0)
185  {
186  if (m_queue->IsEmpty () && !m_baManager->HasPackets ())
187  {
188  NS_LOG_DEBUG ("queue is empty");
189  return;
190  }
191  if (m_baManager->HasBar (m_currentBar))
192  {
194  return;
195  }
196  /* check if packets need retransmission are stored in BlockAckManager */
197  m_currentPacket = m_baManager->GetNextPacket (m_currentHdr);
198  if (m_currentPacket == 0)
199  {
200  Ptr<const WifiMacQueueItem> item = m_queue->PeekFirstAvailable (m_qosBlockedDestinations);
201  if (item == 0)
202  {
203  NS_LOG_DEBUG ("no available packets in the queue");
204  return;
205  }
206  m_currentHdr = item->GetHeader ();
207  m_currentPacketTimestamp = item->GetTimeStamp ();
210  && !m_baManager->ExistsAgreement (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ())
211  && SetupBlockAckIfNeeded ())
212  {
213  return;
214  }
215  item = m_queue->DequeueFirstAvailable (m_qosBlockedDestinations);
216  m_currentPacket = item->GetPacket ();
217  m_currentHdr = item->GetHeader ();
218  m_currentPacketTimestamp = item->GetTimeStamp ();
219  NS_ASSERT (m_currentPacket != 0);
220 
221  uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&m_currentHdr);
222  m_currentHdr.SetSequenceNumber (sequence);
227  m_fragmentNumber = 0;
228  NS_LOG_DEBUG ("dequeued size=" << m_currentPacket->GetSize () <<
229  ", to=" << m_currentHdr.GetAddr1 () <<
230  ", seq=" << m_currentHdr.GetSequenceControl ());
232  {
233  VerifyBlockAck ();
234  }
235  }
236  }
238  if (m_currentHdr.GetAddr1 ().IsGroup ())
239  {
244  NS_LOG_DEBUG ("tx broadcast");
245  }
247  {
249  }
250  else
251  {
253  {
255  }
256  else
257  {
259  }
260  //With COMPRESSED_BLOCK_ACK fragmentation must be avoided.
262  || (m_currentHdr.IsData () && !m_currentHdr.IsQosData ()))
264  && NeedFragmentation ())
265  {
266  m_currentIsFragmented = true;
268  WifiMacHeader hdr;
269  Ptr<Packet> fragment = GetFragmentPacket (&hdr);
270  if (IsLastFragment ())
271  {
272  NS_LOG_DEBUG ("fragmenting last fragment size=" << fragment->GetSize ());
274  }
275  else
276  {
277  NS_LOG_DEBUG ("fragmenting size=" << fragment->GetSize ());
279  }
280  m_low->StartTransmission (fragment, &hdr, m_currentParams, this);
281  }
282  else
283  {
284  m_currentIsFragmented = false;
285  WifiMacHeader peekedHdr;
287  if (m_currentHdr.IsQosData ()
288  && (item = m_queue->PeekByTidAndAddress (m_currentHdr.GetQosTid (),
291  && m_msduAggregator != 0 && !m_currentHdr.IsRetry ())
292  {
293  peekedHdr = item->GetHeader ();
294  /* here is performed aggregation */
295  Ptr<Packet> currentAggregatedPacket = Create<Packet> ();
296  m_msduAggregator->Aggregate (m_currentPacket, currentAggregatedPacket,
297  MapSrcAddressForAggregation (peekedHdr),
298  MapDestAddressForAggregation (peekedHdr));
299  bool aggregated = false;
300  bool isAmsdu = false;
301  Ptr<const WifiMacQueueItem> peekedItem = m_queue->PeekByTidAndAddress (m_currentHdr.GetQosTid (),
304  while (peekedItem != 0)
305  {
306  peekedHdr = peekedItem->GetHeader ();
307  aggregated = m_msduAggregator->Aggregate (peekedItem->GetPacket (), currentAggregatedPacket,
308  MapSrcAddressForAggregation (peekedHdr),
309  MapDestAddressForAggregation (peekedHdr));
310  if (aggregated)
311  {
312  isAmsdu = true;
313  m_queue->Remove (peekedItem->GetPacket ());
314  }
315  else
316  {
317  break;
318  }
319  peekedItem = m_queue->PeekByTidAndAddress (m_currentHdr.GetQosTid (),
321  }
322  if (isAmsdu)
323  {
326  m_currentPacket = currentAggregatedPacket;
327  currentAggregatedPacket = 0;
328  NS_LOG_DEBUG ("tx unicast A-MSDU");
329  }
330  }
334  {
335  CompleteTx ();
336  }
337  }
338  }
339 }
340 
342 {
343  NS_LOG_FUNCTION (this);
344  bool resetDcf = false;
345  // If an internal collision is experienced, the frame involved may still
346  // be sitting in the queue, and m_currentPacket may still be null.
347  Ptr<const Packet> packet;
348  WifiMacHeader header;
349  if (m_currentPacket == 0)
350  {
351  if (m_baManager->HasPackets ())
352  {
353  packet = m_baManager->PeekNextPacket (header);
354  }
355  else
356  {
357  Ptr<const WifiMacQueueItem> item = m_queue->Peek ();
358  if (item)
359  {
360  packet = item->GetPacket ();
361  header = item->GetHeader ();
362  }
363  }
364  }
365  else
366  {
367  packet = m_currentPacket;
368  header = m_currentHdr;
369  }
370  if (packet != 0)
371  {
373  {
374  if (!NeedRtsRetransmission (packet, header))
375  {
376  resetDcf = true;
377  m_stationManager->ReportFinalRtsFailed (header.GetAddr1 (), &header);
378  }
379  else
380  {
381  m_stationManager->ReportRtsFailed (header.GetAddr1 (), &header);
382  }
383  }
384  else if (header.GetAddr1 () == Mac48Address::GetBroadcast ())
385  {
386  resetDcf = false;
387  }
388  else
389  {
390  if (!NeedDataRetransmission (packet, header))
391  {
392  resetDcf = true;
393  m_stationManager->ReportFinalDataFailed (header.GetAddr1 (), &header);
394  }
395  else
396  {
397  m_stationManager->ReportDataFailed (header.GetAddr1 (), &header);
398  }
399  }
400  if (resetDcf)
401  {
402  NS_LOG_DEBUG ("reset DCF");
403  if (!m_txFailedCallback.IsNull ())
404  {
405  m_txFailedCallback (header);
406  }
407  //to reset the dcf.
408  if (m_currentPacket)
409  {
410  NS_LOG_DEBUG ("Discarding m_currentPacket");
411  m_currentPacket = 0;
412  }
413  else
414  {
415  NS_LOG_DEBUG ("Dequeueing and discarding head of queue");
416  m_queue->Remove ();
417  }
418  m_dcf->ResetCw ();
419  }
420  else
421  {
422  m_dcf->UpdateFailedCw ();
423  }
424  }
428 }
429 
430 void
432 {
433  NS_LOG_FUNCTION (this);
437 }
438 
439 void
441 {
442  NS_LOG_FUNCTION (this);
443  NS_LOG_DEBUG ("missed cts");
445  {
446  NS_LOG_DEBUG ("Cts Fail");
447  bool resetCurrentPacket = true;
449  if (!m_txFailedCallback.IsNull ())
450  {
452  }
454  {
455  uint8_t tid = GetTid (m_currentPacket, m_currentHdr);
456  m_low->FlushAggregateQueue (tid);
457 
459  {
460  NS_LOG_DEBUG ("Transmit Block Ack Request");
461  CtrlBAckRequestHeader reqHdr;
462  reqHdr.SetType (COMPRESSED_BLOCK_ACK);
464  reqHdr.SetTidInfo (tid);
465  reqHdr.SetHtImmediateAck (true);
466  Ptr<Packet> bar = Create<Packet> ();
467  bar->AddHeader (reqHdr);
468  Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ());
469  m_currentBar = request;
470  WifiMacHeader hdr;
472  hdr.SetAddr1 (request.recipient);
473  hdr.SetAddr2 (m_low->GetAddress ());
474  hdr.SetAddr3 (m_low->GetBssid ());
475  hdr.SetDsNotTo ();
476  hdr.SetDsNotFrom ();
477  hdr.SetNoRetry ();
478  hdr.SetNoMoreFragments ();
479  m_currentPacket = request.bar;
480  m_currentHdr = hdr;
481  resetCurrentPacket = false;
482  }
483  }
484  //to reset the dcf.
485  if (resetCurrentPacket == true)
486  {
487  m_currentPacket = 0;
488  }
489  m_dcf->ResetCw ();
490  m_cwTrace = m_dcf->GetCw ();
491  }
492  else
493  {
494  m_dcf->UpdateFailedCw ();
495  m_cwTrace = m_dcf->GetCw ();
496  }
500 }
501 
502 void
504 {
505  NS_LOG_FUNCTION (this);
508  || m_currentHdr.IsQosAmsdu ())
509  {
510  NS_LOG_DEBUG ("got ack. tx done.");
511  if (!m_txOkCallback.IsNull ())
512  {
514  }
515 
516  if (m_currentHdr.IsAction ())
517  {
518  WifiActionHeader actionHdr;
520  p->RemoveHeader (actionHdr);
521  if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK
523  {
524  MgtDelBaHeader delBa;
525  p->PeekHeader (delBa);
526  if (delBa.IsByOriginator ())
527  {
528  m_baManager->TearDownBlockAck (m_currentHdr.GetAddr1 (), delBa.GetTid ());
529  }
530  else
531  {
533  }
534  }
535  }
536  m_currentPacket = 0;
537  m_dcf->ResetCw ();
538  if (!HasTxop ())
539  {
541  {
543  }
544  m_cwTrace = m_dcf->GetCw ();
548  }
549  }
550  else
551  {
552  NS_LOG_DEBUG ("got ack. tx not done, size=" << m_currentPacket->GetSize ());
553  if (!HasTxop ())
554  {
556  {
558  m_cwTrace = m_dcf->GetCw ();
563  }
564  }
565  }
566 }
567 
568 void
570 {
571  NS_LOG_FUNCTION (this);
572  NS_LOG_DEBUG ("missed ack");
574  {
575  NS_LOG_DEBUG ("Ack Fail");
577  bool resetCurrentPacket = true;
578  if (!m_txFailedCallback.IsNull ())
579  {
581  }
583  {
584  uint8_t tid = GetTid (m_currentPacket, m_currentHdr);
585 
587  {
588  //send Block ACK Request in order to shift WinStart at the receiver
589  NS_LOG_DEBUG ("Transmit Block Ack Request");
590  CtrlBAckRequestHeader reqHdr;
591  reqHdr.SetType (COMPRESSED_BLOCK_ACK);
593  reqHdr.SetTidInfo (tid);
594  reqHdr.SetHtImmediateAck (true);
595  Ptr<Packet> bar = Create<Packet> ();
596  bar->AddHeader (reqHdr);
597  Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ());
598  m_currentBar = request;
599  WifiMacHeader hdr;
601  hdr.SetAddr1 (request.recipient);
602  hdr.SetAddr2 (m_low->GetAddress ());
603  hdr.SetAddr3 (m_low->GetBssid ());
604  hdr.SetDsNotTo ();
605  hdr.SetDsNotFrom ();
606  hdr.SetNoRetry ();
607  hdr.SetNoMoreFragments ();
608  m_currentPacket = request.bar;
609  m_currentHdr = hdr;
610  resetCurrentPacket = false;
611  }
612  }
613  //to reset the dcf.
614  if (resetCurrentPacket == true)
615  {
616  m_currentPacket = 0;
617  }
618  m_dcf->ResetCw ();
619  m_cwTrace = m_dcf->GetCw ();
620  }
621  else
622  {
623  NS_LOG_DEBUG ("Retransmit");
625  m_dcf->UpdateFailedCw ();
626  m_cwTrace = m_dcf->GetCw ();
627  }
631 }
632 
633 void
635 {
636  NS_LOG_FUNCTION (this << (uint16_t)nMpdus);
637  uint8_t tid = GetTid (m_currentPacket, m_currentHdr);
639  {
640  m_stationManager->ReportAmpduTxStatus (m_currentHdr.GetAddr1 (), tid, 0, nMpdus, 0, 0);
641  }
642  if (NeedBarRetransmission ())
643  {
645  {
646  //should i report this to station addressed by ADDR1?
647  NS_LOG_DEBUG ("Retransmit block ack request");
649  }
650  else
651  {
652  //standard says when loosing a BlockAck originator may send a BAR page 139
653  NS_LOG_DEBUG ("Transmit Block Ack Request");
654  CtrlBAckRequestHeader reqHdr;
655  reqHdr.SetType (COMPRESSED_BLOCK_ACK);
656  if (m_currentHdr.IsQosData ())
657  {
659  }
660  else if (m_currentHdr.IsBlockAckReq ())
661  {
662  CtrlBAckRequestHeader baReqHdr;
663  m_currentPacket->PeekHeader (baReqHdr);
664  reqHdr.SetStartingSequence (baReqHdr.GetStartingSequence ());
665  }
666  else if (m_currentHdr.IsBlockAck ())
667  {
668  CtrlBAckResponseHeader baRespHdr;
669  m_currentPacket->PeekHeader (baRespHdr);
671  }
672  reqHdr.SetTidInfo (tid);
673  reqHdr.SetHtImmediateAck (true);
674  Ptr<Packet> bar = Create<Packet> ();
675  bar->AddHeader (reqHdr);
676  Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ());
677  m_currentBar = request;
678  WifiMacHeader hdr;
680  hdr.SetAddr1 (request.recipient);
681  hdr.SetAddr2 (m_low->GetAddress ());
682  hdr.SetAddr3 (m_low->GetBssid ());
683  hdr.SetDsNotTo ();
684  hdr.SetDsNotFrom ();
685  hdr.SetNoRetry ();
686  hdr.SetNoMoreFragments ();
687 
688  m_currentPacket = request.bar;
689  m_currentHdr = hdr;
690  }
691  m_dcf->UpdateFailedCw ();
692  m_cwTrace = m_dcf->GetCw ();
693  }
694  else
695  {
696  NS_LOG_DEBUG ("Block Ack Request Fail");
697  //to reset the dcf.
698  m_currentPacket = 0;
699  m_dcf->ResetCw ();
700  m_cwTrace = m_dcf->GetCw ();
701  }
705 }
706 
709 {
710  return m_msduAggregator;
711 }
712 
715 {
716  return m_mpduAggregator;
717 }
718 
719 void
721 {
722  NS_LOG_FUNCTION (this);
723  if ((m_currentPacket != 0
724  || !m_queue->IsEmpty () || m_baManager->HasPackets ())
725  && !m_dcf->IsAccessRequested ())
726  {
727  Ptr<const Packet> packet;
728  WifiMacHeader hdr;
729  if (m_currentPacket != 0)
730  {
731  packet = m_currentPacket;
732  hdr = m_currentHdr;
733  }
734  else if (m_baManager->HasPackets ())
735  {
736  packet = m_baManager->PeekNextPacket (hdr);
737  }
738  else
739  {
740  Ptr<const WifiMacQueueItem> item = m_queue->PeekFirstAvailable (m_qosBlockedDestinations);
741  if (item)
742  {
743  packet = item->GetPacket ();
744  hdr = item->GetHeader ();
745  m_currentPacketTimestamp = item->GetTimeStamp ();
746  }
747  }
748  if (packet != 0)
749  {
750  m_isAccessRequestedForRts = m_stationManager->NeedRts (hdr.GetAddr1 (), &hdr, packet, m_low->GetDataTxVector (packet, &hdr));
751  }
752  else
753  {
755  }
757  }
758 }
759 
760 void
762 {
763  //NS_LOG_FUNCTION (this);
764  if (m_currentPacket == 0
765  && (!m_queue->IsEmpty () || m_baManager->HasPackets ())
766  && !m_dcf->IsAccessRequested ())
767  {
768  Ptr<const Packet> packet;
769  WifiMacHeader hdr;
770  if (m_currentPacket != 0)
771  {
772  packet = m_currentPacket;
773  hdr = m_currentHdr;
774  }
775  else if (m_baManager->HasPackets ())
776  {
777  packet = m_baManager->PeekNextPacket (hdr);
778  }
779  else
780  {
781  Ptr<const WifiMacQueueItem> item = m_queue->PeekFirstAvailable (m_qosBlockedDestinations);
782  if (item)
783  {
784  packet = item->GetPacket ();
785  hdr = item->GetHeader ();
786  m_currentPacketTimestamp = item->GetTimeStamp ();
787  }
788  }
789  if (packet != 0)
790  {
791  m_isAccessRequestedForRts = m_stationManager->NeedRts (hdr.GetAddr1 (), &hdr, packet, m_low->GetDataTxVector (packet, &hdr));
792  }
793  else
794  {
796  }
798  }
799 }
800 
801 bool
803 {
804  uint8_t tid = 0;
805  uint16_t seqNumber = 0;
806  if (m_currentHdr.IsQosData ())
807  {
808  tid = m_currentHdr.GetQosTid ();
809  seqNumber = m_currentHdr.GetSequenceNumber ();
810  }
811  else if (m_currentHdr.IsBlockAckReq ())
812  {
813  CtrlBAckRequestHeader baReqHdr;
814  m_currentPacket->PeekHeader (baReqHdr);
815  tid = baReqHdr.GetTidInfo ();
816  seqNumber = baReqHdr.GetStartingSequence ();
817  }
818  else if (m_currentHdr.IsBlockAck ())
819  {
820  CtrlBAckResponseHeader baRespHdr;
821  m_currentPacket->PeekHeader (baRespHdr);
822  tid = baRespHdr.GetTidInfo ();
823  seqNumber = m_currentHdr.GetSequenceNumber ();
824  }
825  return m_baManager->NeedBarRetransmission (tid, seqNumber, m_currentHdr.GetAddr1 ());
826 }
827 
828 void
830 {
831  NS_LOG_FUNCTION (this);
832  Time txopLimit = GetTxopLimit ();
833  NS_ASSERT (txopLimit.IsZero () || Simulator::Now () - m_startTxop <= txopLimit);
835  Ptr<const Packet> peekedPacket = m_baManager->GetNextPacket (hdr);
836  if (peekedPacket == 0)
837  {
838  Ptr<const WifiMacQueueItem> peekedItem = m_queue->PeekByTidAndAddress (m_currentHdr.GetQosTid (),
841  if (peekedItem)
842  {
843  peekedPacket = peekedItem->GetPacket ();
844  hdr = peekedItem->GetHeader ();
845  }
846  }
847  if ((m_currentHdr.IsQosBlockAck () && peekedPacket == 0) || m_baManager->HasBar (m_currentBar))
848  {
850  return;
851  }
852  else if (peekedPacket == 0)
853  {
854  if (txopLimit.IsStrictlyPositive ())
855  {
856  NS_ASSERT (Simulator::Now () - m_startTxop <= txopLimit);
858  }
859  return;
860  }
864  {
866  }
867  else
868  {
870  }
871  if (txopLimit >= GetLow ()->CalculateOverallTxTime (peekedPacket, &hdr, m_currentParams))
872  {
873  NS_LOG_DEBUG ("start next packet");
874  Ptr<WifiMacQueueItem> item = m_queue->DequeueByTidAndAddress (m_currentHdr.GetQosTid (),
877  NS_ASSERT (item != 0);
878  m_currentPacket = item->GetPacket ();
879  m_currentHdr = item->GetHeader ();
880  NS_ASSERT (m_currentPacket != 0);
881  uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&m_currentHdr);
882  m_currentHdr.SetSequenceNumber (sequence);
887  m_fragmentNumber = 0;
888  VerifyBlockAck ();
891  {
892  CompleteTx ();
893  }
894  }
895  else if (txopLimit.IsStrictlyPositive ())
896  {
898  }
899 }
900 
901 Time
903 {
904  Time remainingTxop = GetTxopLimit ();
905  remainingTxop -= (Simulator::Now () - m_startTxop);
906  if (remainingTxop.IsStrictlyNegative ())
907  {
908  remainingTxop = Seconds (0);
909  }
910  NS_LOG_FUNCTION (this << remainingTxop);
911  return remainingTxop;
912 }
913 
914 bool
915 EdcaTxopN::HasTxop (void) const
916 {
917  NS_LOG_FUNCTION (this);
918  WifiMacHeader hdr;
919  if (!m_currentHdr.IsQosData () || GetTxopLimit ().IsZero ())
920  {
921  return false;
922  }
923 
924  Ptr<const WifiMacQueueItem> peekedItem = m_queue->PeekByTidAndAddress (m_currentHdr.GetQosTid (),
927  if (peekedItem == 0)
928  {
929  return false;
930  }
931 
932  Ptr<const Packet> peekedPacket = peekedItem->GetPacket ();
933  hdr = peekedItem->GetHeader ();
936  {
937  params.DisableAck ();
938  }
939  else
940  {
941  params.EnableAck ();
942  }
943 
944  Time duration = GetLow ()->CalculateOverallTxTime (peekedPacket, &hdr, params);
945  if (m_currentPacket != 0)
946  {
947  //take into account current transmission in duration
948  duration += GetLow ()->CalculateOverallTxTime (m_currentPacket, &m_currentHdr, params);
949  }
950  return (GetTxopRemaining () >= duration);
951 }
952 
953 void
955 {
956  NS_LOG_FUNCTION (this);
957  NS_LOG_DEBUG ("a transmission that did not require an ACK just finished");
959  {
961  }
962  m_currentPacket = 0;
963  m_dcf->ResetCw ();
964  m_cwTrace = m_dcf->GetCw ();
968 }
969 
970 bool
972 {
973  NS_LOG_FUNCTION (this);
978  && m_currentHdr.IsQosData ()
981  {
982  //MSDU is not fragmented when it is transmitted using an HT-immediate or
983  //HT-delayed Block Ack agreement or when it is carried in an A-MPDU.
984  return false;
985  }
986  bool needTxopFragmentation = false;
988  {
990  }
991  return (needTxopFragmentation || m_stationManager->NeedFragmentation (m_currentHdr.GetAddr1 (), &m_currentHdr, m_currentPacket));
992 }
993 
994 bool
996 {
997  if (GetTxopLimit ().IsZero ())
998  {
999  return false;
1000  }
1003  {
1004  return true;
1005  }
1006  return false;
1007 }
1008 
1009 uint32_t
1011 {
1012  Time txopDuration = GetTxopLimit ();
1013  if (txopDuration.IsZero ())
1014  {
1015  return 0;
1016  }
1017  uint32_t maxSize = m_currentPacket->GetSize ();
1018  uint32_t minSize = 0;
1019  uint32_t size = 0;
1020  bool found = false;
1021  while (!found)
1022  {
1023  size = (minSize + ((maxSize - minSize) / 2));
1025  {
1026  maxSize = size;
1027  }
1028  else
1029  {
1030  minSize = size;
1031  }
1034  {
1035  found = true;
1036  }
1037  }
1038  NS_ASSERT (size != 0);
1039  return size;
1040 }
1041 
1042 uint32_t
1044 {
1045  uint32_t fragmentSize = GetTxopFragmentSize ();
1046  uint32_t nFragments = (m_currentPacket->GetSize () / fragmentSize);
1047  if ((m_currentPacket->GetSize () % fragmentSize) > 0)
1048  {
1049  nFragments++;
1050  }
1051  NS_LOG_DEBUG ("GetNTxopFragment returning " << nFragments);
1052  return nFragments;
1053 }
1054 
1055 uint32_t
1056 EdcaTxopN::GetTxopFragmentOffset (uint32_t fragmentNumber) const
1057 {
1058  if (fragmentNumber == 0)
1059  {
1060  return 0;
1061  }
1062  uint32_t offset = 0;
1063  uint32_t fragmentSize = GetTxopFragmentSize ();
1064  uint32_t nFragments = (m_currentPacket->GetSize () / fragmentSize);
1065  if ((m_currentPacket->GetSize () % fragmentSize) > 0)
1066  {
1067  nFragments++;
1068  }
1069  if (fragmentNumber < nFragments)
1070  {
1071  offset = (fragmentNumber * fragmentSize);
1072  }
1073  else
1074  {
1075  NS_ASSERT (false);
1076  }
1077  NS_LOG_DEBUG ("GetTxopFragmentOffset returning " << offset);
1078  return offset;
1079 }
1080 
1081 uint32_t
1082 EdcaTxopN::GetNextTxopFragmentSize (uint32_t fragmentNumber) const
1083 {
1084  NS_LOG_FUNCTION (this << fragmentNumber);
1085  uint32_t fragmentSize = GetTxopFragmentSize ();
1086  uint32_t nFragments = GetNTxopFragment ();
1087  if (fragmentNumber >= nFragments)
1088  {
1089  NS_LOG_DEBUG ("GetNextTxopFragmentSize returning 0");
1090  return 0;
1091  }
1092  if (fragmentNumber == nFragments - 1)
1093  {
1094  fragmentSize = (m_currentPacket->GetSize () - ((nFragments - 1) * fragmentSize));
1095  }
1096  NS_LOG_DEBUG ("GetNextTxopFragmentSize returning " << fragmentSize);
1097  return fragmentSize;
1098 }
1099 
1100 uint32_t
1102 {
1103  uint32_t size;
1104  if (IsTxopFragmentation ())
1105  {
1107  }
1108  else
1109  {
1111  }
1112  return size;
1113 }
1114 
1115 uint32_t
1117 {
1118  uint32_t size;
1119  if (IsTxopFragmentation ())
1120  {
1122  }
1123  else
1124  {
1126  }
1127  return size;
1128 }
1129 
1130 uint32_t
1132 {
1133  uint32_t offset;
1134  if (IsTxopFragmentation ())
1135  {
1137  }
1138  else
1139  {
1142  }
1143  return offset;
1144 }
1145 
1146 bool
1148 {
1149  bool isLastFragment;
1150  if (IsTxopFragmentation ())
1151  {
1152  isLastFragment = (m_fragmentNumber == GetNTxopFragment () - 1);
1153  }
1154  else
1155  {
1158  }
1159  return isLastFragment;
1160 }
1161 
1164 {
1165  NS_LOG_FUNCTION (this << hdr);
1166  *hdr = m_currentHdr;
1168  uint32_t startOffset = GetFragmentOffset ();
1169  Ptr<Packet> fragment;
1170  if (IsLastFragment ())
1171  {
1172  hdr->SetNoMoreFragments ();
1173  }
1174  else
1175  {
1176  hdr->SetMoreFragments ();
1177  }
1178  fragment = m_currentPacket->CreateFragment (startOffset,
1179  GetFragmentSize ());
1180  return fragment;
1181 }
1182 
1183 void
1185 {
1186  NS_LOG_FUNCTION (this << (uint16_t)ac);
1187  m_ac = ac;
1188 }
1189 
1192 {
1193  NS_LOG_FUNCTION (this << &hdr);
1194  Mac48Address retval;
1196  {
1197  retval = hdr.GetAddr2 ();
1198  }
1199  else
1200  {
1201  retval = hdr.GetAddr3 ();
1202  }
1203  return retval;
1204 }
1205 
1208 {
1209  NS_LOG_FUNCTION (this << &hdr);
1210  Mac48Address retval;
1212  {
1213  retval = hdr.GetAddr1 ();
1214  }
1215  else
1216  {
1217  retval = hdr.GetAddr3 ();
1218  }
1219  return retval;
1220 }
1221 
1222 void
1224 {
1225  NS_LOG_FUNCTION (this << aggr);
1226  m_msduAggregator = aggr;
1227 }
1228 
1229 void
1231 {
1232  NS_LOG_FUNCTION (this << aggr);
1233  m_mpduAggregator = aggr;
1234 }
1235 
1236 void
1238 {
1239  NS_LOG_FUNCTION (this << packet << &hdr);
1240  WifiMacTrailer fcs;
1241  m_stationManager->PrepareForQueue (hdr.GetAddr1 (), &hdr, packet);
1242  m_queue->PushFront (Create<WifiMacQueueItem> (packet, hdr));
1244 }
1245 
1246 void
1248 {
1249  NS_LOG_FUNCTION (this << respHdr << recipient);
1250  NS_LOG_DEBUG ("received ADDBA response from " << recipient);
1251  uint8_t tid = respHdr->GetTid ();
1252  if (m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::PENDING))
1253  {
1254  if (respHdr->GetStatusCode ().IsSuccess ())
1255  {
1256  NS_LOG_DEBUG ("block ack agreement established with " << recipient);
1257  m_baManager->UpdateAgreement (respHdr, recipient);
1258  }
1259  else
1260  {
1261  NS_LOG_DEBUG ("discard ADDBA response" << recipient);
1262  m_baManager->NotifyAgreementUnsuccessful (recipient, tid);
1263  }
1264  }
1266 }
1267 
1268 void
1270 {
1271  NS_LOG_FUNCTION (this << delBaHdr << recipient);
1272  NS_LOG_DEBUG ("received DELBA frame from=" << recipient);
1273  m_baManager->TearDownBlockAck (recipient, delBaHdr->GetTid ());
1274 }
1275 
1276 void
1277 EdcaTxopN::GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address recipient, double rxSnr, WifiMode txMode, double dataSnr)
1278 {
1279  NS_LOG_FUNCTION (this << blockAck << recipient << rxSnr << txMode.GetUniqueName () << dataSnr);
1280  NS_LOG_DEBUG ("got block ack from=" << recipient);
1281  m_baManager->NotifyGotBlockAck (blockAck, recipient, rxSnr, txMode, dataSnr);
1282  if (!m_txOkCallback.IsNull ())
1283  {
1285  }
1286  m_currentPacket = 0;
1287  m_dcf->ResetCw ();
1288  if (!HasTxop ())
1289  {
1291  {
1293  }
1294  m_cwTrace = m_dcf->GetCw ();
1298  }
1299 }
1300 
1301 void
1303 {
1304  NS_LOG_FUNCTION (this);
1305  uint8_t tid = m_currentHdr.GetQosTid ();
1306  Mac48Address recipient = m_currentHdr.GetAddr1 ();
1307  uint16_t sequence = m_currentHdr.GetSequenceNumber ();
1308  if (m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::INACTIVE))
1309  {
1310  m_baManager->SwitchToBlockAckIfNeeded (recipient, tid, sequence);
1311  }
1312  if ((m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED))
1313  && (GetMpduAggregator () == 0 || GetMpduAggregator ()->GetMaxAmpduSize () == 0))
1314  {
1316  }
1317 }
1318 
1320 {
1321  NS_LOG_FUNCTION (this << dest);
1322  if (m_aMpduEnabled.find (dest) != m_aMpduEnabled.end ())
1323  {
1324  return m_aMpduEnabled.find (dest)->second;
1325  }
1326  return false;
1327 }
1328 
1329 void EdcaTxopN::SetAmpduExist (Mac48Address dest, bool enableAmpdu)
1330 {
1331  NS_LOG_FUNCTION (this << dest << enableAmpdu);
1332  if (m_aMpduEnabled.find (dest) != m_aMpduEnabled.end () && m_aMpduEnabled.find (dest)->second != enableAmpdu)
1333  {
1334  m_aMpduEnabled.erase (m_aMpduEnabled.find (dest));
1335  }
1336  if (m_aMpduEnabled.find (dest) == m_aMpduEnabled.end ())
1337  {
1338  m_aMpduEnabled.insert (std::make_pair (dest, enableAmpdu));
1339  }
1340 }
1341 
1342 void
1344 {
1345  NS_LOG_FUNCTION (this);
1347  {
1348  if (!m_currentHdr.IsRetry ())
1349  {
1351  }
1352  m_baManager->NotifyMpduTransmission (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid (),
1355  }
1356 }
1357 
1358 void
1360 {
1361  NS_ASSERT (hdr.IsQosData ());
1362  m_baManager->StorePacket (packet, hdr, tstamp);
1363  m_baManager->NotifyMpduTransmission (hdr.GetAddr1 (), hdr.GetQosTid (),
1366 }
1367 
1368 bool
1370 {
1371  NS_LOG_FUNCTION (this);
1372  uint8_t tid = m_currentHdr.GetQosTid ();
1373  Mac48Address recipient = m_currentHdr.GetAddr1 ();
1374  uint32_t packets = m_queue->GetNPacketsByTidAndAddress (tid, WifiMacHeader::ADDR1, recipient);
1375  if ((m_blockAckThreshold > 0 && packets >= m_blockAckThreshold)
1376  || (m_mpduAggregator != 0 && m_mpduAggregator->GetMaxAmpduSize () > 0 && packets > 1)
1379  {
1380  /* Block ack setup */
1381  uint16_t startingSequence = m_txMiddle->GetNextSeqNumberByTidAndAddress (tid, recipient);
1382  SendAddBaRequest (recipient, tid, startingSequence, m_blockAckInactivityTimeout, true);
1383  return true;
1384  }
1385  return false;
1386 }
1387 
1388 void
1390 {
1391  NS_LOG_FUNCTION (this << &bar);
1392  WifiMacHeader hdr;
1394  hdr.SetAddr1 (bar.recipient);
1395  hdr.SetAddr2 (m_low->GetAddress ());
1396  hdr.SetAddr3 (m_low->GetBssid ());
1397  hdr.SetDsNotTo ();
1398  hdr.SetDsNotFrom ();
1399  hdr.SetNoRetry ();
1400  hdr.SetNoMoreFragments ();
1401 
1402  m_currentPacket = bar.bar;
1403  m_currentHdr = hdr;
1404 
1408  if (bar.immediate)
1409  {
1411  {
1413  }
1415  {
1417  }
1418  else if (m_blockAckType == MULTI_TID_BLOCK_ACK)
1419  {
1420  NS_FATAL_ERROR ("Multi-tid block ack is not supported");
1421  }
1422  }
1423  else
1424  {
1425  //Delayed block ack
1427  }
1429 }
1430 
1431 void
1433 {
1434  NS_LOG_FUNCTION (this);
1435  m_baManager->SetTxMiddle (m_txMiddle);
1436  m_low->RegisterEdcaForAc (m_ac, this);
1437  m_baManager->SetBlockAckInactivityCallback (MakeCallback (&EdcaTxopN::SendDelbaFrame, this));
1438 }
1439 
1440 void
1442 {
1443  NS_LOG_FUNCTION (this << (uint16_t)threshold);
1444  m_blockAckThreshold = threshold;
1445  m_baManager->SetBlockAckThreshold (threshold);
1446 }
1447 
1448 void
1450 {
1451  NS_LOG_FUNCTION (this << timeout);
1453 }
1454 
1455 uint8_t
1457 {
1458  NS_LOG_FUNCTION (this);
1459  return m_blockAckThreshold;
1460 }
1461 
1462 void
1463 EdcaTxopN::SendAddBaRequest (Mac48Address dest, uint8_t tid, uint16_t startSeq,
1464  uint16_t timeout, bool immediateBAck)
1465 {
1466  NS_LOG_FUNCTION (this << dest << (uint16_t)tid << startSeq << timeout << immediateBAck);
1467  NS_LOG_DEBUG ("sent ADDBA request to " << dest);
1468  WifiMacHeader hdr;
1469  hdr.SetAction ();
1470  hdr.SetAddr1 (dest);
1471  hdr.SetAddr2 (m_low->GetAddress ());
1472  hdr.SetAddr3 (m_low->GetAddress ());
1473  hdr.SetDsNotTo ();
1474  hdr.SetDsNotFrom ();
1475 
1476  WifiActionHeader actionHdr;
1479  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
1480 
1481  Ptr<Packet> packet = Create<Packet> ();
1482  /*Setting ADDBARequest header*/
1483  MgtAddBaRequestHeader reqHdr;
1484  reqHdr.SetAmsduSupport (true);
1485  if (immediateBAck)
1486  {
1487  reqHdr.SetImmediateBlockAck ();
1488  }
1489  else
1490  {
1491  reqHdr.SetDelayedBlockAck ();
1492  }
1493  reqHdr.SetTid (tid);
1494  /* For now we don't use buffer size field in the ADDBA request frame. The recipient
1495  * will choose how many packets it can receive under block ack.
1496  */
1497  reqHdr.SetBufferSize (0);
1498  reqHdr.SetTimeout (timeout);
1499  reqHdr.SetStartingSequence (startSeq);
1500 
1501  m_baManager->CreateAgreement (&reqHdr, dest);
1502 
1503  packet->AddHeader (reqHdr);
1504  packet->AddHeader (actionHdr);
1505 
1506  m_currentPacket = packet;
1507  m_currentHdr = hdr;
1508 
1509  uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&m_currentHdr);
1510  m_currentHdr.SetSequenceNumber (sequence);
1515 
1520 
1522 }
1523 
1524 void
1525 EdcaTxopN::SendDelbaFrame (Mac48Address addr, uint8_t tid, bool byOriginator)
1526 {
1527  NS_LOG_FUNCTION (this << addr << (uint16_t)tid << byOriginator);
1528  WifiMacHeader hdr;
1529  hdr.SetAction ();
1530  hdr.SetAddr1 (addr);
1531  hdr.SetAddr2 (m_low->GetAddress ());
1532  hdr.SetAddr3 (m_low->GetAddress ());
1533  hdr.SetDsNotTo ();
1534  hdr.SetDsNotFrom ();
1535 
1536  MgtDelBaHeader delbaHdr;
1537  delbaHdr.SetTid (tid);
1538  if (byOriginator)
1539  {
1540  delbaHdr.SetByOriginator ();
1541  }
1542  else
1543  {
1544  delbaHdr.SetByRecipient ();
1545  }
1546 
1547  WifiActionHeader actionHdr;
1550  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
1551 
1552  Ptr<Packet> packet = Create<Packet> ();
1553  packet->AddHeader (delbaHdr);
1554  packet->AddHeader (actionHdr);
1555 
1556  PushFront (packet, hdr);
1557 }
1558 
1559 void
1561 {
1562  NS_LOG_FUNCTION (this);
1563  m_dcf->ResetCw ();
1564  m_cwTrace = m_dcf->GetCw ();
1567 }
1568 
1569 void
1571 {
1572  NS_LOG_FUNCTION (this << hdr);
1573  if (!m_txOkCallback.IsNull ())
1574  {
1576  }
1577 }
1578 
1579 void
1581 {
1582  NS_LOG_FUNCTION (this << hdr);
1583  if (!m_txFailedCallback.IsNull ())
1584  {
1586  }
1587 }
1588 
1589 bool
1591 {
1592  return true;
1593 }
1594 
1595 } //namespace ns3
MacLowTransmissionParameters m_currentParams
current transmission parameters
Definition: dca-txop.h:421
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:267
void SetAction()
Set Type/Subtype values for an action header.
void DoDispose(void)
Destructor implementation.
Definition: edca-txop-n.cc:93
void SetRetry(void)
Set the Retry bit in the Frame Control field.
void SetMoreFragments(void)
Set the More Fragment bit in the Frame Control field.
bool NeedRtsRetransmission(Ptr< const Packet > packet, const WifiMacHeader &hdr)
Check if RTS should be re-transmitted if CTS was missed.
Definition: dca-txop.cc:275
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Ptr< DcfState > m_dcf
the DCF state
Definition: dca-txop.h:408
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
uint8_t m_fragmentNumber
the fragment number
Definition: dca-txop.h:422
void SetBlockAckInactivityTimeout(uint16_t timeout)
Set the Block Ack inactivity timeout.
void SetType(WifiMacType type)
Set Type/Subtype values with the correct values depending on the given type.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
virtual void StartTransmission(Ptr< const Packet > packet, const WifiMacHeader *hdr, MacLowTransmissionParameters parameters, Ptr< DcaTxop > dca)
Definition: mac-low.cc:628
uint16_t m_blockAckInactivityTimeout
the Block ACK inactivity timeout
Definition: edca-txop-n.h:553
uint32_t GetFragmentOffset(void) const
Calculate the offset for the current fragment.
uint32_t GetTxopFragmentOffset(uint32_t fragmentNumber) const
Calculate the offset for the fragment.
void VerifyBlockAck(void)
Verifies if dequeued packet has to be transmitted with ack policy Block Ack.
void StartNextPacket(void)
Start transmission for the next packet if allowed by the TxopLimit.
Definition: edca-txop-n.cc:829
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
Definition: mgt-headers.h:625
void NotifyCollision(void)
Notify the EDCAF that collision has occurred.
Definition: edca-txop-n.cc:431
void ReportDataFailed(Mac48Address address, const WifiMacHeader *header)
Should be invoked whenever the AckTimeout associated to a transmission attempt expires.
void EnableBasicBlockAck(void)
Wait BASICBLOCKACKTimeout for a Basic Block Ack Response frame.
Definition: mac-low.cc:73
void CompleteMpduTx(Ptr< const Packet > packet, WifiMacHeader hdr, Time tstamp)
Stores an MPDU (part of an A-MPDU) in blockackagreement (i.e.
bool HasTxop(void) const
Check if the station has TXOP granted for the next MPDU.
Definition: edca-txop-n.cc:915
bool IsZero(void) const
Definition: nstime.h:274
void SendBlockAckRequest(const Bar &bar)
After that all packets, for which a block ack agreement was established, have been transmitted...
bool IsAction() const
Return true if the header is an Action header.
bool GetQosSupported(Mac48Address address) const
Return whether the given station is QoS capable.
Ptr< MacLow > m_low
the MacLow
Definition: dca-txop.h:415
Mac48Address GetBssid(void) const
Return the Basic Service Set Identification.
Definition: mac-low.cc:585
Mac48Address GetAddr3(void) const
Return the address in the Address 3 field.
Implement the header for management frames of type add block ack request.
Definition: mgt-headers.h:758
void SetAccessCategory(AcIndex ac)
Set the access category of this EDCAF.
void SetNoMoreFragments(void)
Un-set the More Fragment bit in the Frame Control Field.
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1270
#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
bool NeedBarRetransmission(void)
Check if Block ACK Request should be re-transmitted.
Definition: edca-txop-n.cc:802
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
uint8_t m_blockAckThreshold
the Block ACK threshold
Definition: edca-txop-n.h:550
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:796
bool IsBroadcast(void) const
TxOk m_txOkCallback
the transmit OK callback
Definition: dca-txop.h:410
bool NeedDataRetransmission(Ptr< const Packet > packet, const WifiMacHeader &hdr)
Check if DATA should be re-transmitted if ACK was missed.
Definition: dca-txop.cc:282
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
void SetHtImmediateAck(bool immediateAck)
Enable or disable HT immediate ACK.
bool IsBlockAck(void) const
Return true if the header is a Block ACK header.
bool NeedRts(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet, WifiTxVector txVector)
uint32_t GetNextFragmentSize(void) const
Calculate the size of the next fragment.
void UpdateFragmentationThreshold(void)
Typically called to update the fragmentation threshold at the start of a new transmission.
bool IsLastFragment(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet, uint32_t fragmentNumber)
CategoryValue GetCategory()
Return the category value.
Definition: mgt-headers.cc:888
void ResetCw(void)
Update the value of the CW variable to take into account a transmission success or a transmission abo...
Definition: dcf-state.cc:130
Time GetTxopRemaining(void) const
Return the remaining duration in the current TXOP.
Definition: edca-txop-n.cc:902
void PrepareForQueue(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet)
Ptr< MsduAggregator > m_msduAggregator
A-MSDU aggregator.
Definition: edca-txop-n.h:545
void SetWifiRemoteStationManager(const Ptr< WifiRemoteStationManager > remoteManager)
Set WifiRemoteStationsManager this EdcaTxopN is associated to.
Definition: edca-txop-n.cc:128
ns3::Time timeout
void SetTid(uint8_t)
Set Traffic ID (TID).
uint32_t GetFragmentSize(void) const
Calculate the size of the current fragment.
Block Ack Request.
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:97
uint32_t GetTxopFragmentSize() const
Calculate the size of the current TXOP fragment.
bool IsQosAmsdu(void) const
Check if the A-MSDU present bit is set in the QoS control field.
control how a packet is transmitted.
Definition: mac-low.h:54
void MissedBlockAck(uint8_t nMpdus)
Event handler when a Block ACK timeout has occurred.
Definition: edca-txop-n.cc:634
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support.
void SetType(BlockAckType type)
Set the block ACK type.
bool m_isAccessRequestedForRts
flag whether access is requested to transmit a RTS frame
Definition: edca-txop-n.h:556
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Ptr< MpduAggregator > m_mpduAggregator
A-MPDU aggregator.
Definition: edca-txop-n.h:546
AcIndex m_ac
the access category
Definition: edca-txop-n.h:544
void MissedAck(void)
Event handler when an ACK is missed.
Definition: edca-txop-n.cc:569
TracedCallback< Time, Time > m_txopTrace
TXOP trace callback.
Definition: edca-txop-n.h:561
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:227
uint8_t GetQosTid(void) const
Return the Traffic ID of a QoS header.
Time GetTxopLimit(void) const
Return the TXOP limit.
Definition: dca-txop.cc:213
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
void DestroyBlockAckAgreement(Mac48Address originator, uint8_t tid)
Definition: mac-low.cc:2287
This queue contains packets for a particular access class.
Definition: edca-txop-n.h:68
void GotDelBaFrame(const MgtDelBaHeader *delBaHdr, Mac48Address recipient)
Event handler when a DELBA frame is received.
Ptr< WifiMacQueue > m_queue
the wifi MAC queue
Definition: dca-txop.h:413
void NotifyAccessGranted(void)
Notify the EDCAF that access has been granted.
Definition: edca-txop-n.cc:179
void RemoveRetransmitPacket(uint8_t tid, Mac48Address recipient, uint16_t seqnumber)
Remove a packet after you peek in the retransmit queue and get it.
Definition: edca-txop-n.cc:173
virtual uint32_t GetInteger(void)=0
Get the next random value as an integer drawn from the distribution.
void ReportFinalDataFailed(Mac48Address address, const WifiMacHeader *header)
Should be invoked after calling ReportDataFailed if NeedDataRetransmission returns false...
bool immediate
immediate
void NotifyInternalCollision(void)
Notify the EDCAF that internal collision has occurred.
Definition: edca-txop-n.cc:341
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
std::map< Mac48Address, bool > m_aMpduEnabled
list containing flags whether A-MPDU is enabled for a given destination address
Definition: edca-txop-n.h:74
TracedValue< uint32_t > m_cwTrace
CW trace value.
Definition: edca-txop-n.h:560
uint16_t GetNextSequenceNumberFor(const WifiMacHeader *hdr)
Return the next sequence number for the given header.
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
TracedValue< uint32_t > m_backoffTrace
backoff trace value
Definition: edca-txop-n.h:559
void ReportRtsFailed(Mac48Address address, const WifiMacHeader *header)
Should be invoked whenever the RtsTimeout associated to a transmission attempt expires.
uint32_t GetNTxopFragment() const
Calculate the number of TXOP fragments needed for the transmission of the current packet...
void SetAddr3(Mac48Address address)
Fill the Address 3 field with the given address.
void SendAddBaRequest(Mac48Address recipient, uint8_t tid, uint16_t startSeq, uint16_t timeout, bool immediateBAck)
Sends an ADDBA Request to establish a block ack agreement with sta addressed by recipient for tid tid...
void SendDelbaFrame(Mac48Address addr, uint8_t tid, bool byOriginator)
Sends DELBA frame to cancel a block ack agreement with sta addressed by addr for tid tid...
Ptr< const Packet > PeekNextRetransmitPacket(WifiMacHeader &header, Mac48Address recipient, uint8_t tid, Time *timestamp)
Peek in retransmit queue and get the next packet without removing it from the queue.
Definition: edca-txop-n.cc:167
bool IsStrictlyPositive(void) const
Definition: nstime.h:294
uint16_t GetSequenceControl(void) const
Return the raw Sequence Control field.
void SetBlockAckThreshold(uint8_t threshold)
Set threshold for block ACK mechanism.
void SetMsduAggregator(const Ptr< MsduAggregator > aggr)
Set the aggregator used to construct A-MSDU subframes.
void MissedCts(void)
Event handler when a CTS timeout has occurred.
Definition: edca-txop-n.cc:440
void SetTypeOfStation(TypeOfStation type)
Set type of station with the given type.
Definition: edca-txop-n.cc:136
bool IsTxopFragmentation() const
Check if the current packet is fragmented because of an exceeded TXOP duration.
Definition: edca-txop-n.cc:995
std::string GetUniqueName(void) const
Definition: wifi-mode.cc:450
static Mac48Address GetBroadcast(void)
bool IsQosBlockAck(void) const
Return if the QoS ACK policy is Block ACK.
Headers for Block ack response.
Definition: ctrl-headers.h:190
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
Mac48Address GetAddress(void) const
Return the MAC address of this MacLow.
Definition: mac-low.cc:529
bool HasNextPacket(void) const
Definition: mac-low.cc:164
bool IsAccessRequested(void) const
Definition: dcf-state.cc:188
Ptr< Packet > GetFragmentPacket(WifiMacHeader *hdr)
Get the next fragment from the packet with appropriate Wifi header for the fragment.
Ptr< WifiRemoteStationManager > m_stationManager
the wifi remote station manager
Definition: dca-txop.h:416
virtual ~EdcaTxopN()
Definition: edca-txop-n.cc:87
uint32_t GetNRetryNeededPackets(Mac48Address recipient, uint8_t tid) const
Definition: edca-txop-n.cc:116
Time CalculateOverallTxFragmentTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters &params, uint32_t fragmentSize) const
Definition: mac-low.cc:1330
Time m_currentPacketTimestamp
the current packet timestamp
Definition: edca-txop-n.h:552
Mac48Address recipient
recipient
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:277
void SetByOriginator(void)
Set the initiator bit in the DELBA.
void SetTidInfo(uint8_t tid)
Set Traffic ID (TID).
uint16_t GetStartingSequence(void) const
Return the starting sequence number.
uint32_t GetFragmentOffset(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet, uint32_t fragmentNumber)
void SetByRecipient(void)
Un-set the initiator bit in the DELBA.
void EndTxNoAck(void)
Event handler when a transmission that does not require an ACK has completed.
Definition: edca-txop-n.cc:954
void StartBackoffNow(uint32_t nSlots)
Definition: dcf-state.cc:154
void SetNoRetry(void)
Un-set the Retry bit in the Frame Control field.
bool NeedFragmentation(void) const
Check if the current packet should be fragmented.
Definition: edca-txop-n.cc:971
void GotAck(void)
Event handler when an ACK is received.
Definition: edca-txop-n.cc:503
Ptr< UniformRandomVariable > m_rng
the random stream
Definition: dca-txop.h:417
Ptr< MpduAggregator > GetMpduAggregator(void) const
Returns the aggregator used to construct A-MPDU subframes.
Definition: edca-txop-n.cc:714
void EnableCompressedBlockAck(void)
Wait COMPRESSEDBLOCKACKTimeout for a Compressed Block Ack Response frame.
Definition: mac-low.cc:78
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< MsduAggregator > GetMsduAggregator(void) const
Returns the aggregator used to construct A-MSDU subframes.
Definition: edca-txop-n.cc:708
Bar m_currentBar
the current BAR
Definition: edca-txop-n.h:554
WifiMacHeader m_currentHdr
the current header
Definition: dca-txop.h:420
bool IsEdca()
Check for EDCA.
bool IsGroup(void) const
void EnableAck(void)
Wait ACKTimeout for an ACK.
Definition: mac-low.cc:93
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
TypeOfStation GetTypeOfStation(void) const
Return type of station.
Definition: edca-txop-n.cc:143
uint32_t GetFragmentSize(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet, uint32_t fragmentNumber)
uint8_t GetTid(void) const
Return the Traffic ID (TID).
Mac48Address MapDestAddressForAggregation(const WifiMacHeader &hdr)
This functions are used only to correctly set destination address in A-MSDU subframes.
bool SetupBlockAckIfNeeded()
If number of packets in the queue reaches m_blockAckThreshold value, an ADDBA Request frame is sent t...
bool GetBaAgreementExists(Mac48Address address, uint8_t tid) const
Definition: edca-txop-n.cc:104
StatusCode GetStatusCode(void) const
Return the status code.
an EUI-48 address
Definition: mac48-address.h:43
bool HasVhtSupported(void) const
Return whether the device has VHT capability support enabled.
bool IsByOriginator(void) const
Check if the initiator bit in the DELBA is setted.
uint8_t GetTid(Ptr< const Packet > packet, const WifiMacHeader hdr)
Extraction operator for TypeId.
Definition: qos-utils.cc:103
void SetAmpduExist(Mac48Address dest, bool enableAmpdu)
Set indication whether A-MPDU is used to transmit data to a peer station.
void BaTxOk(const WifiMacHeader &hdr)
The packet we sent was successfully received by the receiver.
void DisableRts(void)
Do not send rts and wait for cts before sending data.
Definition: mac-low.cc:108
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:249
Time m_startTxop
the start TXOP time
Definition: edca-txop-n.h:555
uint16_t PeekNextSequenceNumberFor(const WifiMacHeader *hdr)
Return the next sequence number for the Traffic ID and destination, but do not pick it (i...
uint32_t GetNextTxopFragmentSize(uint32_t fragmentNumber) const
Calculate the size of the next TXOP fragment.
bool GetAmpduExist(Mac48Address dest) const
Return whether A-MPDU is used to transmit data to a peer station.
Ptr< const Packet > m_currentPacket
the current packet
Definition: dca-txop.h:419
void GotBlockAck(const CtrlBAckResponseHeader *blockAck, Mac48Address recipient, double rxSnr, WifiMode txMode, double dataSnr)
Event handler when a Block ACK is received.
uint8_t GetTid(void) const
Return the Traffic ID (TID).
void FlushAggregateQueue(uint8_t tid)
This function is called to flush the aggregate queue, which is used for A-MPDU.
Definition: mac-low.cc:3009
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
void DoInitialize(void)
Initialize() implementation.
bool HasHtSupported(void) const
Return whether the device has HT capability support enabled.
Ptr< MacLow > GetLow(void) const
Return the MacLow associated with this DcaTxop.
Definition: dca-txop.cc:260
void PushFront(Ptr< const Packet > packet, const WifiMacHeader &hdr)
virtual WifiTxVector GetDataTxVector(Ptr< const Packet > packet, const WifiMacHeader *hdr) const
Return a TXVECTOR for the DATA frame given the destination.
Definition: mac-low.cc:1269
bool HasHeSupported(void) const
Return whether the device has HE capability support enabled.
static TypeId GetTypeId(void)
Get the type ID.
Definition: edca-txop-n.cc:44
void BaTxFailed(const WifiMacHeader &hdr)
The packet we sent was successfully received by the receiver.
bool MustSendHtImmediateAck(void) const
Check if the current ACK policy is immediate.
Time CalculateOverallTxTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters &params) const
Definition: mac-low.cc:1306
Ptr< MacTxMiddle > m_txMiddle
the MacTxMiddle
Definition: dca-txop.h:414
void SetSequenceNumber(uint16_t seq)
Set the sequence number of the header.
bool IsData(void) const
Return true if the Type is DATA.
Ptr< QosBlockedDestinations > m_qosBlockedDestinations
QOS blocked destinations.
Definition: edca-txop-n.h:548
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS DATA...
void CompleteConfig(void)
Complete block ACK configuration.
uint32_t GetCw(void) const
Definition: dcf-state.cc:170
BlockAckActionValue blockAck
block ack
Definition: mgt-headers.h:701
void Unblock(Mac48Address dest, uint8_t tid)
Un-block the given destination address and TID (e.g.
bool IsBlockAckReq(void) const
Return true if the header is a Block ACK Request header.
BlockAckType m_blockAckType
the Block ACK type
Definition: edca-txop-n.h:551
void RestartAccessIfNeeded(void)
Restart access request if needed.
Definition: edca-txop-n.cc:720
Implement the header for management frames of type add block ack response.
Definition: mgt-headers.h:890
Implement the header for management frames of type del block ack.
Definition: mgt-headers.h:1011
void CompleteAmpduTransfer(Mac48Address recipient, uint8_t tid)
Definition: edca-txop-n.cc:122
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:269
WifiMacType GetType(void) const
Return the type (enum WifiMacType)
typedef for union of different ActionValues
Definition: mgt-headers.h:696
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:993
Ptr< const Packet > bar
block ack request
uint8_t GetBlockAckThreshold(void) const
Return the current threshold for block ACK mechanism.
void CompleteTx(void)
For now is typically invoked to complete transmission of a packets sent with ack policy Block Ack: th...
bool IsSuccess(void) const
Return whether the status code is success.
Definition: status-code.cc:42
bool NeedFragmentation(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet)
virtual void DoDispose(void)
Destructor implementation.
Definition: dca-txop.cc:89
void RequestAccess(Ptr< DcfState > state)
Definition: dcf-manager.cc:292
bool IsStrictlyNegative(void) const
Definition: nstime.h:289
void EnableNextData(uint32_t size)
Definition: mac-low.cc:48
void DisableOverrideDurationId(void)
Do not force the duration/id field of the packet: its value is automatically calculated by the MacLow...
Definition: mac-low.cc:63
bool IsLastFragment(void) const
Check if the current fragment is the last fragment.
void Block(Mac48Address dest, uint8_t tid)
Block the given destination address and TID from sending (e.g.
void DisableNextData(void)
Do not attempt to send data burst after current transmission.
Definition: mac-low.cc:53
uint16_t PeekNextSequenceNumberFor(WifiMacHeader *hdr)
Return the next sequence number for the Traffic ID and destination, but do not pick it (i...
Definition: edca-txop-n.cc:161
virtual uint32_t GetMaxAmpduSize(void) const =0
Returns the maximum A-MPDU size in bytes.
void StartAccessIfNeeded(void)
Request access from DCF manager if needed.
Definition: edca-txop-n.cc:761
bool m_currentIsFragmented
flag whether current packet is fragmented
Definition: edca-txop-n.h:557
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
void ReportAmpduTxStatus(Mac48Address address, uint8_t tid, uint8_t nSuccessfulMpdus, uint8_t nFailedMpdus, double rxSnr, double dataSnr)
Typically called per A-MPDU, either when a Block ACK was successfully received or when a BlockAckTime...
tuple address
Definition: first.py:37
TypeOfStation
Enumeration for type of station.
Definition: edca-txop-n.h:44
Ptr< BlockAckManager > m_baManager
the Block ACK manager
Definition: edca-txop-n.h:549
void UpdateFailedCw(void)
Update the value of the CW variable to take into account a transmission failure.
Definition: dcf-state.cc:137
virtual bool Aggregate(Ptr< const Packet > packet, Ptr< Packet > aggregatedPacket, Mac48Address src, Mac48Address dest) const =0
Adds packet to aggregatedPacket.
ActionValue GetAction()
Return the action value.
Definition: mgt-headers.cc:909
Headers for Block ack request.
Definition: ctrl-headers.h:50
handle packet fragmentation and retransmissions.
Definition: dca-txop.h:58
uint32_t GetNOutstandingPacketsInBa(Mac48Address address, uint8_t tid) const
Definition: edca-txop-n.cc:110
void SetFragmentNumber(uint8_t frag)
Set the fragment number of the header.
void DisableAck(void)
Do not wait for Ack after data transmission.
Definition: mac-low.cc:98
void SetAction(CategoryValue type, ActionValue action)
Set action for this Action header.
Definition: mgt-headers.cc:854
uint16_t GetNextSeqNumberByTidAndAddress(uint8_t tid, Mac48Address addr) const
Return the next sequence number for the Traffic ID and destination.
a unique identifier for an interface.
Definition: type-id.h:58
void ReportFinalRtsFailed(Mac48Address address, const WifiMacHeader *header)
Should be invoked after calling ReportRtsFailed if NeedRtsRetransmission returns false.
void SetStartingSequence(uint16_t seq)
Set the starting sequence number from the given raw sequence control field.
bool NeedsAccess(void) const
Check if the EDCAF requires access.
Definition: edca-txop-n.cc:150
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:914
void SetQosAmsdu(void)
Set that A-MSDU is present.
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:38
void SetMpduAggregator(const Ptr< MpduAggregator > aggr)
Set the aggregator used to construct A-MPDU subframes.
bool IsRetry(void) const
Return if the Retry bit is set.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
Implements the IEEE 802.11 MAC header.
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
void GotAddBaResponse(const MgtAddBaResponseHeader *respHdr, Mac48Address recipient)
Event handler when an ADDBA response is received.
Implements the IEEE 802.11 MAC trailer.
virtual void SetWifiRemoteStationManager(const Ptr< WifiRemoteStationManager > remoteManager)
Set WifiRemoteStationsManager this DcaTxop is associated to.
Definition: dca-txop.cc:122
TypeOfStation m_typeOfStation
the type of station
Definition: edca-txop-n.h:547
Mac48Address MapSrcAddressForAggregation(const WifiMacHeader &hdr)
This functions are used only to correctly set source address in A-MSDU subframes. ...
void RegisterEdcaForAc(AcIndex ac, Ptr< EdcaTxopN > edca)
Definition: mac-low.cc:2566
TxFailed m_txFailedCallback
the transmit failed callback
Definition: dca-txop.h:411
Ptr< DcfManager > m_manager
the DCF manager
Definition: dca-txop.h:409
void SetDsNotFrom(void)
Un-set the From DS bit in the Frame Control field.
uint16_t GetNextSequenceNumberFor(WifiMacHeader *hdr)
Return the next sequence number for the given header.
Definition: edca-txop-n.cc:156
uint16_t GetSequenceNumber(void) const
Return the sequence number of the header.
void SetQosAckPolicy(QosAckPolicy policy)
Set the QoS ACK policy in the QoS control field.