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/assert.h"
25 #include "ns3/pointer.h"
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 "mpdu-aggregator.h"
36 #include "mgt-headers.h"
38 #include "ns3/simulator.h"
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 NS_LOG_COMPONENT_DEFINE ("EdcaTxopN");
46 
47 class EdcaTxopN::Dcf : public DcfState
48 {
49 public:
50  Dcf (EdcaTxopN * txop)
51  : m_txop (txop)
52  {
53  }
54 
55  virtual bool IsEdca (void) const
56  {
57  return true;
58  }
59 
60 private:
61  virtual void DoNotifyAccessGranted (void)
62  {
64  }
65  virtual void DoNotifyInternalCollision (void)
66  {
68  }
69  virtual void DoNotifyCollision (void)
70  {
72  }
73  virtual void DoNotifyChannelSwitching (void)
74  {
76  }
77  virtual void DoNotifySleep (void)
78  {
79  m_txop->NotifySleep ();
80  }
81  virtual void DoNotifyWakeUp (void)
82  {
83  m_txop->NotifyWakeUp ();
84  }
85 
87 };
88 
89 
91 {
92 public:
95  m_txop (txop)
96  {
97  }
98 
100  {
101  }
102 
103  virtual void GotCts (double snr, WifiMode txMode)
104  {
105  m_txop->GotCts (snr, txMode);
106  }
107  virtual void MissedCts (void)
108  {
109  m_txop->MissedCts ();
110  }
111  virtual void GotAck (double snr, WifiMode txMode)
112  {
113  m_txop->GotAck (snr, txMode);
114  }
115  virtual void MissedAck (void)
116  {
117  m_txop->MissedAck ();
118  }
119  virtual void GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address source, double rxSnr, WifiMode txMode, double dataSnr)
120  {
121  m_txop->GotBlockAck (blockAck, source, rxSnr, txMode, dataSnr);
122  }
123  virtual void MissedBlockAck (uint32_t nMpdus)
124  {
125  m_txop->MissedBlockAck (nMpdus);
126  }
127  virtual void StartNextFragment (void)
128  {
130  }
131  virtual void StartNext (void)
132  {
133  m_txop->StartNext ();
134  }
135  virtual void Cancel (void)
136  {
137  m_txop->Cancel ();
138  }
139  virtual void EndTxNoAck (void)
140  {
141  m_txop->EndTxNoAck ();
142  }
144  {
145  return m_txop->GetEdcaQueue ();
146  }
147 
148 private:
150 };
151 
152 
154 {
155 public:
158  m_txop (txop)
159  {
160  }
162  {
163  }
164 
165  virtual void BlockAckInactivityTimeout (Mac48Address address, uint8_t tid)
166  {
167  m_txop->SendDelbaFrame (address, tid, false);
168  }
170  {
171  return m_txop->GetEdcaQueue ();
172  }
173  virtual void CompleteTransfer (Mac48Address recipient, uint8_t tid)
174  {
175  m_txop->CompleteAmpduTransfer (recipient, tid);
176  }
177  virtual void SetAmpdu (Mac48Address dest, bool enableAmpdu)
178  {
179  return m_txop->SetAmpduExist (dest, enableAmpdu);
180  }
181  virtual void CompleteMpduTx (Ptr<const Packet> packet, WifiMacHeader hdr, Time tstamp)
182  {
183  m_txop->CompleteMpduTx (packet, hdr, tstamp);
184  }
185  virtual uint16_t GetNextSequenceNumberfor (WifiMacHeader *hdr)
186  {
187  return m_txop->GetNextSequenceNumberfor (hdr);
188  }
189  virtual uint16_t PeekNextSequenceNumberfor (WifiMacHeader *hdr)
190  {
191  return m_txop->PeekNextSequenceNumberfor (hdr);
192  }
193  virtual Ptr<const Packet> PeekNextPacketInBaQueue (WifiMacHeader &header, Mac48Address recipient, uint8_t tid, Time *timestamp)
194  {
195  return m_txop->PeekNextRetransmitPacket (header, recipient, tid, timestamp);
196  }
197  virtual void RemoveFromBaQueue (uint8_t tid, Mac48Address recipient, uint16_t seqnumber)
198  {
199  m_txop->RemoveRetransmitPacket (tid, recipient, seqnumber);
200  }
201  virtual bool GetBlockAckAgreementExists (Mac48Address address, uint8_t tid)
202  {
203  return m_txop->GetBaAgreementExists (address,tid);
204  }
205  virtual uint32_t GetNOutstandingPackets (Mac48Address address, uint8_t tid)
206  {
207  return m_txop->GetNOutstandingPacketsInBa (address, tid);
208  }
209  virtual uint32_t GetNRetryNeededPackets (Mac48Address recipient, uint8_t tid) const
210  {
211  return m_txop->GetNRetryNeededPackets (recipient, tid);
212  }
214  {
215  return m_txop->GetMsduAggregator ();
216  }
218  {
219  return m_txop->GetMpduAggregator ();
220  }
222  {
223  return m_txop->MapSrcAddressForAggregation (hdr);
224  }
226  {
227  return m_txop->MapDestAddressForAggregation (hdr);
228  }
229 
230 private:
232 };
233 
235 
236 TypeId
238 {
239  static TypeId tid = TypeId ("ns3::EdcaTxopN")
240  .SetParent<ns3::Dcf> ()
241  .SetGroupName ("Wifi")
242  .AddConstructor<EdcaTxopN> ()
243  .AddAttribute ("Queue",
244  "The WifiMacQueue object",
245  PointerValue (),
247  MakePointerChecker<WifiMacQueue> ())
248  .AddTraceSource ("BackoffTrace",
249  "Trace source for backoff values",
251  "ns3::TracedValue::Uint32Callback")
252  .AddTraceSource ("CwTrace",
253  "Trace source for contention window values",
255  "ns3::TracedValue::Uint32Callback")
256  ;
257  return tid;
258 }
259 
261  : m_manager (0),
262  m_currentPacket (0),
263  m_msduAggregator (0),
264  m_mpduAggregator (0),
265  m_typeOfStation (STA),
266  m_blockAckType (COMPRESSED_BLOCK_ACK),
267  m_startTxop (Seconds (0)),
268  m_isAccessRequestedForRts (false)
269 {
270  NS_LOG_FUNCTION (this);
273  m_dcf = new EdcaTxopN::Dcf (this);
274  m_queue = CreateObject<WifiMacQueue> ();
275  m_rng = new RealRandomStream ();
277  m_baManager = new BlockAckManager ();
282  m_baManager->SetMaxPacketDelay (m_queue->GetMaxDelay ());
285 }
286 
288 {
289  NS_LOG_FUNCTION (this);
290 }
291 
292 void
294 {
295  NS_LOG_FUNCTION (this);
296  m_queue = 0;
297  m_low = 0;
298  m_stationManager = 0;
299  delete m_transmissionListener;
300  delete m_dcf;
301  delete m_rng;
303  delete m_baManager;
304  delete m_blockAckListener;
306  m_dcf = 0;
307  m_rng = 0;
309  m_baManager = 0;
310  m_blockAckListener = 0;
311  m_txMiddle = 0;
312  m_msduAggregator = 0;
313  m_mpduAggregator = 0;
314 }
315 
316 bool
318 {
319  return m_baManager->ExistsAgreement (address, tid);
320 }
321 
322 uint32_t
324 {
325  return m_baManager->GetNBufferedPackets (address, tid);
326 }
327 
328 uint32_t
329 EdcaTxopN::GetNRetryNeededPackets (Mac48Address recipient, uint8_t tid) const
330 {
331  return m_baManager->GetNRetryNeededPackets (recipient, tid);
332 }
333 
334 void
336 {
337  m_baManager->CompleteAmpduExchange (recipient, tid);
338 }
339 
340 void
342 {
343  NS_LOG_FUNCTION (this << manager);
344  m_manager = manager;
345  m_manager->Add (m_dcf);
346 }
347 
348 void
350 {
351  NS_LOG_FUNCTION (this << &callback);
352  m_txOkCallback = callback;
353 }
354 
355 void
357 {
358  NS_LOG_FUNCTION (this << &callback);
359  m_txFailedCallback = callback;
360 }
361 
362 void
364 {
365  NS_LOG_FUNCTION (this << remoteManager);
366  m_stationManager = remoteManager;
368 }
369 
370 void
372 {
373  NS_LOG_FUNCTION (this << static_cast<uint32_t> (type));
374  m_typeOfStation = type;
375 }
376 
377 enum TypeOfStation
379 {
380  NS_LOG_FUNCTION (this);
381  return m_typeOfStation;
382 }
383 
386 {
387  NS_LOG_FUNCTION (this);
388  return m_queue;
389 }
390 
391 void
392 EdcaTxopN::SetMinCw (uint32_t minCw)
393 {
394  NS_LOG_FUNCTION (this << minCw);
395  m_dcf->SetCwMin (minCw);
396 }
397 
398 void
399 EdcaTxopN::SetMaxCw (uint32_t maxCw)
400 {
401  NS_LOG_FUNCTION (this << maxCw);
402  m_dcf->SetCwMax (maxCw);
403 }
404 
405 void
406 EdcaTxopN::SetAifsn (uint32_t aifsn)
407 {
408  NS_LOG_FUNCTION (this << aifsn);
409  m_dcf->SetAifsn (aifsn);
410 }
411 
412 void
414 {
415  NS_LOG_FUNCTION (this << txopLimit);
416  m_dcf->SetTxopLimit (txopLimit);
417 }
418 
419 uint32_t
421 {
422  NS_LOG_FUNCTION (this);
423  return m_dcf->GetCwMin ();
424 }
425 
426 uint32_t
428 {
429  NS_LOG_FUNCTION (this);
430  return m_dcf->GetCwMax ();
431 }
432 
433 uint32_t
435 {
436  NS_LOG_FUNCTION (this);
437  return m_dcf->GetAifsn ();
438 }
439 
440 Time
442 {
443  NS_LOG_FUNCTION (this);
444  return m_dcf->GetTxopLimit ();
445 }
446 
447 void
449 {
450  NS_LOG_FUNCTION (this << txMiddle);
451  m_txMiddle = txMiddle;
452 }
453 
456 {
457  return m_low;
458 }
459 
460 void
462 {
463  NS_LOG_FUNCTION (this << low);
464  m_low = low;
465 }
466 
467 bool
469 {
470  NS_LOG_FUNCTION (this);
471  return !m_queue->IsEmpty () || m_currentPacket != 0 || m_baManager->HasPackets ();
472 }
473 
475 {
476  return m_txMiddle->GetNextSequenceNumberfor (hdr);
477 }
478 
480 {
482 }
483 
485 EdcaTxopN::PeekNextRetransmitPacket (WifiMacHeader &header,Mac48Address recipient, uint8_t tid, Time *timestamp)
486 {
487  return m_baManager->PeekNextPacketByTidAndAddress (header,recipient,tid, timestamp);
488 }
489 
490 void
491 EdcaTxopN::RemoveRetransmitPacket (uint8_t tid, Mac48Address recipient, uint16_t seqnumber)
492 {
493  m_baManager->RemovePacket (tid, recipient, seqnumber);
494 }
495 
496 void
498 {
499  NS_LOG_FUNCTION (this);
501  if (m_currentPacket == 0)
502  {
503  if (m_queue->IsEmpty () && !m_baManager->HasPackets ())
504  {
505  NS_LOG_DEBUG ("queue is empty");
506  return;
507  }
509  {
511  return;
512  }
513  /* check if packets need retransmission are stored in BlockAckManager */
515  if (m_currentPacket == 0)
516  {
517  if (m_queue->PeekFirstAvailable (&m_currentHdr, m_currentPacketTimestamp, m_qosBlockedDestinations) == 0)
518  {
519  NS_LOG_DEBUG ("no available packets in the queue");
520  return;
521  }
524  && SetupBlockAckIfNeeded ())
525  {
526  return;
527  }
529  NS_ASSERT (m_currentPacket != 0);
530 
531  uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr);
532  m_currentHdr.SetSequenceNumber (sequence);
537  m_fragmentNumber = 0;
538  NS_LOG_DEBUG ("dequeued size=" << m_currentPacket->GetSize () <<
539  ", to=" << m_currentHdr.GetAddr1 () <<
540  ", seq=" << m_currentHdr.GetSequenceControl ());
542  {
543  VerifyBlockAck ();
544  }
545  }
546  }
548  params.DisableOverrideDurationId ();
549  if (m_currentHdr.GetAddr1 ().IsGroup ())
550  {
551  params.DisableRts ();
552  params.DisableAck ();
553  params.DisableNextData ();
555  &m_currentHdr,
556  params,
558 
559  NS_LOG_DEBUG ("tx broadcast");
560  }
562  {
564  }
565  else
566  {
568  {
569  params.DisableAck ();
570  }
571  else
572  {
573  params.EnableAck ();
574  }
576  || (m_currentHdr.IsData () && !m_currentHdr.IsQosData ()))
578  && NeedFragmentation ())
579  {
580  //With COMPRESSED_BLOCK_ACK fragmentation must be avoided.
581  params.DisableRts ();
582  WifiMacHeader hdr;
583  Ptr<Packet> fragment = GetFragmentPacket (&hdr);
584  if (IsLastFragment ())
585  {
586  NS_LOG_DEBUG ("fragmenting last fragment size=" << fragment->GetSize ());
587  params.DisableNextData ();
588  }
589  else
590  {
591  NS_LOG_DEBUG ("fragmenting size=" << fragment->GetSize ());
593  }
594  m_low->StartTransmission (fragment, &hdr, params,
596  }
597  else
598  {
599  WifiMacHeader peekedHdr;
600  Time tstamp;
601  if (m_currentHdr.IsQosData ()
602  && m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (),
605  && m_msduAggregator != 0 && !m_currentHdr.IsRetry ())
606  {
607  /* here is performed aggregation */
608  Ptr<Packet> currentAggregatedPacket = Create<Packet> ();
609  m_msduAggregator->Aggregate (m_currentPacket, currentAggregatedPacket,
610  MapSrcAddressForAggregation (peekedHdr),
611  MapDestAddressForAggregation (peekedHdr));
612  bool aggregated = false;
613  bool isAmsdu = false;
614  Ptr<const Packet> peekedPacket = m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (),
616  m_currentHdr.GetAddr1 (), &tstamp);
617  while (peekedPacket != 0)
618  {
619  aggregated = m_msduAggregator->Aggregate (peekedPacket, currentAggregatedPacket,
620  MapSrcAddressForAggregation (peekedHdr),
621  MapDestAddressForAggregation (peekedHdr));
622  if (aggregated)
623  {
624  isAmsdu = true;
625  m_queue->Remove (peekedPacket);
626  }
627  else
628  {
629  break;
630  }
631  peekedPacket = m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (),
633  }
634  if (isAmsdu)
635  {
638  m_currentPacket = currentAggregatedPacket;
639  currentAggregatedPacket = 0;
640  NS_LOG_DEBUG ("tx unicast A-MSDU");
641  }
642  }
643  params.DisableNextData ();
646  params, m_transmissionListener);
648  {
649  CompleteTx ();
650  }
651  }
652  }
653 }
654 
656 {
657  NS_LOG_FUNCTION (this);
658  bool resetDcf = false;
659  // If an internal collision is experienced, the frame involved may still
660  // be sitting in the queue, and m_currentPacket may still be null.
661  Ptr<const Packet> packet;
662  WifiMacHeader header;
663  if (m_currentPacket == 0)
664  {
665  packet = m_queue->Peek (&header);
666  NS_ASSERT_MSG (packet, "Internal collision but no packet in queue");
667  }
668  else
669  {
670  packet = m_currentPacket;
671  header = m_currentHdr;
672  }
674  {
675  if (!NeedRtsRetransmission (packet, header))
676  {
677  resetDcf = true;
678  m_stationManager->ReportFinalRtsFailed (header.GetAddr1 (), &header);
679  }
680  else
681  {
682  m_stationManager->ReportRtsFailed (header.GetAddr1 (), &header);
683  }
684  }
685  else if (header.GetAddr1 () == Mac48Address::GetBroadcast ())
686  {
687  resetDcf = false;
688  }
689  else
690  {
691  if (!NeedDataRetransmission (packet, header))
692  {
693  resetDcf = true;
694  m_stationManager->ReportFinalDataFailed (header.GetAddr1 (), &header);
695  }
696  else
697  {
698  m_stationManager->ReportDataFailed (header.GetAddr1 (), &header);
699  }
700  }
701  if (resetDcf)
702  {
703  NS_LOG_DEBUG ("reset DCF");
704  if (!m_txFailedCallback.IsNull ())
705  {
706  m_txFailedCallback (header);
707  }
708  //to reset the dcf.
709  if (m_currentPacket)
710  {
711  NS_LOG_DEBUG ("Discarding m_currentPacket");
712  m_currentPacket = 0;
713  }
714  else
715  {
716  NS_LOG_DEBUG ("Dequeueing and discarding head of queue");
717  packet = m_queue->Peek (&header);
718  }
719  m_dcf->ResetCw ();
720  }
721  else
722  {
723  m_dcf->UpdateFailedCw ();
724  }
725  m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ());
728 }
729 
730 void
732 {
733  NS_LOG_FUNCTION (this);
734  m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ());
737 }
738 
739 void
740 EdcaTxopN::GotCts (double snr, WifiMode txMode)
741 {
742  NS_LOG_FUNCTION (this << snr << txMode);
743  NS_LOG_DEBUG ("got cts");
744 }
745 
746 uint8_t
748 {
749  NS_LOG_FUNCTION (this);
750  if (m_currentHdr.IsQosData ())
751  {
752  return m_currentHdr.GetQosTid ();
753  }
754  else if (m_currentHdr.IsBlockAckReq ())
755  {
756  CtrlBAckRequestHeader baReqHdr;
757  m_currentPacket->PeekHeader (baReqHdr);
758  return baReqHdr.GetTidInfo ();
759  }
760  else if (m_currentHdr.IsBlockAck ())
761  {
762  CtrlBAckResponseHeader baRespHdr;
763  m_currentPacket->PeekHeader (baRespHdr);
764  return baRespHdr.GetTidInfo ();
765  }
766  else if (m_currentHdr.IsMgt () && m_currentHdr.IsAction ())
767  {
768  Ptr<Packet> packet = m_currentPacket->Copy ();
769  WifiActionHeader actionHdr;
770  packet->RemoveHeader (actionHdr);
771 
772  if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK)
773  {
774  switch (actionHdr.GetAction ().blockAck)
775  {
777  {
778  MgtAddBaResponseHeader reqHdr;
779  packet->RemoveHeader (reqHdr);
780  return reqHdr.GetTid ();
781  }
783  {
784  MgtAddBaResponseHeader respHdr;
785  packet->RemoveHeader (respHdr);
786  return respHdr.GetTid ();
787  }
789  {
790  MgtDelBaHeader delHdr;
791  packet->RemoveHeader (delHdr);
792  return delHdr.GetTid ();
793  }
794  default:
795  {
796  NS_FATAL_ERROR ("Don't know how to extract Traffic ID from this BA action frame");
797  }
798  }
799  }
800  else
801  {
802  NS_FATAL_ERROR ("Don't know how to extract Traffic ID from this action frame");
803  }
804  }
805  else
806  {
807  NS_FATAL_ERROR ("Current packet has no Traffic ID");
808  }
809 }
810 
811 void
813 {
814  NS_LOG_FUNCTION (this);
815  NS_LOG_DEBUG ("missed cts");
817  {
818  NS_LOG_DEBUG ("Cts Fail");
819  bool resetCurrentPacket = true;
821  if (!m_txFailedCallback.IsNull ())
822  {
824  }
826  {
828  uint8_t tid = GetCurrentTid ();
829 
831  {
832  NS_LOG_DEBUG ("Transmit Block Ack Request");
833  CtrlBAckRequestHeader reqHdr;
834  reqHdr.SetType (COMPRESSED_BLOCK_ACK);
836  reqHdr.SetTidInfo (tid);
837  reqHdr.SetHtImmediateAck (true);
838  Ptr<Packet> bar = Create<Packet> ();
839  bar->AddHeader (reqHdr);
840  Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ());
841  m_currentBar = request;
842  WifiMacHeader hdr;
844  hdr.SetAddr1 (request.recipient);
845  hdr.SetAddr2 (m_low->GetAddress ());
846  hdr.SetAddr3 (m_low->GetBssid ());
847  hdr.SetDsNotTo ();
848  hdr.SetDsNotFrom ();
849  hdr.SetNoRetry ();
850  hdr.SetNoMoreFragments ();
851  m_currentPacket = request.bar;
852  m_currentHdr = hdr;
853  resetCurrentPacket = false;
854  }
855  }
856  //to reset the dcf.
857  if (resetCurrentPacket == true)
858  {
859  m_currentPacket = 0;
860  }
861  m_dcf->ResetCw ();
862  m_cwTrace = m_dcf->GetCw ();
863  }
864  else
865  {
866  m_dcf->UpdateFailedCw ();
867  m_cwTrace = m_dcf->GetCw ();
868  }
869  m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ());
872 }
873 
874 void
876 {
877  NS_LOG_FUNCTION (this);
878  m_queue->Flush ();
879  m_currentPacket = 0;
880 }
881 
882 void
884 {
885  NS_LOG_FUNCTION (this);
886  if (m_currentPacket != 0)
887  {
888  m_queue->PushFront (m_currentPacket, m_currentHdr);
889  m_currentPacket = 0;
890  }
891 }
892 
893 void
895 {
896  NS_LOG_FUNCTION (this);
898 }
899 
900 void
902 {
903  NS_LOG_FUNCTION (this << packet << &hdr);
904  m_stationManager->PrepareForQueue (hdr.GetAddr1 (), &hdr, packet);
905  m_queue->Enqueue (packet, hdr);
907 }
908 
909 void
910 EdcaTxopN::GotAck (double snr, WifiMode txMode)
911 {
912  NS_LOG_FUNCTION (this << snr << txMode);
913  if (!NeedFragmentation ()
914  || IsLastFragment ()
915  || m_currentHdr.IsQosAmsdu ())
916  {
917  NS_LOG_DEBUG ("got ack. tx done.");
918  if (!m_txOkCallback.IsNull ())
919  {
921  }
922 
923  if (m_currentHdr.IsAction ())
924  {
925  WifiActionHeader actionHdr;
927  p->RemoveHeader (actionHdr);
928  if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK
930  {
931  MgtDelBaHeader delBa;
932  p->PeekHeader (delBa);
933  if (delBa.IsByOriginator ())
934  {
936  }
937  else
938  {
940  }
941  }
942  }
943  m_currentPacket = 0;
944  m_dcf->ResetCw ();
945  if (!HasTxop ())
946  {
947  m_cwTrace = m_dcf->GetCw ();
948  m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ());
951  }
952  }
953  else
954  {
955  NS_LOG_DEBUG ("got ack. tx not done, size=" << m_currentPacket->GetSize ());
956  }
957 }
958 
959 void
961 {
962  NS_LOG_FUNCTION (this);
963  NS_LOG_DEBUG ("missed ack");
965  {
966  NS_LOG_DEBUG ("Ack Fail");
968  bool resetCurrentPacket = true;
969  if (!m_txFailedCallback.IsNull ())
970  {
972  }
974  {
975  uint8_t tid = GetCurrentTid ();
976 
978  {
979  //send Block ACK Request in order to shift WinStart at the receiver
980  NS_LOG_DEBUG ("Transmit Block Ack Request");
981  CtrlBAckRequestHeader reqHdr;
982  reqHdr.SetType (COMPRESSED_BLOCK_ACK);
984  reqHdr.SetTidInfo (tid);
985  reqHdr.SetHtImmediateAck (true);
986  Ptr<Packet> bar = Create<Packet> ();
987  bar->AddHeader (reqHdr);
988  Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ());
989  m_currentBar = request;
990  WifiMacHeader hdr;
992  hdr.SetAddr1 (request.recipient);
993  hdr.SetAddr2 (m_low->GetAddress ());
994  hdr.SetAddr3 (m_low->GetBssid ());
995  hdr.SetDsNotTo ();
996  hdr.SetDsNotFrom ();
997  hdr.SetNoRetry ();
998  hdr.SetNoMoreFragments ();
999  m_currentPacket = request.bar;
1000  m_currentHdr = hdr;
1001  resetCurrentPacket = false;
1002  }
1003  }
1004  //to reset the dcf.
1005  if (resetCurrentPacket == true)
1006  {
1007  m_currentPacket = 0;
1008  }
1009  m_dcf->ResetCw ();
1010  m_cwTrace = m_dcf->GetCw ();
1011  }
1012  else
1013  {
1014  NS_LOG_DEBUG ("Retransmit");
1016  m_dcf->UpdateFailedCw ();
1017  m_cwTrace = m_dcf->GetCw ();
1018  }
1019  m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ());
1022 }
1023 
1024 void
1025 EdcaTxopN::MissedBlockAck (uint32_t nMpdus)
1026 {
1027  NS_LOG_FUNCTION (this);
1028  NS_LOG_DEBUG ("missed block ack");
1029  uint8_t tid = GetCurrentTid ();
1031  {
1032  m_stationManager->ReportAmpduTxStatus (m_currentHdr.GetAddr1 (), tid, 0, nMpdus, 0, 0);
1033  }
1034  if (NeedBarRetransmission ())
1035  {
1037  {
1038  //should i report this to station addressed by ADDR1?
1039  NS_LOG_DEBUG ("Retransmit block ack request");
1041  }
1042  else
1043  {
1044  //standard says when loosing a BlockAck originator may send a BAR page 139
1045  NS_LOG_DEBUG ("Transmit Block Ack Request");
1046  CtrlBAckRequestHeader reqHdr;
1047  reqHdr.SetType (COMPRESSED_BLOCK_ACK);
1048  if (m_currentHdr.IsQosData ())
1049  {
1051  }
1052  else if (m_currentHdr.IsBlockAckReq ())
1053  {
1054  CtrlBAckRequestHeader baReqHdr;
1055  m_currentPacket->PeekHeader (baReqHdr);
1056  reqHdr.SetStartingSequence (baReqHdr.GetStartingSequence ());
1057  }
1058  else if (m_currentHdr.IsBlockAck ())
1059  {
1060  CtrlBAckResponseHeader baRespHdr;
1061  m_currentPacket->PeekHeader (baRespHdr);
1063  }
1064  reqHdr.SetTidInfo (tid);
1065  reqHdr.SetHtImmediateAck (true);
1066  Ptr<Packet> bar = Create<Packet> ();
1067  bar->AddHeader (reqHdr);
1068  Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ());
1069  m_currentBar = request;
1070  WifiMacHeader hdr;
1072  hdr.SetAddr1 (request.recipient);
1073  hdr.SetAddr2 (m_low->GetAddress ());
1074  hdr.SetAddr3 (m_low->GetBssid ());
1075  hdr.SetDsNotTo ();
1076  hdr.SetDsNotFrom ();
1077  hdr.SetNoRetry ();
1078  hdr.SetNoMoreFragments ();
1079 
1080  m_currentPacket = request.bar;
1081  m_currentHdr = hdr;
1082  }
1083  m_dcf->UpdateFailedCw ();
1084  m_cwTrace = m_dcf->GetCw ();
1085  }
1086  else
1087  {
1088  NS_LOG_DEBUG ("Block Ack Request Fail");
1089  //to reset the dcf.
1090  m_currentPacket = 0;
1091  m_dcf->ResetCw ();
1092  m_cwTrace = m_dcf->GetCw ();
1093  }
1094  m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ());
1097 }
1098 
1101 {
1102  return m_msduAggregator;
1103 }
1104 
1107 {
1108  return m_mpduAggregator;
1109 }
1110 
1111 void
1113 {
1114  NS_LOG_FUNCTION (this);
1115  if ((m_currentPacket != 0
1116  || !m_queue->IsEmpty () || m_baManager->HasPackets ())
1117  && !m_dcf->IsAccessRequested ())
1118  {
1119  Ptr<const Packet> packet;
1120  WifiMacHeader hdr;
1121  if (m_currentPacket != 0)
1122  {
1123  packet = m_currentPacket;
1124  hdr = m_currentHdr;
1125  }
1126  else if (m_baManager->HasPackets ())
1127  {
1128  packet = m_baManager->PeekNextPacket (hdr);
1129  }
1130  else if (m_queue->PeekFirstAvailable (&hdr, m_currentPacketTimestamp, m_qosBlockedDestinations) != 0)
1131  {
1132  packet = m_queue->PeekFirstAvailable (&hdr, m_currentPacketTimestamp, m_qosBlockedDestinations);
1133  }
1134  if (packet != 0)
1135  {
1136  m_isAccessRequestedForRts = m_stationManager->NeedRts (hdr.GetAddr1 (), &hdr, packet, m_low->GetDataTxVector (packet, &hdr));
1137  }
1138  else
1139  {
1140  m_isAccessRequestedForRts = false;
1141  }
1143  }
1144 }
1145 
1146 void
1148 {
1149  NS_LOG_FUNCTION (this);
1150  if (m_currentPacket == 0
1151  && (!m_queue->IsEmpty () || m_baManager->HasPackets ())
1152  && !m_dcf->IsAccessRequested ())
1153  {
1154  Ptr<const Packet> packet;
1155  WifiMacHeader hdr;
1156  if (m_currentPacket != 0)
1157  {
1158  packet = m_currentPacket;
1159  hdr = m_currentHdr;
1160  }
1161  else if (m_baManager->HasPackets ())
1162  {
1163  packet = m_baManager->PeekNextPacket (hdr);
1164  }
1165  else if (m_queue->PeekFirstAvailable (&hdr, m_currentPacketTimestamp, m_qosBlockedDestinations) != 0)
1166  {
1167  packet = m_queue->PeekFirstAvailable (&hdr, m_currentPacketTimestamp, m_qosBlockedDestinations);
1168  }
1169  if (packet != 0)
1170  {
1171  m_isAccessRequestedForRts = m_stationManager->NeedRts (hdr.GetAddr1 (), &hdr, packet, m_low->GetDataTxVector (packet, &hdr));
1172  }
1173  else
1174  {
1175  m_isAccessRequestedForRts = false;
1176  }
1178  }
1179 }
1180 
1181 bool
1183 {
1184  NS_LOG_FUNCTION (this);
1185  return m_stationManager->NeedRtsRetransmission (hdr.GetAddr1 (), &hdr, packet);
1186 }
1187 
1188 bool
1190 {
1191  NS_LOG_FUNCTION (this);
1192  return m_stationManager->NeedDataRetransmission (hdr.GetAddr1 (), &hdr, packet);
1193 }
1194 
1195 bool
1197 {
1198  uint8_t tid = 0;
1199  uint16_t seqNumber = 0;
1200  if (m_currentHdr.IsQosData ())
1201  {
1202  tid = m_currentHdr.GetQosTid ();
1203  seqNumber = m_currentHdr.GetSequenceNumber ();
1204  }
1205  else if (m_currentHdr.IsBlockAckReq ())
1206  {
1207  CtrlBAckRequestHeader baReqHdr;
1208  m_currentPacket->PeekHeader (baReqHdr);
1209  tid = baReqHdr.GetTidInfo ();
1210  seqNumber = baReqHdr.GetStartingSequence ();
1211  }
1212  else if (m_currentHdr.IsBlockAck ())
1213  {
1214  CtrlBAckResponseHeader baRespHdr;
1215  m_currentPacket->PeekHeader (baRespHdr);
1216  tid = baRespHdr.GetTidInfo ();
1217  seqNumber = m_currentHdr.GetSequenceNumber ();
1218  }
1219  return m_baManager->NeedBarRetransmission (tid, seqNumber, m_currentHdr.GetAddr1 ());
1220 }
1221 
1222 void
1224 {
1225  NS_LOG_FUNCTION (this);
1226  m_fragmentNumber++;
1227 }
1228 
1229 void
1231 {
1232  NS_LOG_FUNCTION (this);
1233  NS_LOG_DEBUG ("start next packet fragment");
1234  /* this callback is used only for fragments. */
1235  NextFragment ();
1236  WifiMacHeader hdr;
1237  Ptr<Packet> fragment = GetFragmentPacket (&hdr);
1239  params.EnableAck ();
1240  params.DisableRts ();
1241  params.DisableOverrideDurationId ();
1242  if (IsLastFragment ())
1243  {
1244  params.DisableNextData ();
1245  }
1246  else
1247  {
1248  params.EnableNextData (GetNextFragmentSize ());
1249  }
1250  Low ()->StartTransmission (fragment, &hdr, params, m_transmissionListener);
1251 }
1252 
1253 void
1255 {
1256  NS_LOG_FUNCTION (this);
1257  WifiMacHeader hdr;
1258  Time tstamp;
1259 
1260  Ptr<const Packet> peekedPacket = m_queue->PeekByTidAndAddress (&hdr,
1264  &tstamp);
1265  if (peekedPacket == 0)
1266  {
1267  return;
1268  }
1269 
1271  params.DisableOverrideDurationId ();
1273  {
1274  params.DisableAck ();
1275  }
1276  else
1277  {
1278  params.EnableAck ();
1279  }
1280 
1281  WifiTxVector dataTxVector = m_stationManager->GetDataTxVector (m_currentHdr.GetAddr1 (), &m_currentHdr, peekedPacket);
1282  if (m_stationManager->NeedRts (m_currentHdr.GetAddr1 (), &m_currentHdr, peekedPacket, dataTxVector))
1283  {
1284  params.EnableRts ();
1285  }
1286  else
1287  {
1288  params.DisableRts ();
1289  }
1290 
1291  if (GetTxopRemaining () >= Low ()->CalculateOverallTxTime (peekedPacket, &hdr, params))
1292  {
1293  NS_LOG_DEBUG ("start next packet");
1294  m_currentPacket = m_queue->DequeueByTidAndAddress (&hdr,
1297  m_currentHdr.GetAddr1 ());
1299  }
1300 }
1301 
1302 Time
1304 {
1305  Time remainingTxop = GetTxopLimit ();
1306  remainingTxop -= (Simulator::Now () - m_startTxop);
1307  if (remainingTxop < MicroSeconds (0))
1308  {
1309  remainingTxop = MicroSeconds (0);
1310  }
1311  NS_LOG_FUNCTION (this << remainingTxop);
1312  return remainingTxop;
1313 }
1314 
1315 bool
1317 {
1318  NS_LOG_FUNCTION (this);
1319  WifiMacHeader hdr;
1320  Time tstamp;
1321  if (!m_currentHdr.IsQosData ())
1322  {
1323  return false;
1324  }
1325 
1326  Ptr<const Packet> peekedPacket = m_queue->PeekByTidAndAddress (&hdr,
1330  &tstamp);
1331  if (peekedPacket == 0)
1332  {
1333  return false;
1334  }
1335 
1337  params.DisableOverrideDurationId ();
1339  {
1340  params.DisableAck ();
1341  }
1342  else
1343  {
1344  params.EnableAck ();
1345  }
1346 
1347  WifiTxVector dataTxVector = m_stationManager->GetDataTxVector (m_currentHdr.GetAddr1 (), &m_currentHdr, peekedPacket);
1348  if (m_stationManager->NeedRts (m_currentHdr.GetAddr1 (), &m_currentHdr, peekedPacket, dataTxVector))
1349  {
1350  params.EnableRts ();
1351  }
1352  else
1353  {
1354  params.DisableRts ();
1355  }
1356 
1357  return (GetTxopRemaining () >= Low ()->CalculateOverallTxTime (peekedPacket, &hdr, params));
1358 }
1359 
1360 void
1362 {
1363  NS_LOG_FUNCTION (this);
1364  NS_LOG_DEBUG ("transmission cancelled");
1365 }
1366 
1367 void
1369 {
1370  NS_LOG_FUNCTION (this);
1371  NS_LOG_DEBUG ("a transmission that did not require an ACK just finished");
1372  m_currentPacket = 0;
1373  m_dcf->ResetCw ();
1374  m_cwTrace = m_dcf->GetCw ();
1375  m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ());
1378 }
1379 
1380 bool
1382 {
1383  NS_LOG_FUNCTION (this);
1387  && m_currentHdr.IsQosData ()
1390  {
1391  //MSDU is not fragmented when it is transmitted using an HT-immediate or
1392  //HT-delayed Block Ack agreement or when it is carried in an A-MPDU.
1393  return false;
1394  }
1396  m_currentPacket);
1397 }
1398 
1399 uint32_t
1401 {
1402  NS_LOG_FUNCTION (this);
1405 }
1406 
1407 uint32_t
1409 {
1410  NS_LOG_FUNCTION (this);
1413 }
1414 
1415 uint32_t
1417 {
1418  NS_LOG_FUNCTION (this);
1421 }
1422 
1423 
1424 bool
1426 {
1427  NS_LOG_FUNCTION (this);
1430 }
1431 
1434 {
1435  NS_LOG_FUNCTION (this << hdr);
1436  *hdr = m_currentHdr;
1438  uint32_t startOffset = GetFragmentOffset ();
1439  Ptr<Packet> fragment;
1440  if (IsLastFragment ())
1441  {
1442  hdr->SetNoMoreFragments ();
1443  }
1444  else
1445  {
1446  hdr->SetMoreFragments ();
1447  }
1448  fragment = m_currentPacket->CreateFragment (startOffset,
1449  GetFragmentSize ());
1450  return fragment;
1451 }
1452 
1453 void
1455 {
1456  NS_LOG_FUNCTION (this << static_cast<uint32_t> (ac));
1457  m_ac = ac;
1458 }
1459 
1462 {
1463  NS_LOG_FUNCTION (this << &hdr);
1464  Mac48Address retval;
1466  {
1467  retval = hdr.GetAddr2 ();
1468  }
1469  else
1470  {
1471  retval = hdr.GetAddr3 ();
1472  }
1473  return retval;
1474 }
1475 
1478 {
1479  NS_LOG_FUNCTION (this << &hdr);
1480  Mac48Address retval;
1482  {
1483  retval = hdr.GetAddr1 ();
1484  }
1485  else
1486  {
1487  retval = hdr.GetAddr3 ();
1488  }
1489  return retval;
1490 }
1491 
1492 void
1494 {
1495  NS_LOG_FUNCTION (this << aggr);
1496  m_msduAggregator = aggr;
1497 }
1498 
1499 void
1501 {
1502  NS_LOG_FUNCTION (this << aggr);
1503  m_mpduAggregator = aggr;
1504 }
1505 
1506 void
1508 {
1509  NS_LOG_FUNCTION (this << packet << &hdr);
1510  WifiMacTrailer fcs;
1511  m_stationManager->PrepareForQueue (hdr.GetAddr1 (), &hdr, packet);
1512  m_queue->PushFront (packet, hdr);
1514 }
1515 
1516 void
1518 {
1519  NS_LOG_FUNCTION (this << respHdr << recipient);
1520  NS_LOG_DEBUG ("received ADDBA response from " << recipient);
1521  uint8_t tid = respHdr->GetTid ();
1523  {
1524  if (respHdr->GetStatusCode ().IsSuccess ())
1525  {
1526  NS_LOG_DEBUG ("block ack agreement established with " << recipient);
1527  m_baManager->UpdateAgreement (respHdr, recipient);
1528  }
1529  else
1530  {
1531  NS_LOG_DEBUG ("discard ADDBA response" << recipient);
1532  m_baManager->NotifyAgreementUnsuccessful (recipient, tid);
1533  }
1534  }
1536 }
1537 
1538 void
1540 {
1541  NS_LOG_FUNCTION (this << delBaHdr << recipient);
1542  NS_LOG_DEBUG ("received DELBA frame from=" << recipient);
1543  m_baManager->TearDownBlockAck (recipient, delBaHdr->GetTid ());
1544 }
1545 
1546 void
1547 EdcaTxopN::GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address recipient, double rxSnr, WifiMode txMode, double dataSnr)
1548 {
1549  NS_LOG_FUNCTION (this << blockAck << recipient << rxSnr << txMode.GetUniqueName () << dataSnr);
1550  NS_LOG_DEBUG ("got block ack from=" << recipient);
1551  m_baManager->NotifyGotBlockAck (blockAck, recipient, rxSnr, txMode, dataSnr);
1552  if (!m_txOkCallback.IsNull ())
1553  {
1555  }
1556  m_currentPacket = 0;
1557  m_dcf->ResetCw ();
1558  m_cwTrace = m_dcf->GetCw ();
1559  m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ());
1562 }
1563 
1564 void
1566 {
1567  NS_LOG_FUNCTION (this);
1568  uint8_t tid = m_currentHdr.GetQosTid ();
1569  Mac48Address recipient = m_currentHdr.GetAddr1 ();
1570  uint16_t sequence = m_currentHdr.GetSequenceNumber ();
1572  {
1573  m_baManager->SwitchToBlockAckIfNeeded (recipient, tid, sequence);
1574  }
1576  {
1578  }
1579 }
1580 
1582 {
1583  NS_LOG_FUNCTION (this << dest);
1584  if (m_aMpduEnabled.find (dest) != m_aMpduEnabled.end ())
1585  {
1586  return m_aMpduEnabled.find (dest)->second;
1587  }
1588  return false;
1589 }
1590 
1591 void EdcaTxopN::SetAmpduExist (Mac48Address dest, bool enableAmpdu)
1592 {
1593  NS_LOG_FUNCTION (this << dest << enableAmpdu);
1594  if (m_aMpduEnabled.find (dest) != m_aMpduEnabled.end () && m_aMpduEnabled.find (dest)->second != enableAmpdu)
1595  {
1596  m_aMpduEnabled.erase (m_aMpduEnabled.find (dest));
1597  }
1598  if (m_aMpduEnabled.find (dest) == m_aMpduEnabled.end ())
1599  {
1600  m_aMpduEnabled.insert (std::make_pair (dest, enableAmpdu));
1601  }
1602 }
1603 
1604 void
1606 {
1607  NS_LOG_FUNCTION (this);
1609  {
1610  if (!m_currentHdr.IsRetry ())
1611  {
1613  }
1617  }
1618 }
1619 
1620 void
1622 {
1623  NS_ASSERT (hdr.IsQosData ());
1624  m_baManager->StorePacket (packet, hdr, tstamp);
1628 }
1629 
1630 bool
1632 {
1633  NS_LOG_FUNCTION (this);
1634  uint8_t tid = m_currentHdr.GetQosTid ();
1635  Mac48Address recipient = m_currentHdr.GetAddr1 ();
1636 
1637  uint32_t packets = m_queue->GetNPacketsByTidAndAddress (tid, WifiMacHeader::ADDR1, recipient);
1638 
1639  if ((m_blockAckThreshold > 0 && packets >= m_blockAckThreshold) || (packets > 1 && m_mpduAggregator != 0) || m_stationManager->HasVhtSupported ())
1640  {
1641  /* Block ack setup */
1642  uint16_t startingSequence = m_txMiddle->GetNextSeqNumberByTidAndAddress (tid, recipient);
1643  SendAddBaRequest (recipient, tid, startingSequence, m_blockAckInactivityTimeout, true);
1644  return true;
1645  }
1646  return false;
1647 }
1648 
1649 void
1651 {
1652  NS_LOG_FUNCTION (this << &bar);
1653  WifiMacHeader hdr;
1655  hdr.SetAddr1 (bar.recipient);
1656  hdr.SetAddr2 (m_low->GetAddress ());
1657  hdr.SetAddr3 (m_low->GetBssid ());
1658  hdr.SetDsNotTo ();
1659  hdr.SetDsNotFrom ();
1660  hdr.SetNoRetry ();
1661  hdr.SetNoMoreFragments ();
1662 
1663  m_currentPacket = bar.bar;
1664  m_currentHdr = hdr;
1665 
1667  params.DisableRts ();
1668  params.DisableNextData ();
1669  params.DisableOverrideDurationId ();
1670  if (bar.immediate)
1671  {
1673  {
1674  params.EnableBasicBlockAck ();
1675  }
1677  {
1678  params.EnableCompressedBlockAck ();
1679  }
1680  else if (m_blockAckType == MULTI_TID_BLOCK_ACK)
1681  {
1682  NS_FATAL_ERROR ("Multi-tid block ack is not supported");
1683  }
1684  }
1685  else
1686  {
1687  //Delayed block ack
1688  params.EnableAck ();
1689  }
1691 }
1692 
1693 void
1695 {
1696  NS_LOG_FUNCTION (this);
1700 }
1701 
1702 void
1704 {
1705  NS_LOG_FUNCTION (this << static_cast<uint32_t> (threshold));
1706  m_blockAckThreshold = threshold;
1707  m_baManager->SetBlockAckThreshold (threshold);
1708 }
1709 
1710 void
1712 {
1713  NS_LOG_FUNCTION (this << timeout);
1715 }
1716 
1717 uint8_t
1719 {
1720  NS_LOG_FUNCTION (this);
1721  return m_blockAckThreshold;
1722 }
1723 
1724 void
1725 EdcaTxopN::SendAddBaRequest (Mac48Address dest, uint8_t tid, uint16_t startSeq,
1726  uint16_t timeout, bool immediateBAck)
1727 {
1728  NS_LOG_FUNCTION (this << dest << static_cast<uint32_t> (tid) << startSeq << timeout << immediateBAck);
1729  NS_LOG_DEBUG ("sent ADDBA request to " << dest);
1730  WifiMacHeader hdr;
1731  hdr.SetAction ();
1732  hdr.SetAddr1 (dest);
1733  hdr.SetAddr2 (m_low->GetAddress ());
1734  hdr.SetAddr3 (m_low->GetAddress ());
1735  hdr.SetDsNotTo ();
1736  hdr.SetDsNotFrom ();
1737 
1738  WifiActionHeader actionHdr;
1741  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
1742 
1743  Ptr<Packet> packet = Create<Packet> ();
1744  /*Setting ADDBARequest header*/
1745  MgtAddBaRequestHeader reqHdr;
1746  reqHdr.SetAmsduSupport (true);
1747  if (immediateBAck)
1748  {
1749  reqHdr.SetImmediateBlockAck ();
1750  }
1751  else
1752  {
1753  reqHdr.SetDelayedBlockAck ();
1754  }
1755  reqHdr.SetTid (tid);
1756  /* For now we don't use buffer size field in the ADDBA request frame. The recipient
1757  * will choose how many packets it can receive under block ack.
1758  */
1759  reqHdr.SetBufferSize (0);
1760  reqHdr.SetTimeout (timeout);
1761  reqHdr.SetStartingSequence (startSeq);
1762 
1763  m_baManager->CreateAgreement (&reqHdr, dest);
1764 
1765  packet->AddHeader (reqHdr);
1766  packet->AddHeader (actionHdr);
1767 
1768  m_currentPacket = packet;
1769  m_currentHdr = hdr;
1770 
1771  uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr);
1772  m_currentHdr.SetSequenceNumber (sequence);
1777 
1779  params.EnableAck ();
1780  params.DisableRts ();
1781  params.DisableNextData ();
1782  params.DisableOverrideDurationId ();
1783 
1786 }
1787 
1788 void
1789 EdcaTxopN::SendDelbaFrame (Mac48Address addr, uint8_t tid, bool byOriginator)
1790 {
1791  NS_LOG_FUNCTION (this << addr << static_cast<uint32_t> (tid) << byOriginator);
1792  WifiMacHeader hdr;
1793  hdr.SetAction ();
1794  hdr.SetAddr1 (addr);
1795  hdr.SetAddr2 (m_low->GetAddress ());
1796  hdr.SetAddr3 (m_low->GetAddress ());
1797  hdr.SetDsNotTo ();
1798  hdr.SetDsNotFrom ();
1799 
1800  MgtDelBaHeader delbaHdr;
1801  delbaHdr.SetTid (tid);
1802  if (byOriginator)
1803  {
1804  delbaHdr.SetByOriginator ();
1805  }
1806  else
1807  {
1808  delbaHdr.SetByRecipient ();
1809  }
1810 
1811  WifiActionHeader actionHdr;
1814  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
1815 
1816  Ptr<Packet> packet = Create<Packet> ();
1817  packet->AddHeader (delbaHdr);
1818  packet->AddHeader (actionHdr);
1819 
1820  PushFront (packet, hdr);
1821 }
1822 
1823 int64_t
1825 {
1826  NS_LOG_FUNCTION (this << stream);
1827  m_rng->AssignStreams (stream);
1828  return 1;
1829 }
1830 
1831 void
1833 {
1834  NS_LOG_FUNCTION (this);
1835  m_dcf->ResetCw ();
1836  m_cwTrace = m_dcf->GetCw ();
1837  m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ());
1840 }
1841 
1842 void
1844 {
1845  NS_LOG_FUNCTION (this << hdr);
1846  if (!m_txOkCallback.IsNull ())
1847  {
1849  }
1850 }
1851 
1852 void
1854 {
1855  NS_LOG_FUNCTION (this << hdr);
1856  if (!m_txFailedCallback.IsNull ())
1857  {
1859  }
1860 }
1861 
1862 } //namespace ns3
virtual 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:189
Keep track of destination address - TID pairs that are waiting for a block ACK response.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
void SetAction()
Set Type/Subtype values for an action header.
void SetRetry(void)
Set the Retry bit in the Frame Control field.
void SetUnblockDestinationCallback(Callback< void, Mac48Address, uint8_t > callback)
virtual void SetMaxCw(uint32_t maxCw)
Set the maximum contention window size.
Definition: edca-txop-n.cc:399
void SetTxopLimit(Time txopLimit)
Set the TXOP limit.
Definition: dcf-manager.cc:62
void SetMoreFragments(void)
Set the More Fragment bit in the Frame Control field.
virtual void DoInitialize(void)
Initialize() implementation.
Definition: object.cc:353
void SetType(enum BlockAckType type)
Set the block ACK type.
TransmissionListener * m_transmissionListener
Definition: edca-txop-n.h:568
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
void NotifyGotBlockAck(const CtrlBAckResponseHeader *blockAck, Mac48Address recipient, double rxSnr, WifiMode txMode, double dataSnr)
Ptr< const Packet > m_currentPacket
Definition: edca-txop-n.h:577
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void DoInitialize()
Initialize() implementation.
void SetQosAckPolicy(enum QosAckPolicy policy)
Set the QoS ACK policy in the QoS control field.
Introspection did not find any typical Config paths.
Definition: dcf.h:33
TxFailed m_txFailedCallback
Definition: edca-txop-n.h:565
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
virtual Mac48Address GetDestAddressForAggregation(const WifiMacHeader &hdr)
Definition: edca-txop-n.cc:225
void NotifyWakeUp(void)
When wake up operation occurs, restart channel access.
Definition: edca-txop-n.cc:894
void SetBlockAckInactivityTimeout(uint16_t timeout)
bool NeedDataRetransmission(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet)
uint32_t GetCwMin(void) const
Return the minimum congestion window size.
Definition: dcf-manager.cc:103
uint32_t GetFragmentSize(void)
Calculate the size of the current fragment.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
uint16_t m_blockAckInactivityTimeout
Definition: edca-txop-n.h:591
void CreateAgreement(const MgtAddBaRequestHeader *reqHdr, Mac48Address recipient)
virtual uint32_t GetNOutstandingPackets(Mac48Address address, uint8_t tid)
Definition: edca-txop-n.cc:205
virtual bool Aggregate(Ptr< const Packet > packet, Ptr< Packet > aggregatedPacket, Mac48Address src, Mac48Address dest)=0
void VerifyBlockAck(void)
Verifies if dequeued packet has to be transmitted with ack policy Block Ack.
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
Definition: mgt-headers.h:548
void NotifyCollision(void)
Notify the EDCAF that collision has occurred.
Definition: edca-txop-n.cc:731
void ReportDataFailed(Mac48Address address, const WifiMacHeader *header)
Should be invoked whenever the AckTimeout associated to a transmission attempt expires.
Ptr< const Packet > PeekNextPacketByTidAndAddress(WifiMacHeader &hdr, Mac48Address recipient, uint8_t tid, Time *timestamp)
void SetTypeOfStation(enum TypeOfStation type)
Set type of station with the given type.
Definition: edca-txop-n.cc:371
void EnableBasicBlockAck(void)
Wait BASICBLOCKACKTimeout for a Basic Block Ack Response frame.
Definition: mac-low.cc:169
void StorePacket(Ptr< const Packet > packet, const WifiMacHeader &hdr, Time tStamp)
void RequestAccess(DcfState *state)
Definition: dcf-manager.cc:526
void CompleteMpduTx(Ptr< const Packet > packet, WifiMacHeader hdr, Time tstamp)
virtual void EndTxNoAck(void)
Invoked upon the end of the transmission of a frame that does not require an ACK (e.g., broadcast and multicast frames).
Definition: edca-txop-n.cc:139
bool IsAction() const
Return true if the header is an Action header.
Mac48Address GetBssid(void) const
Return the Basic Service Set Identification.
Definition: mac-low.cc:681
void SetTxFailedCallback(TxFailed callback)
Definition: edca-txop-n.cc:356
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:667
void GotAck(double snr, WifiMode txMode)
Event handler when an ACK is received.
Definition: edca-txop-n.cc:910
void SetNoMoreFragments(void)
Un-set the More Fragment bit in the Frame Control Field.
void RegisterBlockAckListenerForAc(enum AcIndex ac, MacLowAggregationCapableTransmissionListener *listener)
Definition: mac-low.cc:2813
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1270
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
bool NeedBarRetransmission(void)
Check if Block ACK Request should be re-transmitted.
virtual int64_t AssignStreams(int64_t stream)=0
Assign a fixed random variable stream number to the random variables used by this model...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
enum WifiMacType GetType(void) const
Return the type (enum WifiMacType)
uint8_t m_blockAckThreshold
Definition: edca-txop-n.h:588
void SetWifiRemoteStationManager(Ptr< WifiRemoteStationManager > remoteManager)
Set WifiRemoteStationsManager this EdcaTxopN is associated to.
Definition: edca-txop-n.cc:363
bool HasBar(struct Bar &bar)
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:792
bool IsBroadcast(void) const
virtual bool IsEdca(void) const
Definition: edca-txop-n.cc:55
void SetBlockAckType(enum BlockAckType bAckType)
WifiMacHeader m_currentHdr
Definition: edca-txop-n.h:579
void NotifySleep(void)
When sleep operation occurs, re-insert pending packet into front of the queue.
Definition: edca-txop-n.cc:883
void ReportAmpduTxStatus(Mac48Address address, uint8_t tid, uint32_t nSuccessfulMpdus, uint32_t nFailedMpdus, double rxSnr, double dataSnr)
Typically called per A-MPDU, either when a Block ACK was successfully received or when a BlockAckTime...
void SetAction(enum CategoryValue type, ActionValue action)
Set action for this Action header.
Definition: mgt-headers.cc:762
#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.
void SetAifsn(uint32_t aifsn)
Definition: dcf-manager.cc:56
bool IsBlockAck(void) const
Return true if the header is a Block ACK header.
virtual void Cancel(void)
Invoked if this transmission was canceled one way or another.
Definition: edca-txop-n.cc:135
bool NeedRts(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet, WifiTxVector txVector)
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)
virtual Ptr< MsduAggregator > GetMsduAggregator(void) const
Definition: edca-txop-n.cc:213
CategoryValue GetCategory()
Return the category value.
Definition: mgt-headers.cc:796
virtual Ptr< const Packet > PeekNextPacketInBaQueue(WifiMacHeader &header, Mac48Address recipient, uint8_t tid, Time *timestamp)
Definition: edca-txop-n.cc:193
bool HasPackets(void) const
Returns true if there are packets that need of retransmission or at least a BAR is scheduled...
void ResetCw(void)
Update the value of the CW variable to take into account a transmission success or a transmission abo...
Definition: dcf-manager.cc:115
void PrepareForQueue(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet)
Ptr< MsduAggregator > m_msduAggregator
Definition: edca-txop-n.h:580
ns3::Time timeout
Ptr< const Packet > PeekNextPacket(WifiMacHeader &hdr)
void SetTid(uint8_t)
Set Traffic ID (TID).
virtual Time GetTxopLimit(void) const
Return the TXOP limit.
Definition: edca-txop-n.cc:441
Block Ack Request.
friend class TransmissionListener
Definition: edca-txop-n.h:560
listen to events coming from ns3::MacLow.
Definition: mac-low.h:63
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:99
virtual void MissedAck(void)
ns3::MacLow did not receive an expected ACK within AckTimeout.
Definition: edca-txop-n.cc:115
void Add(DcfState *dcf)
Definition: dcf-manager.cc:424
void NextFragment(void)
Continue to the next fragment.
uint8_t GetCurrentTid() const
Get Traffic ID of the current packet.
Definition: edca-txop-n.cc:747
bool IsQosAmsdu(void) const
Check if the A-MSDU present bit is set in the QoS control field.
Time GetTxopLimit(void) const
Return the TXOP limit.
Definition: dcf-manager.cc:97
void SetTxOkCallback(TxOk callback)
Definition: edca-txop-n.cc:349
BlockAckManager * m_baManager
Definition: edca-txop-n.h:584
control how a packet is transmitted.
Definition: mac-low.h:311
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support.
struct Bar m_currentBar
Definition: edca-txop-n.h:592
virtual void DoNotifyChannelSwitching(void)
Called by DcfManager to notify a DcfState subclass that a channel switching occured.
Definition: edca-txop-n.cc:73
bool m_isAccessRequestedForRts
Definition: edca-txop-n.h:594
virtual uint32_t GetAifsn(void) const
Return the number of slots that make up an AIFS.
Definition: edca-txop-n.cc:434
virtual void StartNextFragment(void)
Invoked when ns3::MacLow wants to start a new transmission as configured by MacLowTransmissionParamet...
Definition: edca-txop-n.cc:127
virtual bool GetBlockAckAgreementExists(Mac48Address address, uint8_t tid)
Definition: edca-txop-n.cc:201
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Handles sequence numbering of IEEE 802.11 data frames.
Definition: mac-tx-middle.h:39
void MissedBlockAck(uint32_t nMpdus)
Event handler when a Block ACK timeout has occurred.
Ptr< MpduAggregator > m_mpduAggregator
Definition: edca-txop-n.h:581
virtual void DoNotifyCollision(void)
Called by DcfManager to notify a DcfState subclass that a normal collision occured, that is, that the medium was busy when access was requested.
Definition: edca-txop-n.cc:69
void SetTxFailedCallback(TxFailed callback)
DcfManager * m_manager
Definition: edca-txop-n.h:562
void MissedAck(void)
Event handler when an ACK is missed.
Definition: edca-txop-n.cc:960
enum TypeOfStation GetTypeOfStation(void) const
Return type of station.
Definition: edca-txop-n.cc:378
void SetLow(Ptr< MacLow > low)
Set MacLow associated with this EdcaTxopN.
Definition: edca-txop-n.cc:461
Ptr< MacLow > Low(void)
Return the MacLow associated with this EdcaTxopN.
Definition: edca-txop-n.cc:455
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:228
uint8_t GetQosTid(void) const
Return the Traffic ID of a QoS header.
Ptr< WifiRemoteStationManager > m_stationManager
Definition: edca-txop-n.h:571
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
void DestroyBlockAckAgreement(Mac48Address originator, uint8_t tid)
Definition: mac-low.cc:2526
This queue contains packets for a particular access class.
Definition: edca-txop-n.h:86
void GotDelBaFrame(const MgtDelBaHeader *delBaHdr, Mac48Address recipient)
void SetQueue(Ptr< WifiMacQueue > queue)
void NotifyAccessGranted(void)
Notify the EDCAF that access has been granted.
Definition: edca-txop-n.cc:497
RandomStream * m_rng
Definition: edca-txop-n.h:570
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:491
void ReportFinalDataFailed(Mac48Address address, const WifiMacHeader *header)
Should be invoked after calling ReportDataFailed if NeedDataRetransmission returns false...
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: pointer.h:220
void NotifyInternalCollision(void)
Notify the EDCAF that internal collision has occurred.
Definition: edca-txop-n.cc:655
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
std::map< Mac48Address, bool > m_aMpduEnabled
Definition: edca-txop-n.h:103
virtual uint32_t GetNRetryNeededPackets(Mac48Address recipient, uint8_t tid) const
Definition: edca-txop-n.cc:209
TracedValue< uint32_t > m_cwTrace
Definition: edca-txop-n.h:596
void UpdateAgreement(const MgtAddBaResponseHeader *respHdr, Mac48Address recipient)
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
TracedValue< uint32_t > m_backoffTrace
Definition: edca-txop-n.h:595
void ReportRtsFailed(Mac48Address address, const WifiMacHeader *header)
Should be invoked whenever the RtsTimeout associated to a transmission attempt expires.
void SetAddr3(Mac48Address address)
Fill the Address 3 field with the given address.
virtual void SetMinCw(uint32_t minCw)
Set the minimum contention window size.
Definition: edca-txop-n.cc:392
uint32_t GetNRetryNeededPackets(Mac48Address recipient, uint8_t tid) const
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...
Ptr< const Packet > PeekNextRetransmitPacket(WifiMacHeader &header, Mac48Address recipient, uint8_t tid, Time *timestamp)
Definition: edca-txop-n.cc:485
void SendDelbaFrame(Mac48Address addr, uint8_t tid, bool byOriginator)
virtual void GotAck(double snr, WifiMode txMode)
Definition: edca-txop-n.cc:111
uint16_t GetSequenceControl(void) const
Return the raw Sequence Control field.
void SetBlockAckThreshold(uint8_t threshold)
Set threshold for block ACK mechanism.
void NotifyAgreementUnsuccessful(Mac48Address recipient, uint8_t tid)
MacTxMiddle * m_txMiddle
Definition: edca-txop-n.h:567
void MissedCts(void)
Event handler when a CTS timeout has occurred.
Definition: edca-txop-n.cc:812
Manage a set of ns3::DcfStateHandle a set of independent ns3::DcfState, each of which represents a si...
Definition: dcf-manager.h:279
virtual void GotBlockAck(const CtrlBAckResponseHeader *blockAck, Mac48Address source, double rxSnr, WifiMode txMode, double dataSnr)
Definition: edca-txop-n.cc:119
enum BlockAckActionValue blockAck
Definition: mgt-headers.h:620
void SetWifiRemoteStationManager(Ptr< WifiRemoteStationManager > manager)
Set up WifiRemoteStationManager associated with this BlockAckManager.
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:479
keep track of the state needed for a single DCF function.
Definition: dcf-manager.h:46
virtual void SetAmpdu(Mac48Address dest, bool enableAmpdu)
Definition: edca-txop-n.cc:177
std::string GetUniqueName(void) const
Definition: wifi-mode.cc:342
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:186
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
void NotifyChannelSwitching(void)
When a channel switching occurs, enqueued packets are removed.
Definition: edca-txop-n.cc:875
Mac48Address GetAddress(void) const
Return the MAC address of this MacLow.
Definition: mac-low.cc:627
void StartNextFragment(void)
Start transmission for the next fragment.
void SetTxMiddle(MacTxMiddle *txMiddle)
bool IsAccessRequested(void) const
Definition: dcf-manager.cc:169
void SetBlockDestinationCallback(Callback< void, Mac48Address, uint8_t > callback)
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
Ptr< Packet > GetFragmentPacket(WifiMacHeader *hdr)
Get the next fragment from the packet with appropriate Wifi header for the fragment.
bool IsMgt(void) const
Return true if the Type is Management.
virtual ~EdcaTxopN()
Definition: edca-txop-n.cc:287
virtual void StartNext(void)
Invoked when ns3::MacLow wants to continue the TXOP.
Definition: edca-txop-n.cc:131
bool HasTxop(void)
uint32_t GetNRetryNeededPackets(Mac48Address recipient, uint8_t tid) const
Definition: edca-txop-n.cc:329
virtual void DoNotifyWakeUp(void)
Called by DcfManager to notify a DcfState subclass that the device has begun to wake up...
Definition: edca-txop-n.cc:81
uint8_t m_fragmentNumber
Definition: edca-txop-n.h:572
void SetTxOkCallback(TxOk callback)
Time m_currentPacketTimestamp
Definition: edca-txop-n.h:590
uint32_t GetCwMax(void) const
Return the maximum congestion window size.
Definition: dcf-manager.cc:109
void SetCwMin(uint32_t minCw)
Set the minimum congestion window size.
Definition: dcf-manager.cc:69
virtual void GotCts(double snr, WifiMode txMode)
Definition: edca-txop-n.cc:103
virtual void StartTransmission(Ptr< const Packet > packet, const WifiMacHeader *hdr, MacLowTransmissionParameters parameters, MacLowTransmissionListener *listener)
Definition: mac-low.cc:724
Mac48Address recipient
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:278
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)
EdcaTxopN * m_txop
Definition: edca-txop-n.cc:86
virtual uint32_t GetMinCw(void) const
Return the minimum contention window size.
Definition: edca-txop-n.cc:420
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.
void StartBackoffNow(uint32_t nSlots)
Definition: dcf-manager.cc:136
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.
Ptr< MpduAggregator > GetMpduAggregator(void) const
void EnableCompressedBlockAck(void)
Wait COMPRESSEDBLOCKACKTimeout for a Compressed Block Ack Response frame.
Definition: mac-low.cc:174
virtual void CompleteTransfer(Mac48Address recipient, uint8_t tid)
Definition: edca-txop-n.cc:173
virtual void MissedCts(void)
ns3::MacLow did not receive an expected CTS within CtsTimeout.
Definition: edca-txop-n.cc:107
uint16_t GetNextSequenceNumberfor(const WifiMacHeader *hdr)
Return the next sequence number for the given header.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< MsduAggregator > GetMsduAggregator(void) const
Hold objects of type Ptr.
Definition: pointer.h:36
void SetAccessCategory(enum AcIndex ac)
Set the access category of this EDCAF.
bool IsGroup(void) const
void EnableAck(void)
Wait ACKTimeout for an ACK.
Definition: mac-low.cc:189
uint16_t PeekNextSequenceNumberfor(const WifiMacHeader *hdr)
Return the next sequence number for the Traffic ID and destination, but do not pick it (i...
bool RemovePacket(uint8_t tid, Mac48Address recipient, uint16_t seqnumber)
Remove a packet after you peek in the queue and get it.
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
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)
bool ExistsAgreementInState(Mac48Address recipient, uint8_t tid, enum OriginatorBlockAckAgreement::State state) const
void SetMpduAggregator(Ptr< MpduAggregator > aggr)
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:317
StatusCode GetStatusCode(void) const
Return the status code.
void StartNext(void)
Start transmission for the next packet if allowed by the TxopLimit.
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.
virtual void DoNotifySleep(void)
Called by DcfManager to notify a DcfState subclass that the device has begun to sleep.
Definition: edca-txop-n.cc:77
void SetAmpduExist(Mac48Address dest, bool enableAmpdu)
virtual Mac48Address GetSrcAddressForAggregation(const WifiMacHeader &hdr)
Definition: edca-txop-n.cc:221
Ptr< const Packet > GetNextPacket(WifiMacHeader &hdr)
void Cancel(void)
Cancel the transmission.
void BaTxOk(const WifiMacHeader &hdr)
The packet we sent was successfully received by the receiver.
void SetManager(DcfManager *manager)
Set DcfManager this EdcaTxopN is associated to.
Definition: edca-txop-n.cc:341
void DisableRts(void)
Do not send rts and wait for cts before sending data.
Definition: mac-low.cc:204
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:224
void Queue(Ptr< const Packet > packet, const WifiMacHeader &hdr)
Definition: edca-txop-n.cc:901
uint16_t GetNextSequenceNumberfor(WifiMacHeader *hdr)
Return the next sequence number for the given header.
Definition: edca-txop-n.cc:474
void SetMsduAggregator(Ptr< MsduAggregator > aggr)
bool GetAmpduExist(Mac48Address dest) const
void SetBlockAckInactivityCallback(Callback< void, Mac48Address, uint8_t, bool > callback)
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).
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
virtual uint16_t GetNextSequenceNumberfor(WifiMacHeader *hdr)
Return the next sequence number for the given header.
Definition: edca-txop-n.cc:185
void SetMaxPacketDelay(Time maxDelay)
void NotifyMpduTransmission(Mac48Address recipient, uint8_t tid, uint16_t nextSeqNumber, WifiMacHeader::QosAckPolicy policy)
bool HasHtSupported(void) const
Return whether the device has HT capability support enabled.
virtual Ptr< WifiMacQueue > GetQueue(void)
Returns the EDCA queue to check if there are packets that can be aggregated with a Block Ack...
Definition: edca-txop-n.cc:169
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:90
bool NeedBarRetransmission(uint8_t tid, uint16_t seqNumber, Mac48Address recipient)
This function returns true if the lifetime of the packets a BAR refers to didn't expire yet else it r...
void PushFront(Ptr< const Packet > packet, const WifiMacHeader &hdr)
bool SwitchToBlockAckIfNeeded(Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
enum BlockAckType m_blockAckType
Definition: edca-txop-n.h:589
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:1381
void SetCwMax(uint32_t maxCw)
Set the maximum congestion window size.
Definition: dcf-manager.cc:80
virtual void DoNotifyAccessGranted(void)
Called by DcfManager to notify a DcfState subclass that access to the medium is granted and can start...
Definition: edca-txop-n.cc:61
virtual void BlockAckInactivityTimeout(Mac48Address address, uint8_t tid)
Typically is called in order to notify EdcaTxopN that a block ack inactivity timeout occurs for the b...
Definition: edca-txop-n.cc:165
static TypeId GetTypeId(void)
Definition: edca-txop-n.cc:237
virtual void MissedBlockAck(uint32_t nMpdus)
Definition: edca-txop-n.cc:123
WifiTxVector GetDataTxVector(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet)
void BaTxFailed(const WifiMacHeader &hdr)
The packet we sent was successfully received by the receiver.
uint32_t GetNBufferedPackets(Mac48Address recipient, uint8_t tid) const
bool MustSendHtImmediateAck(void) const
Check if the current ACK policy is immediate.
uint32_t GetNextFragmentSize(void)
Calculate the size of the next fragment.
void SetSequenceNumber(uint16_t seq)
Set the sequence number of the header.
bool IsData(void) const
Return true if the Type is DATA.
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS DATA...
bool NeedRtsRetransmission(Ptr< const Packet > packet, const WifiMacHeader &hdr)
Check if RTS should be re-transmitted if CTS was missed.
void EnableRts(void)
Send a RTS, and wait CTSTimeout for a CTS.
Definition: mac-low.cc:199
void CompleteConfig(void)
Complete block ACK configuration.
virtual void RemoveFromBaQueue(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:197
uint32_t GetCw(void) const
Definition: dcf-manager.cc:151
uint32_t GetAifsn(void) const
Return the number of slots that make up an AIFS.
Definition: dcf-manager.cc:91
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.
void RestartAccessIfNeeded(void)
Restart access request if needed.
void SetBlockAckThreshold(uint8_t nPackets)
Implement the header for management frames of type add block ack response.
Definition: mgt-headers.h:799
QosBlockedDestinations * m_qosBlockedDestinations
Definition: edca-txop-n.h:583
void CompleteAmpduExchange(Mac48Address recipient, uint8_t tid)
Implement the header for management frames of type del block ack.
Definition: mgt-headers.h:920
void CompleteAmpduTransfer(Mac48Address recipient, uint8_t tid)
Definition: edca-txop-n.cc:335
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Ptr< MacLow > m_low
Definition: edca-txop-n.h:566
typedef for union of different ActionValues
Definition: mgt-headers.h:615
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
Ptr< const Packet > bar
uint8_t GetBlockAckThreshold(void) const
Return the current threshold for block ACK mechanism.
friend class Dcf
Definition: edca-txop-n.h:558
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:44
void SetTxMiddle(MacTxMiddle *txMiddle)
Definition: edca-txop-n.cc:448
void GotCts(double snr, WifiMode txMode)
Event handler when a CTS is received.
Definition: edca-txop-n.cc:740
bool NeedFragmentation(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet)
virtual Ptr< MpduAggregator > GetMpduAggregator(void) const
Definition: edca-txop-n.cc:217
void EnableNextData(uint32_t size)
Definition: mac-low.cc:144
Time GetTxopRemaining(void)
void DoDispose()
Destructor implementation.
Definition: edca-txop-n.cc:293
void DisableOverrideDurationId(void)
Do not force the duration/id field of the packet: its value is automatically calculated by the MacLow...
Definition: mac-low.cc:159
bool NeedDataRetransmission(Ptr< const Packet > packet, const WifiMacHeader &hdr)
Check if DATA should be re-transmitted if ACK was missed.
bool IsLastFragment(void) const
Check if the current fragment is the last fragment.
void Block(Mac48Address dest, uint8_t tid)
Block the given destination address and TID from sending (e.g.
void DisableNextData(void)
Do not attempt to send data burst after current transmission.
Definition: mac-low.cc:149
virtual uint32_t GetMaxCw(void) const
Return the maximum contention window size.
Definition: edca-txop-n.cc:427
bool NeedRtsRetransmission(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet)
virtual uint32_t GetMaxAmpduSize(void) const =0
Ptr< WifiMacQueue > m_queue
Definition: edca-txop-n.h:563
void StartAccessIfNeeded(void)
Request access from DCF manager if needed.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:911
void SetType(enum WifiMacType type)
Set Type/Subtype values with the correct values depending on the given type.
virtual uint32_t GetNext(uint32_t min, uint32_t max)=0
Get integer between min and max (including min and max).
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
tuple address
Definition: first.py:37
virtual void CompleteMpduTx(Ptr< const Packet > packet, WifiMacHeader hdr, Time tstamp)
This function stores an MPDU (part of an A-MPDU) in blockackagreement (i.e.
Definition: edca-txop-n.cc:181
void SendBlockAckRequest(const struct Bar &bar)
After that all packets, for which a block ack agreement was established, have been transmitted...
TypeOfStation
Enumeration for type of station.
Definition: edca-txop-n.h:61
virtual void SetTxopLimit(Time txopLimit)
Definition: edca-txop-n.cc:413
void UpdateFailedCw(void)
Update the value of the CW variable to take into account a transmission failure.
Definition: dcf-manager.cc:121
Manages all block ack agreements for an originator station.
ActionValue GetAction()
Return the action value.
Definition: mgt-headers.cc:817
Headers for Block ack request.
Definition: ctrl-headers.h:50
bool ExistsAgreement(Mac48Address recipient, uint8_t tid) const
void FlushAggregateQueue(void)
This function is called to flush the aggregate queue, which is used for A-MPDU.
Definition: mac-low.cc:3261
virtual void DoNotifyInternalCollision(void)
Called by DcfManager to notify a DcfState subclass that an 'internal' collision occured, that is, that the backoff timer of a higher priority DcfState expired at the same time and that access was granted to this higher priority DcfState.
Definition: edca-txop-n.cc:65
void SetFragmentNumber(uint8_t frag)
Set the fragment number of the header.
void DisableAck(void)
Do not wait for Ack after data transmission.
Definition: mac-low.cc:194
uint32_t GetNOutstandingPacketsInBa(Mac48Address address, uint8_t tid)
Definition: edca-txop-n.cc:323
uint16_t GetNextSeqNumberByTidAndAddress(uint8_t tid, Mac48Address addr) const
Return the next sequence number for the Traffic ID and destination.
a unique identifier for an interface.
Definition: type-id.h:58
void ReportFinalRtsFailed(Mac48Address address, const WifiMacHeader *header)
Should be invoked after calling ReportRtsFailed if NeedRtsRetransmission returns false.
void SetStartingSequence(uint16_t seq)
Set the starting sequence number from the given raw sequence control field.
bool NeedsAccess(void) const
Check if the EDCAF requires access.
Definition: edca-txop-n.cc:468
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:904
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:36
uint32_t GetFragmentOffset(void)
Calculate the offset for the current fragment.
AggregationCapableTransmissionListener * m_blockAckListener
Definition: edca-txop-n.h:569
bool IsRetry(void) const
Return if the Retry bit is set.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257
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)
void TearDownBlockAck(Mac48Address recipient, uint8_t tid)
Implements the IEEE 802.11 MAC trailer.
virtual void SetAifsn(uint32_t aifsn)
Definition: edca-txop-n.cc:406
TypeOfStation m_typeOfStation
Definition: edca-txop-n.h:582
Mac48Address MapSrcAddressForAggregation(const WifiMacHeader &hdr)
This functions are used only to correctly set addresses in a-msdu subframe.
Ptr< WifiMacQueue > GetEdcaQueue() const
Return the packet queue associated with this EdcaTxopN.
Definition: edca-txop-n.cc:385
void SetDsNotFrom(void)
Un-set the From DS bit in the Frame Control field.
virtual Ptr< WifiMacQueue > GetQueue(void)
Definition: edca-txop-n.cc:143
uint16_t GetSequenceNumber(void) const
Return the sequence number of the header.
Dcf(EdcaTxopN *txop)
Definition: edca-txop-n.cc:50