A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20  * Author: Mirko Banchi <mk.banchi@gmail.com>
21  */
22 #include "ns3/log.h"
23 #include "ns3/assert.h"
24 #include "ns3/pointer.h"
25 
26 #include "edca-txop-n.h"
27 #include "mac-low.h"
28 #include "dcf-manager.h"
29 #include "mac-tx-middle.h"
30 #include "wifi-mac-trailer.h"
31 #include "wifi-mac.h"
32 #include "random-stream.h"
33 #include "wifi-mac-queue.h"
34 #include "msdu-aggregator.h"
35 #include "mgt-headers.h"
37 
38 NS_LOG_COMPONENT_DEFINE ("EdcaTxopN");
39 
40 #undef NS_LOG_APPEND_CONTEXT
41 #define NS_LOG_APPEND_CONTEXT if (m_low != 0) { std::clog << "[mac=" << m_low->GetAddress () << "] "; }
42 
43 namespace ns3 {
44 
45 class EdcaTxopN::Dcf : public DcfState
46 {
47 public:
48  Dcf (EdcaTxopN * txop)
49  : m_txop (txop)
50  {
51  }
52 private:
53  virtual void DoNotifyAccessGranted (void)
54  {
56  }
57  virtual void DoNotifyInternalCollision (void)
58  {
60  }
61  virtual void DoNotifyCollision (void)
62  {
64  }
65  virtual void DoNotifyChannelSwitching (void)
66  {
68  }
70 };
71 
73 {
74 public:
77  m_txop (txop) {
78  }
79 
80  virtual ~TransmissionListener () {}
81 
82  virtual void GotCts (double snr, WifiMode txMode)
83  {
84  m_txop->GotCts (snr, txMode);
85  }
86  virtual void MissedCts (void)
87  {
88  m_txop->MissedCts ();
89  }
90  virtual void GotAck (double snr, WifiMode txMode)
91  {
92  m_txop->GotAck (snr, txMode);
93  }
94  virtual void MissedAck (void)
95  {
96  m_txop->MissedAck ();
97  }
98  virtual void GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address source)
99  {
100  m_txop->GotBlockAck (blockAck, source);
101  }
102  virtual void MissedBlockAck (void)
103  {
105  }
106  virtual void StartNext (void)
107  {
108  m_txop->StartNext ();
109  }
110  virtual void Cancel (void)
111  {
112  m_txop->Cancel ();
113  }
114 
115 private:
117 };
118 
120 {
121 public:
124  m_txop (txop) {
125  }
127 
128  virtual void BlockAckInactivityTimeout (Mac48Address address, uint8_t tid)
129  {
130  m_txop->SendDelbaFrame (address, tid, false);
131  }
132 
133 private:
135 };
136 
138 
139 TypeId
141 {
142  static TypeId tid = TypeId ("ns3::EdcaTxopN")
145  .AddAttribute ("BlockAckThreshold", "If number of packets in this queue reaches this value,\
146  block ack mechanism is used. If this value is 0, block ack is never used.",
147  UintegerValue (0),
148  MakeUintegerAccessor (&EdcaTxopN::SetBlockAckThreshold,
150  MakeUintegerChecker<uint8_t> (0, 64))
151  .AddAttribute ("BlockAckInactivityTimeout", "Represents max time (blocks of 1024 micro seconds) allowed for block ack\
152  inactivity. If this value isn't equal to 0 a timer start after that a\
153  block ack setup is completed and will be reset every time that a block\
154  ack frame is received. If this value is 0, block ack inactivity timeout won't be used.",
155  UintegerValue (0),
156  MakeUintegerAccessor (&EdcaTxopN::SetBlockAckInactivityTimeout),
157  MakeUintegerChecker<uint16_t> ())
158  .AddAttribute ("Queue", "The WifiMacQueue object",
159  PointerValue (),
160  MakePointerAccessor (&EdcaTxopN::GetQueue),
161  MakePointerChecker<WifiMacQueue> ())
162  ;
163  return tid;
164 }
165 
167  : m_manager (0),
168  m_currentPacket (0),
169  m_aggregator (0),
170  m_blockAckType (COMPRESSED_BLOCK_ACK)
171 {
172  NS_LOG_FUNCTION (this);
175  m_dcf = new EdcaTxopN::Dcf (this);
176  m_queue = CreateObject<WifiMacQueue> ();
177  m_rng = new RealRandomStream ();
179  m_baManager = new BlockAckManager ();
185 }
186 
188 {
189  NS_LOG_FUNCTION (this);
190 }
191 
192 void
194 {
195  NS_LOG_FUNCTION (this);
196  m_queue = 0;
197  m_low = 0;
198  m_stationManager = 0;
199  delete m_transmissionListener;
200  delete m_dcf;
201  delete m_rng;
203  delete m_baManager;
204  delete m_blockAckListener;
206  m_dcf = 0;
207  m_rng = 0;
209  m_baManager = 0;
210  m_blockAckListener = 0;
211  m_txMiddle = 0;
212  m_aggregator = 0;
213 }
214 
215 void
217 {
218  NS_LOG_FUNCTION (this << manager);
219  m_manager = manager;
220  m_manager->Add (m_dcf);
221 }
222 
223 void
225 {
226  m_txOkCallback = callback;
227 }
228 
229 void
231 {
232  m_txFailedCallback = callback;
233 }
234 
235 void
237 {
238  NS_LOG_FUNCTION (this << remoteManager);
239  m_stationManager = remoteManager;
240 }
241 void
243 {
244  NS_LOG_FUNCTION (this << type);
245  m_typeOfStation = type;
246 }
247 
248 enum TypeOfStation
250 {
251  return m_typeOfStation;
252 }
253 
256 {
257  NS_LOG_FUNCTION (this);
258  return m_queue;
259 }
260 
261 void
262 EdcaTxopN::SetMinCw (uint32_t minCw)
263 {
264  NS_LOG_FUNCTION (this << minCw);
265  m_dcf->SetCwMin (minCw);
266 }
267 
268 void
269 EdcaTxopN::SetMaxCw (uint32_t maxCw)
270 {
271  NS_LOG_FUNCTION (this << maxCw);
272  m_dcf->SetCwMax (maxCw);
273 }
274 
275 void
276 EdcaTxopN::SetAifsn (uint32_t aifsn)
277 {
278  NS_LOG_FUNCTION (this << aifsn);
279  m_dcf->SetAifsn (aifsn);
280 }
281 
282 uint32_t
284 {
285  return m_dcf->GetCwMin ();
286 }
287 
288 uint32_t
290 {
291  return m_dcf->GetCwMax ();
292 }
293 
294 uint32_t
296 {
297  return m_dcf->GetAifsn ();
298 }
299 
300 void
302 {
303  m_txMiddle = txMiddle;
304 }
305 
308 {
309  return m_low;
310 }
311 
312 void
314 {
315  NS_LOG_FUNCTION (this << low);
316  m_low = low;
317 }
318 
319 bool
321 {
322  return !m_queue->IsEmpty () || m_currentPacket != 0 || m_baManager->HasPackets ();
323 }
324 
325 void
327 {
328  NS_LOG_FUNCTION (this);
329  if (m_currentPacket == 0)
330  {
331  if (m_queue->IsEmpty () && !m_baManager->HasPackets ())
332  {
333  NS_LOG_DEBUG ("queue is empty");
334  return;
335  }
337  {
339  return;
340  }
341  /* check if packets need retransmission are stored in BlockAckManager */
343  if (m_currentPacket == 0)
344  {
346  {
347  NS_LOG_DEBUG ("no available packets in the queue");
348  return;
349  }
351  && m_blockAckThreshold > 0
353  && SetupBlockAckIfNeeded ())
354  {
355  return;
356  }
358  NS_ASSERT (m_currentPacket != 0);
359 
360  uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr);
361  m_currentHdr.SetSequenceNumber (sequence);
365  m_fragmentNumber = 0;
366  NS_LOG_DEBUG ("dequeued size=" << m_currentPacket->GetSize () <<
367  ", to=" << m_currentHdr.GetAddr1 () <<
368  ", seq=" << m_currentHdr.GetSequenceControl ());
370  {
371  VerifyBlockAck ();
372  }
373  }
374  }
376  params.DisableOverrideDurationId ();
377  if (m_currentHdr.GetAddr1 ().IsGroup ())
378  {
379  params.DisableRts ();
380  params.DisableAck ();
381  params.DisableNextData ();
383  &m_currentHdr,
384  params,
386 
387  m_currentPacket = 0;
388  m_dcf->ResetCw ();
391  NS_LOG_DEBUG ("tx broadcast");
392  }
394  {
396  }
397  else
398  {
400  {
401  params.DisableAck ();
402  }
403  else
404  {
405  params.EnableAck ();
406  }
408  && !m_currentHdr.IsQosAmsdu ())
409  || m_currentHdr.IsData ())
410  && (m_blockAckThreshold == 0
412  {
413  //With COMPRESSED_BLOCK_ACK fragmentation must be avoided.
414  params.DisableRts ();
415  WifiMacHeader hdr;
416  Ptr<Packet> fragment = GetFragmentPacket (&hdr);
417  if (IsLastFragment ())
418  {
419  NS_LOG_DEBUG ("fragmenting last fragment size=" << fragment->GetSize ());
420  params.DisableNextData ();
421  }
422  else
423  {
424  NS_LOG_DEBUG ("fragmenting size=" << fragment->GetSize ());
426  }
427  m_low->StartTransmission (fragment, &hdr, params,
429  }
430  else
431  {
432  WifiMacHeader peekedHdr;
433  if (m_currentHdr.IsQosData ()
437  && m_aggregator != 0 && !m_currentHdr.IsRetry ())
438  {
439  /* here is performed aggregation */
440  Ptr<Packet> currentAggregatedPacket = Create<Packet> ();
441  m_aggregator->Aggregate (m_currentPacket, currentAggregatedPacket,
442  MapSrcAddressForAggregation (peekedHdr),
443  MapDestAddressForAggregation (peekedHdr));
444  bool aggregated = false;
445  bool isAmsdu = false;
446  Ptr<const Packet> peekedPacket = m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (),
449  while (peekedPacket != 0)
450  {
451  aggregated = m_aggregator->Aggregate (peekedPacket, currentAggregatedPacket,
452  MapSrcAddressForAggregation (peekedHdr),
453  MapDestAddressForAggregation (peekedHdr));
454  if (aggregated)
455  {
456  isAmsdu = true;
457  m_queue->Remove (peekedPacket);
458  }
459  else
460  {
461  break;
462  }
463  peekedPacket = m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (),
465  }
466  if (isAmsdu)
467  {
470  m_currentPacket = currentAggregatedPacket;
471  currentAggregatedPacket = 0;
472  NS_LOG_DEBUG ("tx unicast A-MSDU");
473  }
474  }
475  if (NeedRts ())
476  {
477  params.EnableRts ();
478  NS_LOG_DEBUG ("tx unicast rts");
479  }
480  else
481  {
482  params.DisableRts ();
483  NS_LOG_DEBUG ("tx unicast");
484  }
485  params.DisableNextData ();
487  params, m_transmissionListener);
488  CompleteTx ();
489  }
490  }
491 }
492 
494 {
495  NS_LOG_FUNCTION (this);
496  NotifyCollision ();
497 }
498 
499 void
501 {
502  NS_LOG_FUNCTION (this);
505 }
506 
507 void
508 EdcaTxopN::GotCts (double snr, WifiMode txMode)
509 {
510  NS_LOG_FUNCTION (this << snr << txMode);
511  NS_LOG_DEBUG ("got cts");
512 }
513 
514 void
516 {
517  NS_LOG_FUNCTION (this);
518  NS_LOG_DEBUG ("missed cts");
519  if (!NeedRtsRetransmission ())
520  {
521  NS_LOG_DEBUG ("Cts Fail");
523  if (!m_txFailedCallback.IsNull ())
524  {
526  }
527  // to reset the dcf.
528  m_currentPacket = 0;
529  m_dcf->ResetCw ();
530  }
531  else
532  {
533  m_dcf->UpdateFailedCw ();
534  }
537 }
538 
539 void
541 {
542  m_queue->Flush ();
543  m_currentPacket = 0;
544 }
545 
546 void
548 {
549  NS_LOG_FUNCTION (this << packet << &hdr);
550  WifiMacTrailer fcs;
551  uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.GetSerializedSize ();
553  packet, fullPacketSize);
554  m_queue->Enqueue (packet, hdr);
556 }
557 
558 void
559 EdcaTxopN::GotAck (double snr, WifiMode txMode)
560 {
561  NS_LOG_FUNCTION (this << snr << txMode);
562  if (!NeedFragmentation ()
563  || IsLastFragment ()
564  || m_currentHdr.IsQosAmsdu ())
565  {
566  NS_LOG_DEBUG ("got ack. tx done.");
567  if (!m_txOkCallback.IsNull ())
568  {
570  }
571 
572  if (m_currentHdr.IsAction ())
573  {
574  WifiActionHeader actionHdr;
576  p->RemoveHeader (actionHdr);
577  if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK
579  {
580  MgtDelBaHeader delBa;
581  p->PeekHeader (delBa);
582  if (delBa.IsByOriginator ())
583  {
585  }
586  else
587  {
589  }
590  }
591  }
592  m_currentPacket = 0;
593 
594  m_dcf->ResetCw ();
597  }
598  else
599  {
600  NS_LOG_DEBUG ("got ack. tx not done, size=" << m_currentPacket->GetSize ());
601  }
602 }
603 
604 void
606 {
607  NS_LOG_FUNCTION (this);
608  NS_LOG_DEBUG ("missed ack");
609  if (!NeedDataRetransmission ())
610  {
611  NS_LOG_DEBUG ("Ack Fail");
613  if (!m_txFailedCallback.IsNull ())
614  {
616  }
617  // to reset the dcf.
618  m_currentPacket = 0;
619  m_dcf->ResetCw ();
620  }
621  else
622  {
623  NS_LOG_DEBUG ("Retransmit");
625  m_dcf->UpdateFailedCw ();
626  }
629 }
630 
631 void
633 {
634  NS_LOG_FUNCTION (this);
635  NS_LOG_DEBUG ("missed block ack");
636  //should i report this to station addressed by ADDR1?
637  NS_LOG_DEBUG ("Retransmit block ack request");
639  m_dcf->UpdateFailedCw ();
640 
643 }
644 
647 {
648  return m_aggregator;
649 }
650 
651 void
653 {
654  NS_LOG_FUNCTION (this);
655  if ((m_currentPacket != 0
656  || !m_queue->IsEmpty () || m_baManager->HasPackets ())
657  && !m_dcf->IsAccessRequested ())
658  {
660  }
661 }
662 
663 void
665 {
666  NS_LOG_FUNCTION (this);
667  if (m_currentPacket == 0
668  && (!m_queue->IsEmpty () || m_baManager->HasPackets ())
669  && !m_dcf->IsAccessRequested ())
670  {
672  }
673 }
674 
675 bool
677 {
680 }
681 
682 bool
684 {
687 }
688 
689 bool
691 {
694 }
695 
696 void
698 {
700 }
701 
702 void
704 {
705  NS_LOG_FUNCTION (this);
706  NS_LOG_DEBUG ("start next packet fragment");
707  /* this callback is used only for fragments. */
708  NextFragment ();
709  WifiMacHeader hdr;
710  Ptr<Packet> fragment = GetFragmentPacket (&hdr);
712  params.EnableAck ();
713  params.DisableRts ();
714  params.DisableOverrideDurationId ();
715  if (IsLastFragment ())
716  {
717  params.DisableNextData ();
718  }
719  else
720  {
722  }
723  Low ()->StartTransmission (fragment, &hdr, params, m_transmissionListener);
724 }
725 
726 void
728 {
729  NS_LOG_FUNCTION (this);
730  NS_LOG_DEBUG ("transmission cancelled");
731 }
732 
733 bool
735 {
738 }
739 
740 uint32_t
742 {
745 }
746 
747 uint32_t
749 {
752 }
753 
754 uint32_t
756 {
759 }
760 
761 
762 bool
764 {
767 }
768 
771 {
772  *hdr = m_currentHdr;
774  uint32_t startOffset = GetFragmentOffset ();
775  Ptr<Packet> fragment;
776  if (IsLastFragment ())
777  {
778  hdr->SetNoMoreFragments ();
779  }
780  else
781  {
782  hdr->SetMoreFragments ();
783  }
784  fragment = m_currentPacket->CreateFragment (startOffset,
785  GetFragmentSize ());
786  return fragment;
787 }
788 
789 void
791 {
792  m_ac = ac;
793 }
794 
797 {
798  Mac48Address retval;
800  {
801  retval = hdr.GetAddr2 ();
802  }
803  else
804  {
805  retval = hdr.GetAddr3 ();
806  }
807  return retval;
808 }
809 
812 {
813  Mac48Address retval;
815  {
816  retval = hdr.GetAddr1 ();
817  }
818  else
819  {
820  retval = hdr.GetAddr3 ();
821  }
822  return retval;
823 }
824 
825 void
827 {
828  m_aggregator = aggr;
829 }
830 
831 void
833 {
834  NS_LOG_FUNCTION (this << packet << &hdr);
835  WifiMacTrailer fcs;
836  uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.GetSerializedSize ();
838  packet, fullPacketSize);
839  m_queue->PushFront (packet, hdr);
841 }
842 
843 void
845 {
846  NS_LOG_FUNCTION (this);
847  NS_LOG_DEBUG ("received ADDBA response from " << recipient);
848  uint8_t tid = respHdr->GetTid ();
850  {
851  if (respHdr->GetStatusCode ().IsSuccess ())
852  {
853  NS_LOG_DEBUG ("block ack agreement established with " << recipient);
854  m_baManager->UpdateAgreement (respHdr, recipient);
855  }
856  else
857  {
858  NS_LOG_DEBUG ("discard ADDBA response" << recipient);
859  m_baManager->NotifyAgreementUnsuccessful (recipient, tid);
860  }
861  }
863 }
864 
865 void
867 {
868  NS_LOG_FUNCTION (this);
869  NS_LOG_DEBUG ("received DELBA frame from=" << recipient);
870  m_baManager->TearDownBlockAck (recipient, delBaHdr->GetTid ());
871 }
872 
873 void
875 {
876  NS_LOG_DEBUG ("got block ack from=" << recipient);
877  m_baManager->NotifyGotBlockAck (blockAck, recipient);
878  m_currentPacket = 0;
879  m_dcf->ResetCw ();
882 }
883 
884 void
886 {
887  NS_LOG_FUNCTION (this);
888  uint8_t tid = m_currentHdr.GetQosTid ();
889  Mac48Address recipient = m_currentHdr.GetAddr1 ();
890  uint16_t sequence = m_currentHdr.GetSequenceNumber ();
892  {
893  m_baManager->SwitchToBlockAckIfNeeded (recipient, tid, sequence);
894  }
896  {
898  }
899 }
900 
901 void
903 {
905  {
906  if (!m_currentHdr.IsRetry ())
907  {
909  }
912  m_currentHdr.GetAddr1 ()));
913  //we are not waiting for an ack: transmission is completed
914  m_currentPacket = 0;
915  m_dcf->ResetCw ();
918  }
919 }
920 
921 bool
923 {
924  uint8_t tid = m_currentHdr.GetQosTid ();
925  Mac48Address recipient = m_currentHdr.GetAddr1 ();
926 
927  uint32_t packets = m_queue->GetNPacketsByTidAndAddress (tid, WifiMacHeader::ADDR1, recipient);
928 
929  if (packets >= m_blockAckThreshold)
930  {
931  /* Block ack setup */
932  uint16_t startingSequence = m_txMiddle->GetNextSeqNumberByTidAndAddress (tid, recipient);
933  SendAddBaRequest (recipient, tid, startingSequence, m_blockAckInactivityTimeout, true);
934  return true;
935  }
936  return false;
937 }
938 
939 void
941 {
942  NS_LOG_FUNCTION (this);
943  WifiMacHeader hdr;
945  hdr.SetAddr1 (bar.recipient);
946  hdr.SetAddr2 (m_low->GetAddress ());
947  hdr.SetAddr3 (m_low->GetBssid ());
948  hdr.SetDsNotTo ();
949  hdr.SetDsNotFrom ();
950  hdr.SetNoRetry ();
951  hdr.SetNoMoreFragments ();
952 
953  m_currentPacket = bar.bar;
954  m_currentHdr = hdr;
955 
957  params.DisableRts ();
958  params.DisableNextData ();
959  params.DisableOverrideDurationId ();
960  if (bar.immediate)
961  {
963  {
964  params.EnableBasicBlockAck ();
965  }
967  {
968  params.EnableCompressedBlockAck ();
969  }
971  {
972  NS_FATAL_ERROR ("Multi-tid block ack is not supported");
973  }
974  }
975  else
976  {
977  //Delayed block ack
978  params.EnableAck ();
979  }
981 }
982 
983 void
985 {
986  NS_LOG_FUNCTION (this);
990 }
991 
992 void
994 {
995  m_blockAckThreshold = threshold;
996  m_baManager->SetBlockAckThreshold (threshold);
997 }
998 
999 void
1001 {
1003 }
1004 
1005 uint8_t
1007 {
1008  return m_blockAckThreshold;
1009 }
1010 
1011 void
1012 EdcaTxopN::SendAddBaRequest (Mac48Address dest, uint8_t tid, uint16_t startSeq,
1013  uint16_t timeout, bool immediateBAck)
1014 {
1015  NS_LOG_FUNCTION (this);
1016  NS_LOG_DEBUG ("sent ADDBA request to " << dest);
1017  WifiMacHeader hdr;
1018  hdr.SetAction ();
1019  hdr.SetAddr1 (dest);
1020  hdr.SetAddr2 (m_low->GetAddress ());
1021  hdr.SetAddr3 (m_low->GetAddress ());
1022  hdr.SetDsNotTo ();
1023  hdr.SetDsNotFrom ();
1024 
1025  WifiActionHeader actionHdr;
1028  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
1029 
1030  Ptr<Packet> packet = Create<Packet> ();
1031  /*Setting ADDBARequest header*/
1032  MgtAddBaRequestHeader reqHdr;
1033  reqHdr.SetAmsduSupport (true);
1034  if (immediateBAck)
1035  {
1036  reqHdr.SetImmediateBlockAck ();
1037  }
1038  else
1039  {
1040  reqHdr.SetDelayedBlockAck ();
1041  }
1042  reqHdr.SetTid (tid);
1043  /* For now we don't use buffer size field in the ADDBA request frame. The recipient
1044  * will choose how many packets it can receive under block ack.
1045  */
1046  reqHdr.SetBufferSize (0);
1047  reqHdr.SetTimeout (timeout);
1048  reqHdr.SetStartingSequence (startSeq);
1049 
1050  m_baManager->CreateAgreement (&reqHdr, dest);
1051 
1052  packet->AddHeader (reqHdr);
1053  packet->AddHeader (actionHdr);
1054 
1055  m_currentPacket = packet;
1056  m_currentHdr = hdr;
1057 
1058  uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr);
1059  m_currentHdr.SetSequenceNumber (sequence);
1063 
1065  params.EnableAck ();
1066  params.DisableRts ();
1067  params.DisableNextData ();
1068  params.DisableOverrideDurationId ();
1069 
1072 }
1073 
1074 void
1075 EdcaTxopN::SendDelbaFrame (Mac48Address addr, uint8_t tid, bool byOriginator)
1076 {
1077  WifiMacHeader hdr;
1078  hdr.SetAction ();
1079  hdr.SetAddr1 (addr);
1080  hdr.SetAddr2 (m_low->GetAddress ());
1081  hdr.SetAddr3 (m_low->GetAddress ());
1082  hdr.SetDsNotTo ();
1083  hdr.SetDsNotFrom ();
1084 
1085  MgtDelBaHeader delbaHdr;
1086  delbaHdr.SetTid (tid);
1087  if (byOriginator)
1088  {
1089  delbaHdr.SetByOriginator ();
1090  }
1091  else
1092  {
1093  delbaHdr.SetByRecipient ();
1094  }
1095 
1096  WifiActionHeader actionHdr;
1099  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
1100 
1101  Ptr<Packet> packet = Create<Packet> ();
1102  packet->AddHeader (delbaHdr);
1103  packet->AddHeader (actionHdr);
1104 
1105  PushFront (packet, hdr);
1106 }
1107 
1108 int64_t
1110 {
1111  NS_LOG_FUNCTION (this << stream);
1112  m_rng->AssignStreams (stream);
1113  return 1;
1114 }
1115 
1116 void
1118 {
1119  m_dcf->ResetCw ();
1121  ns3::Dcf::DoStart ();
1122 }
1123 } // namespace ns3