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::TracedValueCallback::Uint32")
54  .AddTraceSource ("CwTrace",
55  "Trace source for contention window values",
57  "ns3::TracedValueCallback::Uint32")
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 void
111 {
112  m_baManager->CompleteAmpduExchange (recipient, tid);
113 }
114 
115 void
117 {
118  DcaTxop::SetWifiRemoteStationManager (remoteManager);
119  NS_LOG_FUNCTION (this << remoteManager);
120  m_baManager->SetWifiRemoteStationManager (m_stationManager);
121 }
122 
123 void
125 {
126  NS_LOG_FUNCTION (this << +type);
127  m_typeOfStation = type;
128 }
129 
132 {
133  NS_LOG_FUNCTION (this);
134  return m_typeOfStation;
135 }
136 
138 {
139  return m_txMiddle->GetNextSequenceNumberFor (hdr);
140 }
141 
143 {
145 }
146 
148 EdcaTxopN::PeekNextRetransmitPacket (WifiMacHeader &header, Mac48Address recipient, uint8_t tid, Time *timestamp)
149 {
150  return m_baManager->PeekNextPacketByTidAndAddress (header, recipient, tid, timestamp);
151 }
152 
153 void
154 EdcaTxopN::RemoveRetransmitPacket (uint8_t tid, Mac48Address recipient, uint16_t seqnumber)
155 {
156  m_baManager->RemovePacket (tid, recipient, seqnumber);
157 }
158 
159 void
161 {
162  NS_LOG_FUNCTION (this);
165  if (m_currentPacket == 0)
166  {
167  if (m_queue->IsEmpty () && !m_baManager->HasPackets ())
168  {
169  NS_LOG_DEBUG ("queue is empty");
170  return;
171  }
172  if (m_baManager->HasBar (m_currentBar))
173  {
175  return;
176  }
177  /* check if packets need retransmission are stored in BlockAckManager */
178  m_currentPacket = m_baManager->GetNextPacket (m_currentHdr, true);
179  if (m_currentPacket == 0)
180  {
181  Ptr<const WifiMacQueueItem> item = m_queue->PeekFirstAvailable (m_qosBlockedDestinations);
182  if (item == 0)
183  {
184  NS_LOG_DEBUG ("no available packets in the queue");
185  return;
186  }
187  m_currentHdr = item->GetHeader ();
188  m_currentPacketTimestamp = item->GetTimeStamp ();
191  && !m_baManager->ExistsAgreement (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ())
192  && SetupBlockAckIfNeeded ())
193  {
194  return;
195  }
196  item = m_queue->DequeueFirstAvailable (m_qosBlockedDestinations);
197  m_currentPacket = item->GetPacket ();
198  m_currentHdr = item->GetHeader ();
199  m_currentPacketTimestamp = item->GetTimeStamp ();
200  NS_ASSERT (m_currentPacket != 0);
201 
202  uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&m_currentHdr);
203  m_currentHdr.SetSequenceNumber (sequence);
208  m_fragmentNumber = 0;
209  NS_LOG_DEBUG ("dequeued size=" << m_currentPacket->GetSize () <<
210  ", to=" << m_currentHdr.GetAddr1 () <<
211  ", seq=" << m_currentHdr.GetSequenceControl ());
213  {
214  VerifyBlockAck ();
215  }
216  }
217  }
218  if (m_currentHdr.GetAddr1 ().IsGroup ())
219  {
223  NS_LOG_DEBUG ("tx broadcast");
225  }
227  {
229  }
230  else
231  {
233  {
235  }
236  else
237  {
239  }
240  //With COMPRESSED_BLOCK_ACK fragmentation must be avoided.
242  || (m_currentHdr.IsData () && !m_currentHdr.IsQosData ()))
244  && NeedFragmentation ())
245  {
246  m_currentIsFragmented = true;
248  WifiMacHeader hdr;
249  Ptr<Packet> fragment = GetFragmentPacket (&hdr);
250  if (IsLastFragment ())
251  {
252  NS_LOG_DEBUG ("fragmenting last fragment size=" << fragment->GetSize ());
254  }
255  else
256  {
257  NS_LOG_DEBUG ("fragmenting size=" << fragment->GetSize ());
259  }
260  m_low->StartTransmission (fragment, &hdr, m_currentParams, this);
261  }
262  else
263  {
264  m_currentIsFragmented = false;
265  WifiMacHeader peekedHdr;
267  if (m_currentHdr.IsQosData ()
268  && (item = m_queue->PeekByTidAndAddress (m_currentHdr.GetQosTid (),
271  && m_msduAggregator != 0 && !m_currentHdr.IsRetry ())
272  {
273  peekedHdr = item->GetHeader ();
274  /* here is performed aggregation */
275  Ptr<Packet> currentAggregatedPacket = Create<Packet> ();
276  m_msduAggregator->Aggregate (m_currentPacket, currentAggregatedPacket,
277  MapSrcAddressForAggregation (peekedHdr),
278  MapDestAddressForAggregation (peekedHdr));
279  bool aggregated = false;
280  bool isAmsdu = false;
281  Ptr<const WifiMacQueueItem> peekedItem = m_queue->PeekByTidAndAddress (m_currentHdr.GetQosTid (),
284  while (peekedItem != 0)
285  {
286  peekedHdr = peekedItem->GetHeader ();
287  aggregated = m_msduAggregator->Aggregate (peekedItem->GetPacket (), currentAggregatedPacket,
288  MapSrcAddressForAggregation (peekedHdr),
289  MapDestAddressForAggregation (peekedHdr));
290  if (aggregated)
291  {
292  isAmsdu = true;
293  m_queue->Remove (peekedItem->GetPacket ());
294  }
295  else
296  {
297  break;
298  }
299  peekedItem = m_queue->PeekByTidAndAddress (m_currentHdr.GetQosTid (),
301  }
302  if (isAmsdu)
303  {
306  m_currentPacket = currentAggregatedPacket;
307  currentAggregatedPacket = 0;
308  NS_LOG_DEBUG ("tx unicast A-MSDU");
309  }
310  }
314  {
315  CompleteTx ();
316  }
317  }
318  }
319 }
320 
322 {
323  NS_LOG_FUNCTION (this);
324  bool resetDcf = false;
325  // If an internal collision is experienced, the frame involved may still
326  // be sitting in the queue, and m_currentPacket may still be null.
327  Ptr<const Packet> packet;
328  WifiMacHeader header;
329  if (m_currentPacket == 0)
330  {
331  if (m_baManager->HasPackets ())
332  {
333  packet = m_baManager->GetNextPacket (header, false);
334  }
335  else
336  {
337  Ptr<const WifiMacQueueItem> item = m_queue->Peek ();
338  if (item)
339  {
340  packet = item->GetPacket ();
341  header = item->GetHeader ();
342  }
343  }
344  }
345  else
346  {
347  packet = m_currentPacket;
348  header = m_currentHdr;
349  }
350  if (packet != 0)
351  {
353  {
354  if (!NeedRtsRetransmission (packet, header))
355  {
356  resetDcf = true;
357  m_stationManager->ReportFinalRtsFailed (header.GetAddr1 (), &header);
358  }
359  else
360  {
361  m_stationManager->ReportRtsFailed (header.GetAddr1 (), &header);
362  }
363  }
364  else if (header.GetAddr1 () == Mac48Address::GetBroadcast ())
365  {
366  resetDcf = false;
367  }
368  else
369  {
370  if (!NeedDataRetransmission (packet, header))
371  {
372  resetDcf = true;
373  m_stationManager->ReportFinalDataFailed (header.GetAddr1 (), &header);
374  }
375  else
376  {
377  m_stationManager->ReportDataFailed (header.GetAddr1 (), &header);
378  }
379  }
380  if (resetDcf)
381  {
382  NS_LOG_DEBUG ("reset DCF");
383  if (!m_txFailedCallback.IsNull ())
384  {
385  m_txFailedCallback (header);
386  }
387  //to reset the dcf.
388  if (m_currentPacket)
389  {
390  NS_LOG_DEBUG ("Discarding m_currentPacket");
391  m_currentPacket = 0;
392  }
393  else
394  {
395  NS_LOG_DEBUG ("Dequeueing and discarding head of queue");
396  m_queue->Remove ();
397  }
398  m_dcf->ResetCw ();
399  }
400  else
401  {
402  m_dcf->UpdateFailedCw ();
403  }
404  }
408 }
409 
410 void
412 {
413  NS_LOG_FUNCTION (this);
417 }
418 
419 void
421 {
422  NS_LOG_FUNCTION (this);
423  NS_LOG_DEBUG ("missed cts");
425  {
426  NS_LOG_DEBUG ("Cts Fail");
427  bool resetCurrentPacket = true;
429  if (!m_txFailedCallback.IsNull ())
430  {
432  }
434  {
435  uint8_t tid = GetTid (m_currentPacket, m_currentHdr);
436  m_low->FlushAggregateQueue (tid);
437 
439  {
440  NS_LOG_DEBUG ("Transmit Block Ack Request");
441  CtrlBAckRequestHeader reqHdr;
442  reqHdr.SetType (COMPRESSED_BLOCK_ACK);
444  reqHdr.SetTidInfo (tid);
445  reqHdr.SetHtImmediateAck (true);
446  Ptr<Packet> bar = Create<Packet> ();
447  bar->AddHeader (reqHdr);
448  Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ());
449  m_currentBar = request;
450  WifiMacHeader hdr;
452  hdr.SetAddr1 (request.recipient);
453  hdr.SetAddr2 (m_low->GetAddress ());
454  hdr.SetAddr3 (m_low->GetBssid ());
455  hdr.SetDsNotTo ();
456  hdr.SetDsNotFrom ();
457  hdr.SetNoRetry ();
458  hdr.SetNoMoreFragments ();
459  m_currentPacket = request.bar;
460  m_currentHdr = hdr;
461  resetCurrentPacket = false;
462  }
463  }
464  //to reset the dcf.
465  if (resetCurrentPacket == true)
466  {
467  m_currentPacket = 0;
468  }
469  m_dcf->ResetCw ();
470  m_cwTrace = m_dcf->GetCw ();
471  }
472  else
473  {
474  m_dcf->UpdateFailedCw ();
475  m_cwTrace = m_dcf->GetCw ();
476  }
480 }
481 
482 void
484 {
485  NS_LOG_FUNCTION (this);
488  || m_currentHdr.IsQosAmsdu ())
489  {
490  NS_LOG_DEBUG ("got ack. tx done.");
491  if (!m_txOkCallback.IsNull ())
492  {
494  }
495 
496  if (m_currentHdr.IsAction ())
497  {
498  WifiActionHeader actionHdr;
500  p->RemoveHeader (actionHdr);
501  if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK
503  {
504  MgtDelBaHeader delBa;
505  p->PeekHeader (delBa);
506  if (delBa.IsByOriginator ())
507  {
508  m_baManager->DestroyAgreement (m_currentHdr.GetAddr1 (), delBa.GetTid ());
509  }
510  else
511  {
513  }
514  }
515  }
516  m_currentPacket = 0;
517  m_dcf->ResetCw ();
518  if (!HasTxop ())
519  {
521  {
523  }
524  m_cwTrace = m_dcf->GetCw ();
528  }
529  }
530  else
531  {
532  NS_LOG_DEBUG ("got ack. tx not done, size=" << m_currentPacket->GetSize ());
533  if (!HasTxop ())
534  {
536  {
538  m_cwTrace = m_dcf->GetCw ();
543  }
544  }
545  }
546 }
547 
548 void
550 {
551  NS_LOG_FUNCTION (this);
552  NS_LOG_DEBUG ("missed ack");
554  {
555  NS_LOG_DEBUG ("Ack Fail");
557  bool resetCurrentPacket = true;
558  if (!m_txFailedCallback.IsNull ())
559  {
561  }
563  {
564  uint8_t tid = GetTid (m_currentPacket, m_currentHdr);
565 
567  {
568  //send Block ACK Request in order to shift WinStart at the receiver
569  NS_LOG_DEBUG ("Transmit Block Ack Request");
570  CtrlBAckRequestHeader reqHdr;
571  reqHdr.SetType (COMPRESSED_BLOCK_ACK);
573  reqHdr.SetTidInfo (tid);
574  reqHdr.SetHtImmediateAck (true);
575  Ptr<Packet> bar = Create<Packet> ();
576  bar->AddHeader (reqHdr);
577  Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ());
578  m_currentBar = request;
579  WifiMacHeader hdr;
581  hdr.SetAddr1 (request.recipient);
582  hdr.SetAddr2 (m_low->GetAddress ());
583  hdr.SetAddr3 (m_low->GetBssid ());
584  hdr.SetDsNotTo ();
585  hdr.SetDsNotFrom ();
586  hdr.SetNoRetry ();
587  hdr.SetNoMoreFragments ();
588  m_currentPacket = request.bar;
589  m_currentHdr = hdr;
590  resetCurrentPacket = false;
591  }
592  }
593  //to reset the dcf.
594  if (resetCurrentPacket == true)
595  {
596  m_currentPacket = 0;
597  }
598  m_dcf->ResetCw ();
599  m_cwTrace = m_dcf->GetCw ();
600  }
601  else
602  {
603  NS_LOG_DEBUG ("Retransmit");
605  m_dcf->UpdateFailedCw ();
606  m_cwTrace = m_dcf->GetCw ();
607  }
611 }
612 
613 void
615 {
616  NS_LOG_FUNCTION (this << +nMpdus);
617  uint8_t tid = GetTid (m_currentPacket, m_currentHdr);
619  {
620  m_stationManager->ReportAmpduTxStatus (m_currentHdr.GetAddr1 (), tid, 0, nMpdus, 0, 0);
621  }
622  if (NeedBarRetransmission ())
623  {
625  {
626  //should i report this to station addressed by ADDR1?
627  NS_LOG_DEBUG ("Retransmit block ack request");
629  }
630  else
631  {
632  //standard says when loosing a BlockAck originator may send a BAR page 139
633  NS_LOG_DEBUG ("Transmit Block Ack Request");
634  CtrlBAckRequestHeader reqHdr;
635  reqHdr.SetType (COMPRESSED_BLOCK_ACK);
636  if (m_currentHdr.IsQosData ())
637  {
639  }
640  else if (m_currentHdr.IsBlockAckReq ())
641  {
642  CtrlBAckRequestHeader baReqHdr;
643  m_currentPacket->PeekHeader (baReqHdr);
644  reqHdr.SetStartingSequence (baReqHdr.GetStartingSequence ());
645  }
646  else if (m_currentHdr.IsBlockAck ())
647  {
648  CtrlBAckResponseHeader baRespHdr;
649  m_currentPacket->PeekHeader (baRespHdr);
651  }
652  reqHdr.SetTidInfo (tid);
653  reqHdr.SetHtImmediateAck (true);
654  Ptr<Packet> bar = Create<Packet> ();
655  bar->AddHeader (reqHdr);
656  Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ());
657  m_currentBar = request;
658  WifiMacHeader hdr;
660  hdr.SetAddr1 (request.recipient);
661  hdr.SetAddr2 (m_low->GetAddress ());
662  hdr.SetAddr3 (m_low->GetBssid ());
663  hdr.SetDsNotTo ();
664  hdr.SetDsNotFrom ();
665  hdr.SetNoRetry ();
666  hdr.SetNoMoreFragments ();
667 
668  m_currentPacket = request.bar;
669  m_currentHdr = hdr;
670  }
671  m_dcf->UpdateFailedCw ();
672  m_cwTrace = m_dcf->GetCw ();
673  }
674  else
675  {
676  NS_LOG_DEBUG ("Block Ack Request Fail");
677  //to reset the dcf.
678  m_currentPacket = 0;
679  m_dcf->ResetCw ();
680  m_cwTrace = m_dcf->GetCw ();
681  }
685 }
686 
689 {
690  return m_msduAggregator;
691 }
692 
695 {
696  return m_mpduAggregator;
697 }
698 
699 void
701 {
702  NS_LOG_FUNCTION (this);
703  if ((m_currentPacket != 0
704  || !m_queue->IsEmpty () || m_baManager->HasPackets ())
705  && !m_dcf->IsAccessRequested ())
706  {
707  Ptr<const Packet> packet;
708  WifiMacHeader hdr;
709  if (m_currentPacket != 0)
710  {
711  packet = m_currentPacket;
712  hdr = m_currentHdr;
713  }
714  else if (m_baManager->HasPackets ())
715  {
716  packet = m_baManager->GetNextPacket (hdr, false);
717  }
718  else
719  {
720  Ptr<const WifiMacQueueItem> item = m_queue->PeekFirstAvailable (m_qosBlockedDestinations);
721  if (item)
722  {
723  packet = item->GetPacket ();
724  hdr = item->GetHeader ();
725  m_currentPacketTimestamp = item->GetTimeStamp ();
726  }
727  }
728  if (packet != 0)
729  {
730  m_isAccessRequestedForRts = m_stationManager->NeedRts (hdr.GetAddr1 (), &hdr, packet, m_low->GetDataTxVector (packet, &hdr));
731  }
732  else
733  {
735  }
737  }
738 }
739 
740 void
742 {
743  //NS_LOG_FUNCTION (this);
744  if (m_currentPacket == 0
745  && (!m_queue->IsEmpty () || m_baManager->HasPackets ())
746  && !m_dcf->IsAccessRequested ())
747  {
748  Ptr<const Packet> packet;
749  WifiMacHeader hdr;
750  if (m_baManager->HasPackets ())
751  {
752  packet = m_baManager->GetNextPacket (hdr, false);
753  }
754  else
755  {
756  Ptr<const WifiMacQueueItem> item = m_queue->PeekFirstAvailable (m_qosBlockedDestinations);
757  if (item)
758  {
759  packet = item->GetPacket ();
760  hdr = item->GetHeader ();
761  m_currentPacketTimestamp = item->GetTimeStamp ();
762  }
763  }
764  if (packet != 0)
765  {
766  m_isAccessRequestedForRts = m_stationManager->NeedRts (hdr.GetAddr1 (), &hdr, packet, m_low->GetDataTxVector (packet, &hdr));
767  }
768  else
769  {
771  }
773  }
774 }
775 
776 bool
778 {
779  uint8_t tid = 0;
780  uint16_t seqNumber = 0;
781  if (m_currentHdr.IsQosData ())
782  {
783  tid = m_currentHdr.GetQosTid ();
784  seqNumber = m_currentHdr.GetSequenceNumber ();
785  }
786  else if (m_currentHdr.IsBlockAckReq ())
787  {
788  CtrlBAckRequestHeader baReqHdr;
789  m_currentPacket->PeekHeader (baReqHdr);
790  tid = baReqHdr.GetTidInfo ();
791  seqNumber = baReqHdr.GetStartingSequence ();
792  }
793  else if (m_currentHdr.IsBlockAck ())
794  {
795  CtrlBAckResponseHeader baRespHdr;
796  m_currentPacket->PeekHeader (baRespHdr);
797  tid = baRespHdr.GetTidInfo ();
798  seqNumber = m_currentHdr.GetSequenceNumber ();
799  }
800  return m_baManager->NeedBarRetransmission (tid, seqNumber, m_currentHdr.GetAddr1 ());
801 }
802 
803 void
805 {
806  NS_LOG_FUNCTION (this);
807  Time txopLimit = GetTxopLimit ();
808  NS_ASSERT (txopLimit.IsZero () || Simulator::Now () - m_startTxop <= txopLimit);
810  Ptr<const Packet> peekedPacket = m_baManager->GetNextPacket (hdr, true);
811  if (peekedPacket == 0)
812  {
813  Ptr<const WifiMacQueueItem> peekedItem = m_queue->PeekByTidAndAddress (m_currentHdr.GetQosTid (),
816  if (peekedItem)
817  {
818  peekedPacket = peekedItem->GetPacket ();
819  hdr = peekedItem->GetHeader ();
820  }
821  }
822  if ((m_currentHdr.IsQosBlockAck () && peekedPacket == 0) || m_baManager->HasBar (m_currentBar))
823  {
825  return;
826  }
827  else if (peekedPacket == 0)
828  {
829  if (txopLimit.IsStrictlyPositive ())
830  {
831  NS_ASSERT (Simulator::Now () - m_startTxop <= txopLimit);
833  }
834  return;
835  }
838  {
840  }
841  else
842  {
844  }
845  if (txopLimit >= GetLow ()->CalculateOverallTxTime (peekedPacket, &hdr, m_currentParams))
846  {
847  NS_LOG_DEBUG ("start next packet");
848  Ptr<WifiMacQueueItem> item = m_queue->DequeueByTidAndAddress (m_currentHdr.GetQosTid (),
851  NS_ASSERT (item != 0);
852  m_currentPacket = item->GetPacket ();
853  m_currentHdr = item->GetHeader ();
854  NS_ASSERT (m_currentPacket != 0);
855  uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&m_currentHdr);
856  m_currentHdr.SetSequenceNumber (sequence);
861  m_fragmentNumber = 0;
862  VerifyBlockAck ();
865  {
866  CompleteTx ();
867  }
868  }
869  else if (txopLimit.IsStrictlyPositive ())
870  {
872  }
873 }
874 
875 Time
877 {
878  Time remainingTxop = GetTxopLimit ();
879  remainingTxop -= (Simulator::Now () - m_startTxop);
880  if (remainingTxop.IsStrictlyNegative ())
881  {
882  remainingTxop = Seconds (0);
883  }
884  NS_LOG_FUNCTION (this << remainingTxop);
885  return remainingTxop;
886 }
887 
888 bool
889 EdcaTxopN::HasTxop (void) const
890 {
891  NS_LOG_FUNCTION (this);
892  WifiMacHeader hdr;
893  if (!m_currentHdr.IsQosData () || GetTxopLimit ().IsZero ())
894  {
895  return false;
896  }
897 
898  Ptr<const WifiMacQueueItem> peekedItem = m_queue->PeekByTidAndAddress (m_currentHdr.GetQosTid (),
901  if (peekedItem == 0)
902  {
903  return false;
904  }
905 
906  Ptr<const Packet> peekedPacket = peekedItem->GetPacket ();
907  hdr = peekedItem->GetHeader ();
910  {
911  params.DisableAck ();
912  }
913  else
914  {
915  params.EnableAck ();
916  }
917 
918  Time duration = GetLow ()->CalculateOverallTxTime (peekedPacket, &hdr, params);
919  if (m_currentPacket != 0)
920  {
921  //take into account current transmission in duration
922  duration += GetLow ()->CalculateOverallTxTime (m_currentPacket, &m_currentHdr, params);
923  }
924  return (GetTxopRemaining () >= duration);
925 }
926 
927 void
929 {
930  NS_LOG_FUNCTION (this);
931  NS_LOG_DEBUG ("a transmission that did not require an ACK just finished");
933  {
935  }
936  m_currentPacket = 0;
937  m_dcf->ResetCw ();
938  m_cwTrace = m_dcf->GetCw ();
942 }
943 
944 bool
946 {
947  NS_LOG_FUNCTION (this);
952  && m_currentHdr.IsQosData ()
955  {
956  //MSDU is not fragmented when it is transmitted using an HT-immediate or
957  //HT-delayed Block Ack agreement or when it is carried in an A-MPDU.
958  return false;
959  }
960  bool needTxopFragmentation = false;
962  {
964  }
965  return (needTxopFragmentation || m_stationManager->NeedFragmentation (m_currentHdr.GetAddr1 (), &m_currentHdr, m_currentPacket));
966 }
967 
968 bool
970 {
971  if (GetTxopLimit ().IsZero ())
972  {
973  return false;
974  }
977  {
978  return true;
979  }
980  return false;
981 }
982 
983 uint32_t
985 {
986  Time txopDuration = GetTxopLimit ();
987  if (txopDuration.IsZero ())
988  {
989  return 0;
990  }
991  uint32_t maxSize = m_currentPacket->GetSize ();
992  uint32_t minSize = 0;
993  uint32_t size = 0;
994  bool found = false;
995  while (!found)
996  {
997  size = (minSize + ((maxSize - minSize) / 2));
999  {
1000  maxSize = size;
1001  }
1002  else
1003  {
1004  minSize = size;
1005  }
1006  if (GetLow ()->CalculateOverallTxTime (m_currentPacket, &m_currentHdr, m_currentParams, size) <= txopDuration
1007  && GetLow ()->CalculateOverallTxTime (m_currentPacket, &m_currentHdr, m_currentParams, size + 1) > txopDuration)
1008  {
1009  found = true;
1010  }
1011  }
1012  NS_ASSERT (size != 0);
1013  return size;
1014 }
1015 
1016 uint32_t
1018 {
1019  uint32_t fragmentSize = GetTxopFragmentSize ();
1020  uint32_t nFragments = (m_currentPacket->GetSize () / fragmentSize);
1021  if ((m_currentPacket->GetSize () % fragmentSize) > 0)
1022  {
1023  nFragments++;
1024  }
1025  NS_LOG_DEBUG ("GetNTxopFragment returning " << nFragments);
1026  return nFragments;
1027 }
1028 
1029 uint32_t
1030 EdcaTxopN::GetTxopFragmentOffset (uint32_t fragmentNumber) const
1031 {
1032  if (fragmentNumber == 0)
1033  {
1034  return 0;
1035  }
1036  uint32_t offset = 0;
1037  uint32_t fragmentSize = GetTxopFragmentSize ();
1038  uint32_t nFragments = (m_currentPacket->GetSize () / fragmentSize);
1039  if ((m_currentPacket->GetSize () % fragmentSize) > 0)
1040  {
1041  nFragments++;
1042  }
1043  if (fragmentNumber < nFragments)
1044  {
1045  offset = (fragmentNumber * fragmentSize);
1046  }
1047  else
1048  {
1049  NS_ASSERT (false);
1050  }
1051  NS_LOG_DEBUG ("GetTxopFragmentOffset returning " << offset);
1052  return offset;
1053 }
1054 
1055 uint32_t
1056 EdcaTxopN::GetNextTxopFragmentSize (uint32_t fragmentNumber) const
1057 {
1058  NS_LOG_FUNCTION (this << fragmentNumber);
1059  uint32_t fragmentSize = GetTxopFragmentSize ();
1060  uint32_t nFragments = GetNTxopFragment ();
1061  if (fragmentNumber >= nFragments)
1062  {
1063  NS_LOG_DEBUG ("GetNextTxopFragmentSize returning 0");
1064  return 0;
1065  }
1066  if (fragmentNumber == nFragments - 1)
1067  {
1068  fragmentSize = (m_currentPacket->GetSize () - ((nFragments - 1) * fragmentSize));
1069  }
1070  NS_LOG_DEBUG ("GetNextTxopFragmentSize returning " << fragmentSize);
1071  return fragmentSize;
1072 }
1073 
1074 uint32_t
1076 {
1077  uint32_t size;
1078  if (IsTxopFragmentation ())
1079  {
1081  }
1082  else
1083  {
1085  }
1086  return size;
1087 }
1088 
1089 uint32_t
1091 {
1092  uint32_t size;
1093  if (IsTxopFragmentation ())
1094  {
1096  }
1097  else
1098  {
1100  }
1101  return size;
1102 }
1103 
1104 uint32_t
1106 {
1107  uint32_t offset;
1108  if (IsTxopFragmentation ())
1109  {
1111  }
1112  else
1113  {
1116  }
1117  return offset;
1118 }
1119 
1120 bool
1122 {
1123  bool isLastFragment;
1124  if (IsTxopFragmentation ())
1125  {
1126  isLastFragment = (m_fragmentNumber == GetNTxopFragment () - 1);
1127  }
1128  else
1129  {
1132  }
1133  return isLastFragment;
1134 }
1135 
1138 {
1139  NS_LOG_FUNCTION (this << hdr);
1140  *hdr = m_currentHdr;
1142  uint32_t startOffset = GetFragmentOffset ();
1143  Ptr<Packet> fragment;
1144  if (IsLastFragment ())
1145  {
1146  hdr->SetNoMoreFragments ();
1147  }
1148  else
1149  {
1150  hdr->SetMoreFragments ();
1151  }
1152  fragment = m_currentPacket->CreateFragment (startOffset,
1153  GetFragmentSize ());
1154  return fragment;
1155 }
1156 
1157 void
1159 {
1160  NS_LOG_FUNCTION (this << +ac);
1161  m_ac = ac;
1162 }
1163 
1166 {
1167  NS_LOG_FUNCTION (this << &hdr);
1168  Mac48Address retval;
1170  {
1171  retval = hdr.GetAddr2 ();
1172  }
1173  else
1174  {
1175  retval = hdr.GetAddr3 ();
1176  }
1177  return retval;
1178 }
1179 
1182 {
1183  NS_LOG_FUNCTION (this << &hdr);
1184  Mac48Address retval;
1186  {
1187  retval = hdr.GetAddr1 ();
1188  }
1189  else
1190  {
1191  retval = hdr.GetAddr3 ();
1192  }
1193  return retval;
1194 }
1195 
1196 void
1198 {
1199  NS_LOG_FUNCTION (this << aggr);
1200  m_msduAggregator = aggr;
1201 }
1202 
1203 void
1205 {
1206  NS_LOG_FUNCTION (this << aggr);
1207  m_mpduAggregator = aggr;
1208 }
1209 
1210 void
1212 {
1213  NS_LOG_FUNCTION (this << packet << &hdr);
1214  WifiMacTrailer fcs;
1215  m_stationManager->PrepareForQueue (hdr.GetAddr1 (), &hdr, packet);
1216  m_queue->PushFront (Create<WifiMacQueueItem> (packet, hdr));
1218 }
1219 
1220 void
1222 {
1223  NS_LOG_FUNCTION (this << respHdr << recipient);
1224  NS_LOG_DEBUG ("received ADDBA response from " << recipient);
1225  uint8_t tid = respHdr->GetTid ();
1226  if (m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::PENDING))
1227  {
1228  if (respHdr->GetStatusCode ().IsSuccess ())
1229  {
1230  NS_LOG_DEBUG ("block ack agreement established with " << recipient);
1231  m_baManager->UpdateAgreement (respHdr, recipient);
1232  }
1233  else
1234  {
1235  NS_LOG_DEBUG ("discard ADDBA response" << recipient);
1236  m_baManager->NotifyAgreementUnsuccessful (recipient, tid);
1237  }
1238  }
1240 }
1241 
1242 void
1244 {
1245  NS_LOG_FUNCTION (this << delBaHdr << recipient);
1246  NS_LOG_DEBUG ("received DELBA frame from=" << recipient);
1247  m_baManager->DestroyAgreement (recipient, delBaHdr->GetTid ());
1248 }
1249 
1250 void
1251 EdcaTxopN::GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address recipient, double rxSnr, WifiMode txMode, double dataSnr)
1252 {
1253  NS_LOG_FUNCTION (this << blockAck << recipient << rxSnr << txMode.GetUniqueName () << dataSnr);
1254  NS_LOG_DEBUG ("got block ack from=" << recipient);
1255  m_baManager->NotifyGotBlockAck (blockAck, recipient, rxSnr, txMode, dataSnr);
1256  if (!m_txOkCallback.IsNull ())
1257  {
1259  }
1260  m_currentPacket = 0;
1261  m_dcf->ResetCw ();
1262  if (!HasTxop ())
1263  {
1265  {
1267  }
1268  m_cwTrace = m_dcf->GetCw ();
1272  }
1273 }
1274 
1275 void
1277 {
1278  NS_LOG_FUNCTION (this);
1279  uint8_t tid = m_currentHdr.GetQosTid ();
1280  Mac48Address recipient = m_currentHdr.GetAddr1 ();
1281  uint16_t sequence = m_currentHdr.GetSequenceNumber ();
1282  if (m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::INACTIVE))
1283  {
1284  m_baManager->SwitchToBlockAckIfNeeded (recipient, tid, sequence);
1285  }
1286  if ((m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED))
1287  && (GetMpduAggregator () == 0 || GetMpduAggregator ()->GetMaxAmpduSize () == 0))
1288  {
1290  }
1291 }
1292 
1294 {
1295  NS_LOG_FUNCTION (this << dest);
1296  if (m_aMpduEnabled.find (dest) != m_aMpduEnabled.end ())
1297  {
1298  return m_aMpduEnabled.find (dest)->second;
1299  }
1300  return false;
1301 }
1302 
1303 void EdcaTxopN::SetAmpduExist (Mac48Address dest, bool enableAmpdu)
1304 {
1305  NS_LOG_FUNCTION (this << dest << enableAmpdu);
1306  if (m_aMpduEnabled.find (dest) != m_aMpduEnabled.end () && m_aMpduEnabled.find (dest)->second != enableAmpdu)
1307  {
1308  m_aMpduEnabled.erase (m_aMpduEnabled.find (dest));
1309  }
1310  if (m_aMpduEnabled.find (dest) == m_aMpduEnabled.end ())
1311  {
1312  m_aMpduEnabled.insert (std::make_pair (dest, enableAmpdu));
1313  }
1314 }
1315 
1316 void
1318 {
1319  NS_LOG_FUNCTION (this);
1321  {
1322  if (!m_currentHdr.IsRetry ())
1323  {
1325  }
1326  m_baManager->NotifyMpduTransmission (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid (),
1329  }
1330 }
1331 
1332 void
1334 {
1335  NS_ASSERT (hdr.IsQosData ());
1336  m_baManager->StorePacket (packet, hdr, tstamp);
1337  m_baManager->NotifyMpduTransmission (hdr.GetAddr1 (), hdr.GetQosTid (),
1340 }
1341 
1342 bool
1344 {
1345  NS_LOG_FUNCTION (this);
1346  uint8_t tid = m_currentHdr.GetQosTid ();
1347  Mac48Address recipient = m_currentHdr.GetAddr1 ();
1348  uint32_t packets = m_queue->GetNPacketsByTidAndAddress (tid, WifiMacHeader::ADDR1, recipient);
1349  if ((m_blockAckThreshold > 0 && packets >= m_blockAckThreshold)
1350  || (m_mpduAggregator != 0 && m_mpduAggregator->GetMaxAmpduSize () > 0 && packets > 1)
1353  {
1354  /* Block ack setup */
1355  uint16_t startingSequence = m_txMiddle->GetNextSeqNumberByTidAndAddress (tid, recipient);
1356  SendAddBaRequest (recipient, tid, startingSequence, m_blockAckInactivityTimeout, true);
1357  return true;
1358  }
1359  return false;
1360 }
1361 
1362 void
1364 {
1365  NS_LOG_FUNCTION (this << &bar);
1366  WifiMacHeader hdr;
1368  hdr.SetAddr1 (bar.recipient);
1369  hdr.SetAddr2 (m_low->GetAddress ());
1370  hdr.SetAddr3 (m_low->GetBssid ());
1371  hdr.SetDsNotTo ();
1372  hdr.SetDsNotFrom ();
1373  hdr.SetNoRetry ();
1374  hdr.SetNoMoreFragments ();
1375 
1376  m_currentPacket = bar.bar;
1377  m_currentHdr = hdr;
1378 
1381  if (bar.immediate)
1382  {
1384  {
1386  }
1388  {
1390  }
1391  else if (m_blockAckType == MULTI_TID_BLOCK_ACK)
1392  {
1393  NS_FATAL_ERROR ("Multi-tid block ack is not supported");
1394  }
1395  }
1396  else
1397  {
1398  //Delayed block ack
1400  }
1402 }
1403 
1404 void
1406 {
1407  NS_LOG_FUNCTION (this);
1408  m_baManager->SetTxMiddle (m_txMiddle);
1409  m_low->RegisterEdcaForAc (m_ac, this);
1410  m_baManager->SetBlockAckInactivityCallback (MakeCallback (&EdcaTxopN::SendDelbaFrame, this));
1411 }
1412 
1413 void
1415 {
1416  NS_LOG_FUNCTION (this << +threshold);
1417  m_blockAckThreshold = threshold;
1418  m_baManager->SetBlockAckThreshold (threshold);
1419 }
1420 
1421 void
1423 {
1424  NS_LOG_FUNCTION (this << timeout);
1426 }
1427 
1428 uint8_t
1430 {
1431  NS_LOG_FUNCTION (this);
1432  return m_blockAckThreshold;
1433 }
1434 
1435 void
1436 EdcaTxopN::SendAddBaRequest (Mac48Address dest, uint8_t tid, uint16_t startSeq,
1437  uint16_t timeout, bool immediateBAck)
1438 {
1439  NS_LOG_FUNCTION (this << dest << +tid << startSeq << timeout << immediateBAck);
1440  NS_LOG_DEBUG ("sent ADDBA request to " << dest);
1441  WifiMacHeader hdr;
1443  hdr.SetAddr1 (dest);
1444  hdr.SetAddr2 (m_low->GetAddress ());
1445  hdr.SetAddr3 (m_low->GetAddress ());
1446  hdr.SetDsNotTo ();
1447  hdr.SetDsNotFrom ();
1448 
1449  WifiActionHeader actionHdr;
1452  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
1453 
1454  Ptr<Packet> packet = Create<Packet> ();
1455  /*Setting ADDBARequest header*/
1456  MgtAddBaRequestHeader reqHdr;
1457  reqHdr.SetAmsduSupport (true);
1458  if (immediateBAck)
1459  {
1460  reqHdr.SetImmediateBlockAck ();
1461  }
1462  else
1463  {
1464  reqHdr.SetDelayedBlockAck ();
1465  }
1466  reqHdr.SetTid (tid);
1467  /* For now we don't use buffer size field in the ADDBA request frame. The recipient
1468  * will choose how many packets it can receive under block ack.
1469  */
1470  reqHdr.SetBufferSize (0);
1471  reqHdr.SetTimeout (timeout);
1472  reqHdr.SetStartingSequence (startSeq);
1473 
1474  m_baManager->CreateAgreement (&reqHdr, dest);
1475 
1476  packet->AddHeader (reqHdr);
1477  packet->AddHeader (actionHdr);
1478 
1479  m_currentPacket = packet;
1480  m_currentHdr = hdr;
1481 
1482  uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&m_currentHdr);
1483  m_currentHdr.SetSequenceNumber (sequence);
1488 
1492 
1494 }
1495 
1496 void
1497 EdcaTxopN::SendDelbaFrame (Mac48Address addr, uint8_t tid, bool byOriginator)
1498 {
1499  NS_LOG_FUNCTION (this << addr << +tid << byOriginator);
1500  WifiMacHeader hdr;
1502  hdr.SetAddr1 (addr);
1503  hdr.SetAddr2 (m_low->GetAddress ());
1504  hdr.SetAddr3 (m_low->GetAddress ());
1505  hdr.SetDsNotTo ();
1506  hdr.SetDsNotFrom ();
1507 
1508  MgtDelBaHeader delbaHdr;
1509  delbaHdr.SetTid (tid);
1510  if (byOriginator)
1511  {
1512  delbaHdr.SetByOriginator ();
1513  m_baManager->DestroyAgreement (addr, tid);
1514  }
1515  else
1516  {
1517  delbaHdr.SetByRecipient ();
1518  m_low->DestroyBlockAckAgreement (addr, tid);
1519  }
1520 
1521  WifiActionHeader actionHdr;
1524  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
1525 
1526  Ptr<Packet> packet = Create<Packet> ();
1527  packet->AddHeader (delbaHdr);
1528  packet->AddHeader (actionHdr);
1529 
1530  PushFront (packet, hdr);
1531 }
1532 
1533 void
1535 {
1536  NS_LOG_FUNCTION (this);
1537  m_dcf->ResetCw ();
1538  m_cwTrace = m_dcf->GetCw ();
1541 }
1542 
1543 void
1545 {
1546  NS_LOG_FUNCTION (this << hdr);
1547  if (!m_txOkCallback.IsNull ())
1548  {
1550  }
1551 }
1552 
1553 void
1555 {
1556  NS_LOG_FUNCTION (this << hdr);
1557  if (!m_txFailedCallback.IsNull ())
1558  {
1560  }
1561 }
1562 
1563 bool
1565 {
1566  return true;
1567 }
1568 
1569 } //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:280
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:461
uint16_t m_blockAckInactivityTimeout
the Block ACK inactivity timeout
Definition: edca-txop-n.h:528
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:804
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
Definition: mgt-headers.h:850
void NotifyCollision(void)
Notify the EDCAF that collision has occurred.
Definition: edca-txop-n.cc:411
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.
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:889
bool IsZero(void) const
Definition: nstime.h:288
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:421
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:983
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
Time CalculateOverallTxTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters &params, uint32_t fragmentSize=0) const
Definition: mac-low.cc:1091
#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:777
#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:525
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:821
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.
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:876
void PrepareForQueue(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet)
Ptr< MsduAggregator > m_msduAggregator
A-MSDU aggregator.
Definition: edca-txop-n.h:520
void SetWifiRemoteStationManager(const Ptr< WifiRemoteStationManager > remoteManager)
Set WifiRemoteStationsManager this EdcaTxopN is associated to.
Definition: edca-txop-n.cc:116
ns3::Time timeout
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.
Definition: edca-txop-n.cc:984
bool IsQosAmsdu(void) const
Check if the A-MSDU present bit is set in the QoS control field.
control how a packet is transmitted.
void MissedBlockAck(uint8_t nMpdus)
Event handler when a Block ACK timeout has occurred.
Definition: edca-txop-n.cc:614
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:531
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:521
AcIndex m_ac
the access category
Definition: edca-txop-n.h:519
void MissedAck(void)
Event handler when an ACK is missed.
Definition: edca-txop-n.cc:549
TracedCallback< Time, Time > m_txopTrace
TXOP trace callback.
Definition: edca-txop-n.h:536
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:2019
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:160
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:154
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:321
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:535
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:534
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:148
bool IsStrictlyPositive(void) const
Definition: nstime.h:308
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:420
void SetTypeOfStation(TypeOfStation type)
Set type of station with the given type.
Definition: edca-txop-n.cc:124
bool IsTxopFragmentation() const
Check if the current packet is fragmented because of an exceeded TXOP duration.
Definition: edca-txop-n.cc:969
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:365
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
Time m_currentPacketTimestamp
the current packet timestamp
Definition: edca-txop-n.h:527
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:290
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:928
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:945
void GotAck(void)
Event handler when an ACK is received.
Definition: edca-txop-n.cc:483
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:694
void EnableCompressedBlockAck(void)
Wait COMPRESSEDBLOCKACKTimeout for a Compressed Block Ack Response frame.
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:688
Bar m_currentBar
the current BAR
Definition: edca-txop-n.h:529
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.
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:131
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:95
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 SetTid(uint8_t tid)
Set Traffic ID (TID).
void DisableRts(void)
Do not send rts and wait for cts before sending data.
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:530
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:2738
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:1054
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
bool Aggregate(Ptr< const Packet > packet, Ptr< Packet > aggregatedPacket, Mac48Address src, Mac48Address dest) const
Adds packet to aggregatedPacket.
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.
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:523
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:926
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:526
void RestartAccessIfNeeded(void)
Restart access request if needed.
Definition: edca-txop-n.cc:700
Implement the header for management frames of type add block ack response.
Definition: mgt-headers.h:1115
Implement the header for management frames of type del block ack.
Definition: mgt-headers.h:1236
void CompleteAmpduTransfer(Mac48Address recipient, uint8_t tid)
Definition: edca-txop-n.cc:110
#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:921
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1007
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
uint16_t GetMaxAmpduSize(void) const
Returns the maximum A-MPDU size in bytes.
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:302
bool IsStrictlyNegative(void) const
Definition: nstime.h:303
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.
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:142
void StartAccessIfNeeded(void)
Request access from DCF manager if needed.
Definition: edca-txop-n.cc:741
bool m_currentIsFragmented
flag whether current packet is fragmented
Definition: edca-txop-n.h:532
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:524
void UpdateFailedCw(void)
Update the value of the CW variable to take into account a transmission failure.
Definition: dcf-state.cc:137
ActionValue GetAction()
Return the action value.
Headers for Block ack request.
Definition: ctrl-headers.h:50
handle packet fragmentation and retransmissions.
Definition: dca-txop.h:58
void SetFragmentNumber(uint8_t frag)
Set the fragment number of the header.
void DisableAck(void)
Do not wait for Ack after data transmission.
void SetAction(CategoryValue type, ActionValue action)
Set action for this Action header.
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.
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:522
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:2298
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:137
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.