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  virtual void EndTxNoAck (void)
115  {
116  m_txop->EndTxNoAck ();
117  }
118 
119 private:
121 };
122 
124 {
125 public:
128  m_txop (txop) {
129  }
131 
132  virtual void BlockAckInactivityTimeout (Mac48Address address, uint8_t tid)
133  {
134  m_txop->SendDelbaFrame (address, tid, false);
135  }
136 
137 private:
139 };
140 
142 
143 TypeId
145 {
146  static TypeId tid = TypeId ("ns3::EdcaTxopN")
149  .AddAttribute ("BlockAckThreshold", "If number of packets in this queue reaches this value,\
150  block ack mechanism is used. If this value is 0, block ack is never used.",
151  UintegerValue (0),
152  MakeUintegerAccessor (&EdcaTxopN::SetBlockAckThreshold,
154  MakeUintegerChecker<uint8_t> (0, 64))
155  .AddAttribute ("BlockAckInactivityTimeout", "Represents max time (blocks of 1024 micro seconds) allowed for block ack\
156  inactivity. If this value isn't equal to 0 a timer start after that a\
157  block ack setup is completed and will be reset every time that a block\
158  ack frame is received. If this value is 0, block ack inactivity timeout won't be used.",
159  UintegerValue (0),
160  MakeUintegerAccessor (&EdcaTxopN::SetBlockAckInactivityTimeout),
161  MakeUintegerChecker<uint16_t> ())
162  .AddAttribute ("Queue", "The WifiMacQueue object",
163  PointerValue (),
164  MakePointerAccessor (&EdcaTxopN::GetQueue),
165  MakePointerChecker<WifiMacQueue> ())
166  ;
167  return tid;
168 }
169 
171  : m_manager (0),
172  m_currentPacket (0),
173  m_aggregator (0),
174  m_blockAckType (COMPRESSED_BLOCK_ACK)
175 {
176  NS_LOG_FUNCTION (this);
179  m_dcf = new EdcaTxopN::Dcf (this);
180  m_queue = CreateObject<WifiMacQueue> ();
181  m_rng = new RealRandomStream ();
183  m_baManager = new BlockAckManager ();
189 }
190 
192 {
193  NS_LOG_FUNCTION (this);
194 }
195 
196 void
198 {
199  NS_LOG_FUNCTION (this);
200  m_queue = 0;
201  m_low = 0;
202  m_stationManager = 0;
203  delete m_transmissionListener;
204  delete m_dcf;
205  delete m_rng;
207  delete m_baManager;
208  delete m_blockAckListener;
210  m_dcf = 0;
211  m_rng = 0;
213  m_baManager = 0;
214  m_blockAckListener = 0;
215  m_txMiddle = 0;
216  m_aggregator = 0;
217 }
218 
219 void
221 {
222  NS_LOG_FUNCTION (this << manager);
223  m_manager = manager;
224  m_manager->Add (m_dcf);
225 }
226 
227 void
229 {
230  NS_LOG_FUNCTION (this << &callback);
231  m_txOkCallback = callback;
232 }
233 
234 void
236 {
237  NS_LOG_FUNCTION (this << &callback);
238  m_txFailedCallback = callback;
239 }
240 
241 void
243 {
244  NS_LOG_FUNCTION (this << remoteManager);
245  m_stationManager = remoteManager;
246 }
247 void
249 {
250  NS_LOG_FUNCTION (this << static_cast<uint32_t> (type));
251  m_typeOfStation = type;
252 }
253 
254 enum TypeOfStation
256 {
257  NS_LOG_FUNCTION (this);
258  return m_typeOfStation;
259 }
260 
263 {
264  NS_LOG_FUNCTION (this);
265  return m_queue;
266 }
267 
268 void
269 EdcaTxopN::SetMinCw (uint32_t minCw)
270 {
271  NS_LOG_FUNCTION (this << minCw);
272  m_dcf->SetCwMin (minCw);
273 }
274 
275 void
276 EdcaTxopN::SetMaxCw (uint32_t maxCw)
277 {
278  NS_LOG_FUNCTION (this << maxCw);
279  m_dcf->SetCwMax (maxCw);
280 }
281 
282 void
283 EdcaTxopN::SetAifsn (uint32_t aifsn)
284 {
285  NS_LOG_FUNCTION (this << aifsn);
286  m_dcf->SetAifsn (aifsn);
287 }
288 
289 uint32_t
291 {
292  NS_LOG_FUNCTION (this);
293  return m_dcf->GetCwMin ();
294 }
295 
296 uint32_t
298 {
299  NS_LOG_FUNCTION (this);
300  return m_dcf->GetCwMax ();
301 }
302 
303 uint32_t
305 {
306  NS_LOG_FUNCTION (this);
307  return m_dcf->GetAifsn ();
308 }
309 
310 void
312 {
313  NS_LOG_FUNCTION (this << txMiddle);
314  m_txMiddle = txMiddle;
315 }
316 
319 {
320  NS_LOG_FUNCTION (this);
321  return m_low;
322 }
323 
324 void
326 {
327  NS_LOG_FUNCTION (this << low);
328  m_low = low;
329 }
330 
331 bool
333 {
334  NS_LOG_FUNCTION (this);
335  return !m_queue->IsEmpty () || m_currentPacket != 0 || m_baManager->HasPackets ();
336 }
337 
338 void
340 {
341  NS_LOG_FUNCTION (this);
342  if (m_currentPacket == 0)
343  {
344  if (m_queue->IsEmpty () && !m_baManager->HasPackets ())
345  {
346  NS_LOG_DEBUG ("queue is empty");
347  return;
348  }
350  {
352  return;
353  }
354  /* check if packets need retransmission are stored in BlockAckManager */
356  if (m_currentPacket == 0)
357  {
359  {
360  NS_LOG_DEBUG ("no available packets in the queue");
361  return;
362  }
364  && m_blockAckThreshold > 0
366  && SetupBlockAckIfNeeded ())
367  {
368  return;
369  }
371  NS_ASSERT (m_currentPacket != 0);
372 
373  uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr);
374  m_currentHdr.SetSequenceNumber (sequence);
378  m_fragmentNumber = 0;
379  NS_LOG_DEBUG ("dequeued size=" << m_currentPacket->GetSize () <<
380  ", to=" << m_currentHdr.GetAddr1 () <<
381  ", seq=" << m_currentHdr.GetSequenceControl ());
383  {
384  VerifyBlockAck ();
385  }
386  }
387  }
389  params.DisableOverrideDurationId ();
390  if (m_currentHdr.GetAddr1 ().IsGroup ())
391  {
392  params.DisableRts ();
393  params.DisableAck ();
394  params.DisableNextData ();
396  &m_currentHdr,
397  params,
399 
400  NS_LOG_DEBUG ("tx broadcast");
401  }
403  {
405  }
406  else
407  {
409  {
410  params.DisableAck ();
411  }
412  else
413  {
414  params.EnableAck ();
415  }
417  && !m_currentHdr.IsQosAmsdu ())
418  ||
419  (m_currentHdr.IsData ()
421  && (m_blockAckThreshold == 0
423  {
424  //With COMPRESSED_BLOCK_ACK fragmentation must be avoided.
425  params.DisableRts ();
426  WifiMacHeader hdr;
427  Ptr<Packet> fragment = GetFragmentPacket (&hdr);
428  if (IsLastFragment ())
429  {
430  NS_LOG_DEBUG ("fragmenting last fragment size=" << fragment->GetSize ());
431  params.DisableNextData ();
432  }
433  else
434  {
435  NS_LOG_DEBUG ("fragmenting size=" << fragment->GetSize ());
437  }
438  m_low->StartTransmission (fragment, &hdr, params,
440  }
441  else
442  {
443  WifiMacHeader peekedHdr;
444  if (m_currentHdr.IsQosData ()
448  && m_aggregator != 0 && !m_currentHdr.IsRetry ())
449  {
450  /* here is performed aggregation */
451  Ptr<Packet> currentAggregatedPacket = Create<Packet> ();
452  m_aggregator->Aggregate (m_currentPacket, currentAggregatedPacket,
453  MapSrcAddressForAggregation (peekedHdr),
454  MapDestAddressForAggregation (peekedHdr));
455  bool aggregated = false;
456  bool isAmsdu = false;
457  Ptr<const Packet> peekedPacket = m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (),
460  while (peekedPacket != 0)
461  {
462  aggregated = m_aggregator->Aggregate (peekedPacket, currentAggregatedPacket,
463  MapSrcAddressForAggregation (peekedHdr),
464  MapDestAddressForAggregation (peekedHdr));
465  if (aggregated)
466  {
467  isAmsdu = true;
468  m_queue->Remove (peekedPacket);
469  }
470  else
471  {
472  break;
473  }
474  peekedPacket = m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (),
476  }
477  if (isAmsdu)
478  {
481  m_currentPacket = currentAggregatedPacket;
482  currentAggregatedPacket = 0;
483  NS_LOG_DEBUG ("tx unicast A-MSDU");
484  }
485  }
486  if (NeedRts ())
487  {
488  params.EnableRts ();
489  NS_LOG_DEBUG ("tx unicast rts");
490  }
491  else
492  {
493  params.DisableRts ();
494  NS_LOG_DEBUG ("tx unicast");
495  }
496  params.DisableNextData ();
498  params, m_transmissionListener);
499  CompleteTx ();
500  }
501  }
502 }
503 
505 {
506  NS_LOG_FUNCTION (this);
507  NotifyCollision ();
508 }
509 
510 void
512 {
513  NS_LOG_FUNCTION (this);
516 }
517 
518 void
519 EdcaTxopN::GotCts (double snr, WifiMode txMode)
520 {
521  NS_LOG_FUNCTION (this << snr << txMode);
522  NS_LOG_DEBUG ("got cts");
523 }
524 
525 void
527 {
528  NS_LOG_FUNCTION (this);
529  NS_LOG_DEBUG ("missed cts");
530  if (!NeedRtsRetransmission ())
531  {
532  NS_LOG_DEBUG ("Cts Fail");
534  if (!m_txFailedCallback.IsNull ())
535  {
537  }
538  // to reset the dcf.
539  m_currentPacket = 0;
540  m_dcf->ResetCw ();
541  }
542  else
543  {
544  m_dcf->UpdateFailedCw ();
545  }
548 }
549 
550 void
552 {
553  NS_LOG_FUNCTION (this);
554  m_queue->Flush ();
555  m_currentPacket = 0;
556 }
557 
558 void
560 {
561  NS_LOG_FUNCTION (this << packet << &hdr);
562  WifiMacTrailer fcs;
563  uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.GetSerializedSize ();
565  packet, fullPacketSize);
566  m_queue->Enqueue (packet, hdr);
568 }
569 
570 void
571 EdcaTxopN::GotAck (double snr, WifiMode txMode)
572 {
573  NS_LOG_FUNCTION (this << snr << txMode);
574  if (!NeedFragmentation ()
575  || IsLastFragment ()
576  || m_currentHdr.IsQosAmsdu ())
577  {
578  NS_LOG_DEBUG ("got ack. tx done.");
579  if (!m_txOkCallback.IsNull ())
580  {
582  }
583 
584  if (m_currentHdr.IsAction ())
585  {
586  WifiActionHeader actionHdr;
588  p->RemoveHeader (actionHdr);
589  if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK
591  {
592  MgtDelBaHeader delBa;
593  p->PeekHeader (delBa);
594  if (delBa.IsByOriginator ())
595  {
597  }
598  else
599  {
601  }
602  }
603  }
604  m_currentPacket = 0;
605 
606  m_dcf->ResetCw ();
609  }
610  else
611  {
612  NS_LOG_DEBUG ("got ack. tx not done, size=" << m_currentPacket->GetSize ());
613  }
614 }
615 
616 void
618 {
619  NS_LOG_FUNCTION (this);
620  NS_LOG_DEBUG ("missed ack");
621  if (!NeedDataRetransmission ())
622  {
623  NS_LOG_DEBUG ("Ack Fail");
625  if (!m_txFailedCallback.IsNull ())
626  {
628  }
629  // to reset the dcf.
630  m_currentPacket = 0;
631  m_dcf->ResetCw ();
632  }
633  else
634  {
635  NS_LOG_DEBUG ("Retransmit");
637  m_dcf->UpdateFailedCw ();
638  }
641 }
642 
643 void
645 {
646  NS_LOG_FUNCTION (this);
647  NS_LOG_DEBUG ("missed block ack");
648  //should i report this to station addressed by ADDR1?
649  NS_LOG_DEBUG ("Retransmit block ack request");
651  m_dcf->UpdateFailedCw ();
652 
655 }
656 
659 {
660  return m_aggregator;
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 void
677 {
678  NS_LOG_FUNCTION (this);
679  if (m_currentPacket == 0
680  && (!m_queue->IsEmpty () || m_baManager->HasPackets ())
681  && !m_dcf->IsAccessRequested ())
682  {
684  }
685 }
686 
687 bool
689 {
690  NS_LOG_FUNCTION (this);
693 }
694 
695 bool
697 {
698  NS_LOG_FUNCTION (this);
701 }
702 
703 bool
705 {
706  NS_LOG_FUNCTION (this);
709 }
710 
711 void
713 {
714  NS_LOG_FUNCTION (this);
716 }
717 
718 void
720 {
721  NS_LOG_FUNCTION (this);
722  NS_LOG_DEBUG ("start next packet fragment");
723  /* this callback is used only for fragments. */
724  NextFragment ();
725  WifiMacHeader hdr;
726  Ptr<Packet> fragment = GetFragmentPacket (&hdr);
728  params.EnableAck ();
729  params.DisableRts ();
730  params.DisableOverrideDurationId ();
731  if (IsLastFragment ())
732  {
733  params.DisableNextData ();
734  }
735  else
736  {
738  }
739  Low ()->StartTransmission (fragment, &hdr, params, m_transmissionListener);
740 }
741 
742 void
744 {
745  NS_LOG_FUNCTION (this);
746  NS_LOG_DEBUG ("transmission cancelled");
747 }
748 
749 void
751 {
752  NS_LOG_FUNCTION (this);
753  NS_LOG_DEBUG ("a transmission that did not require an ACK just finished");
754  m_currentPacket = 0;
755  m_dcf->ResetCw ();
758 }
759 
760 bool
762 {
763  NS_LOG_FUNCTION (this);
766 }
767 
768 uint32_t
770 {
771  NS_LOG_FUNCTION (this);
774 }
775 
776 uint32_t
778 {
779  NS_LOG_FUNCTION (this);
782 }
783 
784 uint32_t
786 {
787  NS_LOG_FUNCTION (this);
790 }
791 
792 
793 bool
795 {
796  NS_LOG_FUNCTION (this);
799 }
800 
803 {
804  NS_LOG_FUNCTION (this << hdr);
805  *hdr = m_currentHdr;
807  uint32_t startOffset = GetFragmentOffset ();
808  Ptr<Packet> fragment;
809  if (IsLastFragment ())
810  {
811  hdr->SetNoMoreFragments ();
812  }
813  else
814  {
815  hdr->SetMoreFragments ();
816  }
817  fragment = m_currentPacket->CreateFragment (startOffset,
818  GetFragmentSize ());
819  return fragment;
820 }
821 
822 void
824 {
825  NS_LOG_FUNCTION (this << static_cast<uint32_t> (ac));
826  m_ac = ac;
827 }
828 
831 {
832  NS_LOG_FUNCTION (this << &hdr);
833  Mac48Address retval;
835  {
836  retval = hdr.GetAddr2 ();
837  }
838  else
839  {
840  retval = hdr.GetAddr3 ();
841  }
842  return retval;
843 }
844 
847 {
848  NS_LOG_FUNCTION (this << &hdr);
849  Mac48Address retval;
851  {
852  retval = hdr.GetAddr1 ();
853  }
854  else
855  {
856  retval = hdr.GetAddr3 ();
857  }
858  return retval;
859 }
860 
861 void
863 {
864  NS_LOG_FUNCTION (this << aggr);
865  m_aggregator = aggr;
866 }
867 
868 void
870 {
871  NS_LOG_FUNCTION (this << packet << &hdr);
872  WifiMacTrailer fcs;
873  uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.GetSerializedSize ();
875  packet, fullPacketSize);
876  m_queue->PushFront (packet, hdr);
878 }
879 
880 void
882 {
883  NS_LOG_FUNCTION (this << respHdr << recipient);
884  NS_LOG_DEBUG ("received ADDBA response from " << recipient);
885  uint8_t tid = respHdr->GetTid ();
887  {
888  if (respHdr->GetStatusCode ().IsSuccess ())
889  {
890  NS_LOG_DEBUG ("block ack agreement established with " << recipient);
891  m_baManager->UpdateAgreement (respHdr, recipient);
892  }
893  else
894  {
895  NS_LOG_DEBUG ("discard ADDBA response" << recipient);
896  m_baManager->NotifyAgreementUnsuccessful (recipient, tid);
897  }
898  }
900 }
901 
902 void
904 {
905  NS_LOG_FUNCTION (this << delBaHdr << recipient);
906  NS_LOG_DEBUG ("received DELBA frame from=" << recipient);
907  m_baManager->TearDownBlockAck (recipient, delBaHdr->GetTid ());
908 }
909 
910 void
912 {
913  NS_LOG_FUNCTION (this << blockAck << recipient);
914  NS_LOG_DEBUG ("got block ack from=" << recipient);
915  m_baManager->NotifyGotBlockAck (blockAck, recipient);
916  m_currentPacket = 0;
917  m_dcf->ResetCw ();
920 }
921 
922 void
924 {
925  NS_LOG_FUNCTION (this);
926  uint8_t tid = m_currentHdr.GetQosTid ();
927  Mac48Address recipient = m_currentHdr.GetAddr1 ();
928  uint16_t sequence = m_currentHdr.GetSequenceNumber ();
930  {
931  m_baManager->SwitchToBlockAckIfNeeded (recipient, tid, sequence);
932  }
934  {
936  }
937 }
938 
939 void
941 {
942  NS_LOG_FUNCTION (this);
944  {
945  if (!m_currentHdr.IsRetry ())
946  {
948  }
951  m_currentHdr.GetAddr1 ()));
952  }
953 }
954 
955 bool
957 {
958  NS_LOG_FUNCTION (this);
959  uint8_t tid = m_currentHdr.GetQosTid ();
960  Mac48Address recipient = m_currentHdr.GetAddr1 ();
961 
962  uint32_t packets = m_queue->GetNPacketsByTidAndAddress (tid, WifiMacHeader::ADDR1, recipient);
963 
964  if (packets >= m_blockAckThreshold)
965  {
966  /* Block ack setup */
967  uint16_t startingSequence = m_txMiddle->GetNextSeqNumberByTidAndAddress (tid, recipient);
968  SendAddBaRequest (recipient, tid, startingSequence, m_blockAckInactivityTimeout, true);
969  return true;
970  }
971  return false;
972 }
973 
974 void
976 {
977  NS_LOG_FUNCTION (this << &bar);
978  WifiMacHeader hdr;
980  hdr.SetAddr1 (bar.recipient);
981  hdr.SetAddr2 (m_low->GetAddress ());
982  hdr.SetAddr3 (m_low->GetBssid ());
983  hdr.SetDsNotTo ();
984  hdr.SetDsNotFrom ();
985  hdr.SetNoRetry ();
986  hdr.SetNoMoreFragments ();
987 
988  m_currentPacket = bar.bar;
989  m_currentHdr = hdr;
990 
992  params.DisableRts ();
993  params.DisableNextData ();
994  params.DisableOverrideDurationId ();
995  if (bar.immediate)
996  {
998  {
999  params.EnableBasicBlockAck ();
1000  }
1002  {
1003  params.EnableCompressedBlockAck ();
1004  }
1005  else if (m_blockAckType == MULTI_TID_BLOCK_ACK)
1006  {
1007  NS_FATAL_ERROR ("Multi-tid block ack is not supported");
1008  }
1009  }
1010  else
1011  {
1012  //Delayed block ack
1013  params.EnableAck ();
1014  }
1016 }
1017 
1018 void
1020 {
1021  NS_LOG_FUNCTION (this);
1025 }
1026 
1027 void
1029 {
1030  NS_LOG_FUNCTION (this << static_cast<uint32_t> (threshold));
1031  m_blockAckThreshold = threshold;
1032  m_baManager->SetBlockAckThreshold (threshold);
1033 }
1034 
1035 void
1037 {
1038  NS_LOG_FUNCTION (this << timeout);
1040 }
1041 
1042 uint8_t
1044 {
1045  NS_LOG_FUNCTION (this);
1046  return m_blockAckThreshold;
1047 }
1048 
1049 void
1050 EdcaTxopN::SendAddBaRequest (Mac48Address dest, uint8_t tid, uint16_t startSeq,
1051  uint16_t timeout, bool immediateBAck)
1052 {
1053  NS_LOG_FUNCTION (this << dest << static_cast<uint32_t> (tid) << startSeq << timeout << immediateBAck);
1054  NS_LOG_DEBUG ("sent ADDBA request to " << dest);
1055  WifiMacHeader hdr;
1056  hdr.SetAction ();
1057  hdr.SetAddr1 (dest);
1058  hdr.SetAddr2 (m_low->GetAddress ());
1059  hdr.SetAddr3 (m_low->GetAddress ());
1060  hdr.SetDsNotTo ();
1061  hdr.SetDsNotFrom ();
1062 
1063  WifiActionHeader actionHdr;
1066  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
1067 
1068  Ptr<Packet> packet = Create<Packet> ();
1069  /*Setting ADDBARequest header*/
1070  MgtAddBaRequestHeader reqHdr;
1071  reqHdr.SetAmsduSupport (true);
1072  if (immediateBAck)
1073  {
1074  reqHdr.SetImmediateBlockAck ();
1075  }
1076  else
1077  {
1078  reqHdr.SetDelayedBlockAck ();
1079  }
1080  reqHdr.SetTid (tid);
1081  /* For now we don't use buffer size field in the ADDBA request frame. The recipient
1082  * will choose how many packets it can receive under block ack.
1083  */
1084  reqHdr.SetBufferSize (0);
1085  reqHdr.SetTimeout (timeout);
1086  reqHdr.SetStartingSequence (startSeq);
1087 
1088  m_baManager->CreateAgreement (&reqHdr, dest);
1089 
1090  packet->AddHeader (reqHdr);
1091  packet->AddHeader (actionHdr);
1092 
1093  m_currentPacket = packet;
1094  m_currentHdr = hdr;
1095 
1096  uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr);
1097  m_currentHdr.SetSequenceNumber (sequence);
1101 
1103  params.EnableAck ();
1104  params.DisableRts ();
1105  params.DisableNextData ();
1106  params.DisableOverrideDurationId ();
1107 
1110 }
1111 
1112 void
1113 EdcaTxopN::SendDelbaFrame (Mac48Address addr, uint8_t tid, bool byOriginator)
1114 {
1115  NS_LOG_FUNCTION (this << addr << static_cast<uint32_t> (tid) << byOriginator);
1116  WifiMacHeader hdr;
1117  hdr.SetAction ();
1118  hdr.SetAddr1 (addr);
1119  hdr.SetAddr2 (m_low->GetAddress ());
1120  hdr.SetAddr3 (m_low->GetAddress ());
1121  hdr.SetDsNotTo ();
1122  hdr.SetDsNotFrom ();
1123 
1124  MgtDelBaHeader delbaHdr;
1125  delbaHdr.SetTid (tid);
1126  if (byOriginator)
1127  {
1128  delbaHdr.SetByOriginator ();
1129  }
1130  else
1131  {
1132  delbaHdr.SetByRecipient ();
1133  }
1134 
1135  WifiActionHeader actionHdr;
1138  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
1139 
1140  Ptr<Packet> packet = Create<Packet> ();
1141  packet->AddHeader (delbaHdr);
1142  packet->AddHeader (actionHdr);
1143 
1144  PushFront (packet, hdr);
1145 }
1146 
1147 int64_t
1149 {
1150  NS_LOG_FUNCTION (this << stream);
1151  m_rng->AssignStreams (stream);
1152  return 1;
1153 }
1154 
1155 void
1157 {
1158  NS_LOG_FUNCTION (this);
1159  m_dcf->ResetCw ();
1162 }
1163 } // namespace ns3