A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
mac-low.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 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 
23 #include "ns3/assert.h"
24 #include "ns3/packet.h"
25 #include "ns3/simulator.h"
26 #include "ns3/tag.h"
27 #include "ns3/log.h"
28 #include "ns3/node.h"
29 #include "ns3/double.h"
30 
31 #include "mac-low.h"
32 #include "wifi-phy.h"
33 #include "wifi-mac-trailer.h"
34 #include "qos-utils.h"
35 #include "edca-txop-n.h"
36 #include "snr-tag.h"
37 
38 NS_LOG_COMPONENT_DEFINE ("MacLow");
39 
40 #undef NS_LOG_APPEND_CONTEXT
41 #define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] "
42 
43 
44 namespace ns3 {
45 
46 MacLowTransmissionListener::MacLowTransmissionListener ()
47 {
48 }
49 MacLowTransmissionListener::~MacLowTransmissionListener ()
50 {
51 }
52 void
54  Mac48Address source)
55 {
56 }
57 void
59 {
60 }
61 MacLowDcfListener::MacLowDcfListener ()
62 {
63 }
64 MacLowDcfListener::~MacLowDcfListener ()
65 {
66 }
67 
68 MacLowBlockAckEventListener::MacLowBlockAckEventListener ()
69 {
70 }
71 MacLowBlockAckEventListener::~MacLowBlockAckEventListener ()
72 {
73 }
74 
75 MacLowTransmissionParameters::MacLowTransmissionParameters ()
76  : m_nextSize (0),
77  m_waitAck (ACK_NONE),
78  m_sendRts (false),
79  m_overrideDurationId (Seconds (0))
80 {
81 }
82 void
84 {
85  m_nextSize = size;
86 }
87 void
89 {
90  m_nextSize = 0;
91 }
92 void
94 {
95  m_overrideDurationId = durationId;
96 }
97 void
99 {
100  m_overrideDurationId = Seconds (0);
101 }
102 void
104 {
105  m_waitAck = ACK_SUPER_FAST;
106 }
107 void
109 {
110  m_waitAck = BLOCK_ACK_BASIC;
111 }
112 void
114 {
115  m_waitAck = BLOCK_ACK_COMPRESSED;
116 }
117 void
119 {
120  m_waitAck = BLOCK_ACK_MULTI_TID;
121 }
122 void
124 {
125  m_waitAck = ACK_FAST;
126 }
127 void
129 {
130  m_waitAck = ACK_NORMAL;
131 }
132 void
134 {
135  m_waitAck = ACK_NONE;
136 }
137 void
139 {
140  m_sendRts = true;
141 }
142 void
144 {
145  m_sendRts = false;
146 }
147 bool
149 {
150  return (m_waitAck != ACK_NONE);
151 }
152 bool
154 {
155  return (m_waitAck == ACK_NORMAL);
156 }
157 bool
159 {
160  return (m_waitAck == ACK_FAST);
161 }
162 bool
164 {
165  return (m_waitAck == ACK_SUPER_FAST);
166 }
167 bool
169 {
170  return (m_waitAck == BLOCK_ACK_BASIC) ? true : false;
171 }
172 bool
174 {
175  return (m_waitAck == BLOCK_ACK_COMPRESSED) ? true : false;
176 }
177 bool
179 {
180  return (m_waitAck == BLOCK_ACK_MULTI_TID) ? true : false;
181 }
182 bool
184 {
185  return m_sendRts;
186 }
187 bool
189 {
190  return (m_overrideDurationId != Seconds (0));
191 }
192 Time
194 {
195  NS_ASSERT (m_overrideDurationId != Seconds (0));
196  return m_overrideDurationId;
197 }
198 bool
200 {
201  return (m_nextSize != 0);
202 }
203 uint32_t
205 {
207  return m_nextSize;
208 }
209 
210 std::ostream &operator << (std::ostream &os, const MacLowTransmissionParameters &params)
211 {
212  os << "["
213  << "send rts=" << params.m_sendRts << ", "
214  << "next size=" << params.m_nextSize << ", "
215  << "dur=" << params.m_overrideDurationId << ", "
216  << "ack=";
217  switch (params.m_waitAck)
218  {
219  case MacLowTransmissionParameters::ACK_NONE:
220  os << "none";
221  break;
222  case MacLowTransmissionParameters::ACK_NORMAL:
223  os << "normal";
224  break;
225  case MacLowTransmissionParameters::ACK_FAST:
226  os << "fast";
227  break;
228  case MacLowTransmissionParameters::ACK_SUPER_FAST:
229  os << "super-fast";
230  break;
231  case MacLowTransmissionParameters::BLOCK_ACK_BASIC:
232  os << "basic-block-ack";
233  break;
234  case MacLowTransmissionParameters::BLOCK_ACK_COMPRESSED:
235  os << "compressed-block-ack";
236  break;
237  case MacLowTransmissionParameters::BLOCK_ACK_MULTI_TID:
238  os << "multi-tid-block-ack";
239  break;
240  }
241  os << "]";
242  return os;
243 }
244 
245 
246 /***************************************************************
247  * Listener for PHY events. Forwards to MacLow
248  ***************************************************************/
249 
250 
252 {
253 public:
255  : m_macLow (macLow)
256  {
257  }
258  virtual ~PhyMacLowListener ()
259  {
260  }
261  virtual void NotifyRxStart (Time duration)
262  {
263  }
264  virtual void NotifyRxEndOk (void)
265  {
266  }
267  virtual void NotifyRxEndError (void)
268  {
269  }
270  virtual void NotifyTxStart (Time duration)
271  {
272  }
273  virtual void NotifyMaybeCcaBusyStart (Time duration)
274  {
275  }
276  virtual void NotifySwitchingStart (Time duration, uint16_t toChannel)
277  {
278  m_macLow->NotifySwitchingStartNow (duration);
279  }
280  virtual void NotifySensingStart (Time duration)
281  {
282  m_macLow->NotifySensingStartNow (duration);
283  }
284 private:
285  ns3::MacLow *m_macLow;
286 };
287 
288 
289 MacLow::MacLow ()
290  : m_normalAckTimeoutEvent (),
291  m_fastAckTimeoutEvent (),
292  m_superFastAckTimeoutEvent (),
293  m_fastAckFailedTimeoutEvent (),
294  m_blockAckTimeoutEvent (),
295  m_ctsTimeoutEvent (),
296  m_sendCtsEvent (),
297  m_sendAckEvent (),
298  m_sendDataEvent (),
299  m_waitSifsEvent (),
300  m_endTxNoAckEvent (),
301  m_currentPacket (0),
302  m_listener (0)
303 {
304  NS_LOG_FUNCTION (this);
305  m_lastNavDuration = Seconds (0);
306  m_lastNavStart = Seconds (0);
307  m_promisc = false;
308  m_tx = false;
309  m_rx = false;
310 }
311 
312 MacLow::~MacLow ()
313 {
314  NS_LOG_FUNCTION (this);
315 }
316 
317 void
318 MacLow::SetupPhyMacLowListener (Ptr<WifiPhy> phy)
319 {
320  m_phyMacLowListener = new PhyMacLowListener (this);
321  phy->RegisterListener (m_phyMacLowListener);
322 }
323 
324 
325 void
327 {
328  NS_LOG_FUNCTION (this);
329  m_normalAckTimeoutEvent.Cancel ();
330  m_fastAckTimeoutEvent.Cancel ();
331  m_superFastAckTimeoutEvent.Cancel ();
332  m_fastAckFailedTimeoutEvent.Cancel ();
333  m_blockAckTimeoutEvent.Cancel ();
334  m_ctsTimeoutEvent.Cancel ();
335  m_sendCtsEvent.Cancel ();
336  m_sendAckEvent.Cancel ();
337  m_sendDataEvent.Cancel ();
338  m_waitSifsEvent.Cancel ();
339  m_endTxNoAckEvent.Cancel ();
340  m_phy = 0;
341  m_stationManager = 0;
342  delete m_phyMacLowListener;
343  m_phyMacLowListener = 0;
344 }
345 
346 void
347 MacLow::CancelAllEvents (void)
348 {
349  NS_LOG_FUNCTION (this);
350  bool oneRunning = false;
351  if (m_normalAckTimeoutEvent.IsRunning ())
352  {
353  m_normalAckTimeoutEvent.Cancel ();
354  oneRunning = true;
355  }
356  if (m_fastAckTimeoutEvent.IsRunning ())
357  {
358  m_fastAckTimeoutEvent.Cancel ();
359  oneRunning = true;
360  }
361  if (m_superFastAckTimeoutEvent.IsRunning ())
362  {
363  m_superFastAckTimeoutEvent.Cancel ();
364  oneRunning = true;
365  }
366  if (m_fastAckFailedTimeoutEvent.IsRunning ())
367  {
368  m_fastAckFailedTimeoutEvent.Cancel ();
369  oneRunning = true;
370  }
371  if (m_blockAckTimeoutEvent.IsRunning ())
372  {
373  m_blockAckTimeoutEvent.Cancel ();
374  oneRunning = true;
375  }
376  if (m_ctsTimeoutEvent.IsRunning ())
377  {
378  m_ctsTimeoutEvent.Cancel ();
379  oneRunning = true;
380  }
381  if (m_sendCtsEvent.IsRunning ())
382  {
383  m_sendCtsEvent.Cancel ();
384  oneRunning = true;
385  }
386  if (m_sendAckEvent.IsRunning ())
387  {
388  m_sendAckEvent.Cancel ();
389  oneRunning = true;
390  }
391  if (m_sendDataEvent.IsRunning ())
392  {
393  m_sendDataEvent.Cancel ();
394  oneRunning = true;
395  }
396  if (m_waitSifsEvent.IsRunning ())
397  {
398  m_waitSifsEvent.Cancel ();
399  oneRunning = true;
400  }
401  if (m_endTxNoAckEvent.IsRunning ())
402  {
403  m_endTxNoAckEvent.Cancel ();
404  oneRunning = true;
405  }
406  if (oneRunning && m_listener != 0)
407  {
408  m_listener->Cancel ();
409  m_listener = 0;
410  }
411 }
412 
413 void
414 MacLow::SetPhy (Ptr<WifiPhy> phy)
415 {
416  m_phy = phy;
419  SetupPhyMacLowListener (phy);
420 }
421 Ptr<WifiPhy>
422 MacLow::GetPhy (void)
423 {
424  return m_phy;
425 }
426 void
427 MacLow::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> manager)
428 {
429  m_stationManager = manager;
430 }
431 
432 void
433 MacLow::SetAddress (Mac48Address ad)
434 {
435  m_self = ad;
436 }
437 void
438 MacLow::SetAckTimeout (Time ackTimeout)
439 {
440  m_ackTimeout = ackTimeout;
441 }
442 void
443 MacLow::SetBasicBlockAckTimeout (Time blockAckTimeout)
444 {
445  m_basicBlockAckTimeout = blockAckTimeout;
446 }
447 void
448 MacLow::SetCompressedBlockAckTimeout (Time blockAckTimeout)
449 {
450  m_compressedBlockAckTimeout = blockAckTimeout;
451 }
452 void
453 MacLow::SetCtsTimeout (Time ctsTimeout)
454 {
455  m_ctsTimeout = ctsTimeout;
456 }
457 void
458 MacLow::SetSifs (Time sifs)
459 {
460  m_sifs = sifs;
461 }
462 void
463 MacLow::SetSlotTime (Time slotTime)
464 {
465  m_slotTime = slotTime;
466 }
467 void
468 MacLow::SetPifs (Time pifs)
469 {
470  m_pifs = pifs;
471 }
472 void
473 MacLow::SetBssid (Mac48Address bssid)
474 {
475  m_bssid = bssid;
476 }
477 void
478 MacLow::SetPromisc (void)
479 {
480  m_promisc = true;
481 }
482 Mac48Address
483 MacLow::GetAddress (void) const
484 {
485  return m_self;
486 }
487 Time
488 MacLow::GetAckTimeout (void) const
489 {
490  return m_ackTimeout;
491 }
492 Time
493 MacLow::GetBasicBlockAckTimeout () const
494 {
495  return m_basicBlockAckTimeout;
496 }
497 Time
498 MacLow::GetCompressedBlockAckTimeout () const
499 {
500  return m_compressedBlockAckTimeout;
501 }
502 Time
503 MacLow::GetCtsTimeout (void) const
504 {
505  return m_ctsTimeout;
506 }
507 Time
508 MacLow::GetSifs (void) const
509 {
510  return m_sifs;
511 }
512 Time
513 MacLow::GetSlotTime (void) const
514 {
515  return m_slotTime;
516 }
517 Time
518 MacLow::GetPifs (void) const
519 {
520  return m_pifs;
521 }
522 Mac48Address
523 MacLow::GetBssid (void) const
524 {
525  return m_bssid;
526 }
527 
528 void
530 {
531  m_rxCallback = callback;
532 }
533 void
535 {
536  m_dcfListeners.push_back (listener);
537 }
538 
539 
540 void
542  const WifiMacHeader* hdr,
544  MacLowTransmissionListener *listener)
545 {
546  NS_LOG_FUNCTION (this << packet << hdr << params << listener);
547  /* m_currentPacket is not NULL because someone started
548  * a transmission and was interrupted before one of:
549  * - ctsTimeout
550  * - sendDataAfterCTS
551  * expired. This means that one of these timers is still
552  * running. They are all cancelled below anyway by the
553  * call to CancelAllEvents (because of at least one
554  * of these two timer) which will trigger a call to the
555  * previous listener's cancel method.
556  *
557  * This typically happens because the high-priority
558  * QapScheduler has taken access to the channel from
559  * one of the Edca of the QAP.
560  */
561  m_currentPacket = packet->Copy ();
562  m_currentHdr = *hdr;
563  CancelAllEvents ();
564  m_listener = listener;
565  m_txParams = params;
566 
567  //NS_ASSERT (m_phy->IsStateIdle ());
568 
569  NS_LOG_DEBUG ("startTx size=" << GetSize (m_currentPacket, &m_currentHdr) <<
570  ", to=" << m_currentHdr.GetAddr1 () << ", listener=" << m_listener);
571 
572  if (m_txParams.MustSendRts ())
573  {
574  SendRtsForPacket ();
575  }
576  else
577  {
578  SendDataPacket ();
579  }
580 
581  /* When this method completes, we have taken ownership of the medium. */
582  NS_ASSERT (m_phy->IsStateTx ());
583 }
584 
585 void
587 {
588  NS_LOG_FUNCTION (this << packet << rxSnr);
589  NS_LOG_DEBUG ("rx failed ");
590  if (m_txParams.MustWaitFastAck ())
591  {
592  NS_ASSERT (m_fastAckFailedTimeoutEvent.IsExpired ());
593  m_fastAckFailedTimeoutEvent = Simulator::Schedule (GetSifs (),
594  &MacLow::FastAckFailedTimeout, this);
595  }
596  return;
597 }
598 
599 void
601 {
602  NS_LOG_DEBUG ("switching channel. Cancelling MAC pending events");
603  m_stationManager->Reset ();
604  CancelAllEvents ();
605  if (m_navCounterResetCtsMissed.IsRunning ())
606  {
607  m_navCounterResetCtsMissed.Cancel ();
608  }
609  m_lastNavStart = Simulator::Now ();
610  m_lastNavDuration = Seconds (0);
611  m_currentPacket = 0;
612  m_listener = 0;
613 }
614 
615 void
617 {
618  NS_LOG_DEBUG("Sensing channel at mac low");
619  m_stationManager->Reset ();
620  CancelAllEvents();
621  if (m_navCounterResetCtsMissed.IsRunning ())
622  {
623  m_navCounterResetCtsMissed.Cancel ();
624  }
625  m_lastNavStart = Simulator::Now ();
626  m_lastNavDuration = Seconds (0);
627  m_currentPacket = 0;
628  m_listener = 0;
629 }
630 
631 void
632 MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamble preamble)
633 {
634  NS_LOG_FUNCTION (this << packet << rxSnr << txMode << preamble);
635  /* A packet is received from the PHY.
636  * When we have handled this packet,
637  * we handle any packet present in the
638  * packet queue.
639  */
640  WifiMacHeader hdr;
641  packet->RemoveHeader (hdr);
642 
643  bool isPrevNavZero = IsNavZero ();
644  NS_LOG_DEBUG ("duration/id=" << hdr.GetDuration ());
645  NotifyNav (hdr, txMode, preamble);
646  if (hdr.IsRts ())
647  {
648  /* see section 9.2.5.7 802.11-1999
649  * A STA that is addressed by an RTS frame shall transmit a CTS frame after a SIFS
650  * period if the NAV at the STA receiving the RTS frame indicates that the medium is
651  * idle. If the NAV at the STA receiving the RTS indicates the medium is not idle,
652  * that STA shall not respond to the RTS frame.
653  */
654  if (isPrevNavZero
655  && hdr.GetAddr1 () == m_self)
656  {
657  NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
658  NS_ASSERT (m_sendCtsEvent.IsExpired ());
659  m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
660  rxSnr, txMode);
661  m_sendCtsEvent = Simulator::Schedule (GetSifs (),
662  &MacLow::SendCtsAfterRts, this,
663  hdr.GetAddr2 (),
664  hdr.GetDuration (),
665  txMode,
666  rxSnr);
667  }
668  else
669  {
670  NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
671  }
672  }
673  else if (hdr.IsCts ()
674  && hdr.GetAddr1 () == m_self
675  && m_ctsTimeoutEvent.IsRunning ()
676  && m_currentPacket != 0)
677  {
678  NS_LOG_DEBUG ("receive cts from=" << m_currentHdr.GetAddr1 ());
679  SnrTag tag;
680  packet->RemovePacketTag (tag);
681  m_stationManager->ReportRxOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
682  rxSnr, txMode);
683  m_stationManager->ReportRtsOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
684  rxSnr, txMode, tag.Get ());
685 
686  m_ctsTimeoutEvent.Cancel ();
687  NotifyCtsTimeoutResetNow ();
688  m_listener->GotCts (rxSnr, txMode);
689  NS_ASSERT (m_sendDataEvent.IsExpired ());
690  m_sendDataEvent = Simulator::Schedule (GetSifs (),
691  &MacLow::SendDataAfterCts, this,
692  hdr.GetAddr1 (),
693  hdr.GetDuration (),
694  txMode);
695  }
696  else if (hdr.IsAck ()
697  && hdr.GetAddr1 () == m_self
698  && (m_normalAckTimeoutEvent.IsRunning ()
699  || m_fastAckTimeoutEvent.IsRunning ()
700  || m_superFastAckTimeoutEvent.IsRunning ())
701  && m_txParams.MustWaitAck ())
702  {
703  NS_LOG_DEBUG ("receive ack from=" << m_currentHdr.GetAddr1 ());
704  SnrTag tag;
705  packet->RemovePacketTag (tag);
706  m_stationManager->ReportRxOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
707  rxSnr, txMode);
708  m_stationManager->ReportDataOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
709  rxSnr, txMode, tag.Get ());
710  bool gotAck = false;
711  if (m_txParams.MustWaitNormalAck ()
712  && m_normalAckTimeoutEvent.IsRunning ())
713  {
714  m_normalAckTimeoutEvent.Cancel ();
715  NotifyAckTimeoutResetNow ();
716  gotAck = true;
717  }
718  if (m_txParams.MustWaitFastAck ()
719  && m_fastAckTimeoutEvent.IsRunning ())
720  {
721  m_fastAckTimeoutEvent.Cancel ();
722  NotifyAckTimeoutResetNow ();
723  gotAck = true;
724  }
725  if (gotAck)
726  {
727  m_listener->GotAck (rxSnr, txMode);
728  }
729  if (m_txParams.HasNextPacket ())
730  {
731  m_waitSifsEvent = Simulator::Schedule (GetSifs (),
732  &MacLow::WaitSifsAfterEndTx, this);
733  }
734  }
735  else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self
736  && (m_txParams.MustWaitBasicBlockAck () || m_txParams.MustWaitCompressedBlockAck ())
737  && m_blockAckTimeoutEvent.IsRunning ())
738  {
739  NS_LOG_DEBUG ("got block ack from " << hdr.GetAddr2 ());
740  CtrlBAckResponseHeader blockAck;
741  packet->RemoveHeader (blockAck);
742  m_blockAckTimeoutEvent.Cancel ();
743  m_listener->GotBlockAck (&blockAck, hdr.GetAddr2 ());
744  }
745  else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
746  {
747  CtrlBAckRequestHeader blockAckReq;
748  packet->RemoveHeader (blockAckReq);
749  if (!blockAckReq.IsMultiTid ())
750  {
751  uint8_t tid = blockAckReq.GetTidInfo ();
752  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), tid));
753  if (it != m_bAckAgreements.end ())
754  {
755  //Update block ack cache
756  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), tid));
757  NS_ASSERT (i != m_bAckCaches.end ());
758  (*i).second.UpdateWithBlockAckReq (blockAckReq.GetStartingSequence ());
759 
760  NS_ASSERT (m_sendAckEvent.IsExpired ());
761  /* See section 11.5.3 in IEEE802.11 for mean of this timer */
762  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
763  if ((*it).second.first.IsImmediateBlockAck ())
764  {
765  NS_LOG_DEBUG ("rx blockAckRequest/sendImmediateBlockAck from=" << hdr.GetAddr2 ());
766  m_sendAckEvent = Simulator::Schedule (GetSifs (),
767  &MacLow::SendBlockAckAfterBlockAckRequest, this,
768  blockAckReq,
769  hdr.GetAddr2 (),
770  hdr.GetDuration (),
771  txMode);
772  }
773  else
774  {
775  NS_FATAL_ERROR ("Delayed block ack not supported.");
776  }
777  }
778  else
779  {
780  NS_LOG_DEBUG ("There's not a valid agreement for this block ack request.");
781  }
782  }
783  else
784  {
785  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
786  }
787  }
788  else if (hdr.IsCtl ())
789  {
790  NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ());
791  }
792  else if (hdr.GetAddr1 () == m_self)
793  {
794  m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
795  rxSnr, txMode);
796 
797  if (hdr.IsQosData () && StoreMpduIfNeeded (packet, hdr))
798  {
799  /* From section 9.10.4 in IEEE802.11:
800  Upon the receipt of a QoS data frame from the originator for which
801  the Block Ack agreement exists, the recipient shall buffer the MSDU
802  regardless of the value of the Ack Policy subfield within the
803  QoS Control field of the QoS data frame. */
804  if (hdr.IsQosAck ())
805  {
806  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
807  RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (),
808  hdr.GetAddr2 (), hdr.GetQosTid ());
809  RxCompleteBufferedPacketsUntilFirstLost (hdr.GetAddr2 (), hdr.GetQosTid ());
810  NS_ASSERT (m_sendAckEvent.IsExpired ());
811  m_sendAckEvent = Simulator::Schedule (GetSifs (),
812  &MacLow::SendAckAfterData, this,
813  hdr.GetAddr2 (),
814  hdr.GetDuration (),
815  txMode,
816  rxSnr);
817  }
818  else if (hdr.IsQosBlockAck ())
819  {
820  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
821  /* See section 11.5.3 in IEEE802.11 for mean of this timer */
822  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
823  }
824  return;
825  }
826  else if (hdr.IsQosData () && hdr.IsQosBlockAck ())
827  {
828  /* This happens if a packet with ack policy Block Ack is received and a block ack
829  agreement for that packet doesn't exist.
830 
831  From section 11.5.3 in IEEE802.11e:
832  When a recipient does not have an active Block ack for a TID, but receives
833  data MPDUs with the Ack Policy subfield set to Block Ack, it shall discard
834  them and shall send a DELBA frame using the normal access
835  mechanisms. */
836  AcIndex ac = QosUtilsMapTidToAc (hdr.GetQosTid ());
837  m_edcaListeners[ac]->BlockAckInactivityTimeout (hdr.GetAddr2 (), hdr.GetQosTid ());
838  return;
839  }
840  else if (hdr.IsQosData () && hdr.IsQosNoAck ())
841  {
842  NS_LOG_DEBUG ("rx unicast/noAck from=" << hdr.GetAddr2 ());
843  }
844  else if (hdr.IsData () || hdr.IsMgt ())
845  {
846  NS_LOG_DEBUG ("rx unicast/sendAck from=" << hdr.GetAddr2 ());
847  NS_ASSERT (m_sendAckEvent.IsExpired ());
848  m_sendAckEvent = Simulator::Schedule (GetSifs (),
849  &MacLow::SendAckAfterData, this,
850  hdr.GetAddr2 (),
851  hdr.GetDuration (),
852  txMode,
853  rxSnr);
854  }
855  goto rxPacket;
856  }
857  else if (hdr.GetAddr1 ().IsGroup ())
858  {
859  if (hdr.IsData () || hdr.IsMgt ())
860  {
861  NS_LOG_DEBUG ("rx group from=" << hdr.GetAddr2 ());
862  goto rxPacket;
863  }
864  else
865  {
866  // DROP
867  }
868  }
869  else if (m_promisc)
870  {
871  NS_ASSERT (hdr.GetAddr1 () != m_self);
872  if (hdr.IsData ())
873  {
874  goto rxPacket;
875  }
876  }
877  else
878  {
879  //NS_LOG_DEBUG_VERBOSE ("rx not-for-me from %d", GetSource (packet));
880  }
881  return;
882 rxPacket:
883  WifiMacTrailer fcs;
884  packet->RemoveTrailer (fcs);
885  m_rxCallback (packet, &hdr);
886  return;
887 }
888 
889 uint32_t
890 MacLow::GetAckSize (void) const
891 {
892  WifiMacHeader ack;
893  ack.SetType (WIFI_MAC_CTL_ACK);
894  return ack.GetSize () + 4;
895 }
896 uint32_t
897 MacLow::GetBlockAckSize (enum BlockAckType type) const
898 {
899  WifiMacHeader hdr;
900  hdr.SetType (WIFI_MAC_CTL_BACKRESP);
901  CtrlBAckResponseHeader blockAck;
902  if (type == BASIC_BLOCK_ACK)
903  {
904  blockAck.SetType (BASIC_BLOCK_ACK);
905  }
906  else if (type == COMPRESSED_BLOCK_ACK)
907  {
908  blockAck.SetType (COMPRESSED_BLOCK_ACK);
909  }
910  else if (type == MULTI_TID_BLOCK_ACK)
911  {
912  //Not implemented
913  NS_ASSERT (false);
914  }
915  return hdr.GetSize () + blockAck.GetSerializedSize () + 4;
916 }
917 uint32_t
918 MacLow::GetRtsSize (void) const
919 {
920  WifiMacHeader rts;
921  rts.SetType (WIFI_MAC_CTL_RTS);
922  return rts.GetSize () + 4;
923 }
924 Time
925 MacLow::GetAckDuration (Mac48Address to, WifiMode dataTxMode) const
926 {
927  WifiMode ackMode = GetAckTxModeForData (to, dataTxMode);
928  return m_phy->CalculateTxDuration (GetAckSize (), ackMode, WIFI_PREAMBLE_LONG);
929 }
930 Time
931 MacLow::GetBlockAckDuration (Mac48Address to, WifiMode blockAckReqTxMode, enum BlockAckType type) const
932 {
933  /*
934  * For immediate BlockAck we should transmit the frame with the same WifiMode
935  * as the BlockAckReq.
936  *
937  * from section 9.6 in IEEE802.11e:
938  * The BlockAck control frame shall be sent at the same rate and modulation class as
939  * the BlockAckReq frame if it is sent in response to a BlockAckReq frame.
940  */
941  return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxMode, WIFI_PREAMBLE_LONG);
942 }
943 Time
944 MacLow::GetCtsDuration (Mac48Address to, WifiMode rtsTxMode) const
945 {
946  WifiMode ctsMode = GetCtsTxModeForRts (to, rtsTxMode);
947  return m_phy->CalculateTxDuration (GetCtsSize (), ctsMode, WIFI_PREAMBLE_LONG);
948 }
949 uint32_t
950 MacLow::GetCtsSize (void) const
951 {
952  WifiMacHeader cts;
953  cts.SetType (WIFI_MAC_CTL_CTS);
954  return cts.GetSize () + 4;
955 }
956 uint32_t
957 MacLow::GetSize (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
958 {
959  WifiMacTrailer fcs;
960  return packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
961 }
962 
963 WifiMode
964 MacLow::GetRtsTxMode (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
965 {
966  Mac48Address to = hdr->GetAddr1 ();
967  return m_stationManager->GetRtsMode (to, hdr, packet);
968 }
969 WifiMode
970 MacLow::GetDataTxMode (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
971 {
972  Mac48Address to = hdr->GetAddr1 ();
973  WifiMacTrailer fcs;
974  uint32_t size = packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
975  return m_stationManager->GetDataMode (to, hdr, packet, size);
976 }
977 
978 WifiMode
979 MacLow::GetCtsTxModeForRts (Mac48Address to, WifiMode rtsTxMode) const
980 {
981  return m_stationManager->GetCtsMode (to, rtsTxMode);
982 }
983 WifiMode
984 MacLow::GetAckTxModeForData (Mac48Address to, WifiMode dataTxMode) const
985 {
986  return m_stationManager->GetAckMode (to, dataTxMode);
987 }
988 
989 
990 Time
991 MacLow::CalculateOverallTxTime (Ptr<const Packet> packet,
992  const WifiMacHeader* hdr,
993  const MacLowTransmissionParameters& params) const
994 {
995  Time txTime = Seconds (0);
996  WifiMode rtsMode = GetRtsTxMode (packet, hdr);
997  WifiMode dataMode = GetDataTxMode (packet, hdr);
998  if (params.MustSendRts ())
999  {
1000  txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsMode, WIFI_PREAMBLE_LONG);
1001  txTime += GetCtsDuration (hdr->GetAddr1 (), rtsMode);
1002  txTime += Time (GetSifs () * 2);
1003  }
1004  uint32_t dataSize = GetSize (packet, hdr);
1005  txTime += m_phy->CalculateTxDuration (dataSize, dataMode, WIFI_PREAMBLE_LONG);
1006  if (params.MustWaitAck ())
1007  {
1008  txTime += GetSifs ();
1009  txTime += GetAckDuration (hdr->GetAddr1 (), dataMode);
1010  }
1011  return txTime;
1012 }
1013 
1014 Time
1016  const WifiMacHeader* hdr,
1017  const MacLowTransmissionParameters& params) const
1018 {
1019  Time txTime = CalculateOverallTxTime (packet, hdr, params);
1020  if (params.HasNextPacket ())
1021  {
1022  WifiMode dataMode = GetDataTxMode (packet, hdr);
1023  txTime += GetSifs ();
1024  txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataMode, WIFI_PREAMBLE_LONG);
1025  }
1026  return txTime;
1027 }
1028 
1029 void
1031 {
1032  NS_ASSERT (m_lastNavStart <= Simulator::Now ());
1033  Time duration = hdr.GetDuration ();
1034 
1035  if (hdr.IsCfpoll ()
1036  && hdr.GetAddr2 () == m_bssid)
1037  {
1038  // see section 9.3.2.2 802.11-1999
1039  DoNavResetNow (duration);
1040  return;
1041  }
1042  // XXX Note that we should also handle CF_END specially here
1043  // but we don't for now because we do not generate them.
1044  else if (hdr.GetAddr1 () != m_self)
1045  {
1046  // see section 9.2.5.4 802.11-1999
1047  bool navUpdated = DoNavStartNow (duration);
1048  if (hdr.IsRts () && navUpdated)
1049  {
1058  WifiMacHeader cts;
1059  cts.SetType (WIFI_MAC_CTL_CTS);
1060  Time navCounterResetCtsMissedDelay =
1061  m_phy->CalculateTxDuration (cts.GetSerializedSize (), txMode, preamble) +
1062  Time (2 * GetSifs ()) + Time (2 * GetSlotTime ());
1063  m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay,
1064  &MacLow::NavCounterResetCtsMissed, this,
1065  Simulator::Now ());
1066  }
1067  }
1068 }
1069 
1070 void
1071 MacLow::NavCounterResetCtsMissed (Time rtsEndRxTime)
1072 {
1073  if (m_phy->GetLastRxStartTime () > rtsEndRxTime)
1074  {
1075  DoNavResetNow (Seconds (0.0));
1076  }
1077 }
1078 
1079 void
1080 MacLow::DoNavResetNow (Time duration)
1081 {
1082  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1083  {
1084  (*i)->NavReset (duration);
1085  }
1086  m_lastNavStart = Simulator::Now ();
1087  m_lastNavStart = duration;
1088 }
1089 bool
1090 MacLow::DoNavStartNow (Time duration)
1091 {
1092  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1093  {
1094  (*i)->NavStart (duration);
1095  }
1096  Time newNavEnd = Simulator::Now () + duration;
1097  Time oldNavEnd = m_lastNavStart + m_lastNavDuration;
1098  if (newNavEnd > oldNavEnd)
1099  {
1100  m_lastNavStart = Simulator::Now ();
1101  m_lastNavDuration = duration;
1102  return true;
1103  }
1104  return false;
1105 }
1106 void
1107 MacLow::NotifyAckTimeoutStartNow (Time duration)
1108 {
1109  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1110  {
1111  (*i)->AckTimeoutStart (duration);
1112  }
1113 }
1114 void
1115 MacLow::NotifyAckTimeoutResetNow ()
1116 {
1117  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1118  {
1119  (*i)->AckTimeoutReset ();
1120  }
1121 }
1122 void
1123 MacLow::NotifyCtsTimeoutStartNow (Time duration)
1124 {
1125  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1126  {
1127  (*i)->CtsTimeoutStart (duration);
1128  }
1129 }
1130 void
1131 MacLow::NotifyCtsTimeoutResetNow ()
1132 {
1133  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1134  {
1135  (*i)->CtsTimeoutReset ();
1136  }
1137 }
1138 
1139 void
1140 MacLow::ForwardDown (Ptr<const Packet> packet, const WifiMacHeader* hdr,
1141  WifiMode txMode)
1142 {
1143  NS_LOG_FUNCTION (this << packet << hdr << txMode);
1144  NS_LOG_DEBUG ("send " << hdr->GetTypeString () <<
1145  ", to=" << hdr->GetAddr1 () <<
1146  ", size=" << packet->GetSize () <<
1147  ", mode=" << txMode <<
1148  ", duration=" << hdr->GetDuration () <<
1149  ", seq=0x" << std::hex << m_currentHdr.GetSequenceControl () << std::dec);
1150  m_phy->SendPacket (packet, txMode, WIFI_PREAMBLE_LONG, 0);
1151 }
1152 
1153 void
1154 MacLow::CtsTimeout (void)
1155 {
1156  NS_LOG_FUNCTION (this);
1157  NS_LOG_DEBUG ("cts timeout");
1158  // XXX: should check that there was no rx start before now.
1159  // we should restart a new cts timeout now until the expected
1160  // end of rx if there was a rx start before now.
1161  m_stationManager->ReportRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1162  m_currentPacket = 0;
1163  MacLowTransmissionListener *listener = m_listener;
1164  m_listener = 0;
1165  listener->MissedCts ();
1166 }
1167 void
1168 MacLow::NormalAckTimeout (void)
1169 {
1170  NS_LOG_FUNCTION (this);
1171  NS_LOG_DEBUG ("normal ack timeout");
1172  // XXX: should check that there was no rx start before now.
1173  // we should restart a new ack timeout now until the expected
1174  // end of rx if there was a rx start before now.
1175  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1176  MacLowTransmissionListener *listener = m_listener;
1177  m_listener = 0;
1178  listener->MissedAck ();
1179 }
1180 void
1181 MacLow::FastAckTimeout (void)
1182 {
1183  NS_LOG_FUNCTION (this);
1184  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1185  MacLowTransmissionListener *listener = m_listener;
1186  m_listener = 0;
1187  if (m_phy->IsStateIdle ())
1188  {
1189  NS_LOG_DEBUG ("fast Ack idle missed");
1190  listener->MissedAck ();
1191  }
1192  else
1193  {
1194  NS_LOG_DEBUG ("fast Ack ok");
1195  }
1196 }
1197 void
1198 MacLow::BlockAckTimeout (void)
1199 {
1200  NS_LOG_FUNCTION (this);
1201  NS_LOG_DEBUG ("block ack timeout");
1202 
1203  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1204  MacLowTransmissionListener *listener = m_listener;
1205  m_listener = 0;
1206  listener->MissedBlockAck ();
1207 }
1208 void
1209 MacLow::SuperFastAckTimeout ()
1210 {
1211  NS_LOG_FUNCTION (this);
1212  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1213  MacLowTransmissionListener *listener = m_listener;
1214  m_listener = 0;
1215  if (m_phy->IsStateIdle ())
1216  {
1217  NS_LOG_DEBUG ("super fast Ack failed");
1218  listener->MissedAck ();
1219  }
1220  else
1221  {
1222  NS_LOG_DEBUG ("super fast Ack ok");
1223  listener->GotAck (0.0, WifiMode ());
1224  }
1225 }
1226 
1227 void
1228 MacLow::SendRtsForPacket (void)
1229 {
1230  NS_LOG_FUNCTION (this);
1231  /* send an RTS for this packet. */
1232  WifiMacHeader rts;
1233  rts.SetType (WIFI_MAC_CTL_RTS);
1234  rts.SetDsNotFrom ();
1235  rts.SetDsNotTo ();
1236  rts.SetNoRetry ();
1237  rts.SetNoMoreFragments ();
1238  rts.SetAddr1 (m_currentHdr.GetAddr1 ());
1239  rts.SetAddr2 (m_self);
1240  WifiMode rtsTxMode = GetRtsTxMode (m_currentPacket, &m_currentHdr);
1241  Time duration = Seconds (0);
1242  if (m_txParams.HasDurationId ())
1243  {
1244  duration += m_txParams.GetDurationId ();
1245  }
1246  else
1247  {
1248  WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
1249  duration += GetSifs ();
1250  duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxMode);
1251  duration += GetSifs ();
1252  duration += m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr),
1253  dataTxMode, WIFI_PREAMBLE_LONG);
1254  duration += GetSifs ();
1255  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
1256  }
1257  rts.SetDuration (duration);
1258 
1259  Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxMode, WIFI_PREAMBLE_LONG);
1260  Time timerDelay = txDuration + GetCtsTimeout ();
1261 
1262  NS_ASSERT (m_ctsTimeoutEvent.IsExpired ());
1263  NotifyCtsTimeoutStartNow (timerDelay);
1264  m_ctsTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::CtsTimeout, this);
1265 
1266  Ptr<Packet> packet = Create<Packet> ();
1267  packet->AddHeader (rts);
1268  WifiMacTrailer fcs;
1269  packet->AddTrailer (fcs);
1270 
1271  ForwardDown (packet, &rts, rtsTxMode);
1272 }
1273 
1274 void
1275 MacLow::StartDataTxTimers (void)
1276 {
1277  WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
1278  Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxMode, WIFI_PREAMBLE_LONG);
1279  if (m_txParams.MustWaitNormalAck ())
1280  {
1281  Time timerDelay = txDuration + GetAckTimeout ();
1282  NS_ASSERT (m_normalAckTimeoutEvent.IsExpired ());
1283  NotifyAckTimeoutStartNow (timerDelay);
1284  m_normalAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::NormalAckTimeout, this);
1285  }
1286  else if (m_txParams.MustWaitFastAck ())
1287  {
1288  Time timerDelay = txDuration + GetPifs ();
1289  NS_ASSERT (m_fastAckTimeoutEvent.IsExpired ());
1290  NotifyAckTimeoutStartNow (timerDelay);
1291  m_fastAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::FastAckTimeout, this);
1292  }
1293  else if (m_txParams.MustWaitSuperFastAck ())
1294  {
1295  Time timerDelay = txDuration + GetPifs ();
1296  NS_ASSERT (m_superFastAckTimeoutEvent.IsExpired ());
1297  NotifyAckTimeoutStartNow (timerDelay);
1298  m_superFastAckTimeoutEvent = Simulator::Schedule (timerDelay,
1299  &MacLow::SuperFastAckTimeout, this);
1300  }
1301  else if (m_txParams.MustWaitBasicBlockAck ())
1302  {
1303  Time timerDelay = txDuration + GetBasicBlockAckTimeout ();
1304  NS_ASSERT (m_blockAckTimeoutEvent.IsExpired ());
1305  m_blockAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::BlockAckTimeout, this);
1306  }
1307  else if (m_txParams.MustWaitCompressedBlockAck ())
1308  {
1309  Time timerDelay = txDuration + GetCompressedBlockAckTimeout ();
1310  NS_ASSERT (m_blockAckTimeoutEvent.IsExpired ());
1311  m_blockAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::BlockAckTimeout, this);
1312  }
1313  else if (m_txParams.HasNextPacket ())
1314  {
1315  Time delay = txDuration + GetSifs ();
1316  NS_ASSERT (m_waitSifsEvent.IsExpired ());
1317  m_waitSifsEvent = Simulator::Schedule (delay, &MacLow::WaitSifsAfterEndTx, this);
1318  }
1319  else
1320  {
1321  // since we do not expect any timer to be triggered.
1322  Simulator::Schedule(txDuration, &MacLow::EndTxNoAck, this);
1323  }
1324 }
1325 
1326 void
1327 MacLow::SendDataPacket (void)
1328 {
1329  NS_LOG_FUNCTION (this);
1330  /* send this packet directly. No RTS is needed. */
1331  StartDataTxTimers ();
1332 
1333  WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
1334  Time duration = Seconds (0.0);
1335  if (m_txParams.HasDurationId ())
1336  {
1337  duration += m_txParams.GetDurationId ();
1338  }
1339  else
1340  {
1341  if (m_txParams.MustWaitBasicBlockAck ())
1342  {
1343  duration += GetSifs ();
1344  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxMode, BASIC_BLOCK_ACK);
1345  }
1346  else if (m_txParams.MustWaitCompressedBlockAck ())
1347  {
1348  duration += GetSifs ();
1349  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxMode, COMPRESSED_BLOCK_ACK);
1350  }
1351  else if (m_txParams.MustWaitAck ())
1352  {
1353  duration += GetSifs ();
1354  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
1355  }
1356  if (m_txParams.HasNextPacket ())
1357  {
1358  duration += GetSifs ();
1359  duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (),
1360  dataTxMode, WIFI_PREAMBLE_LONG);
1361  if (m_txParams.MustWaitAck ())
1362  {
1363  duration += GetSifs ();
1364  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
1365  }
1366  }
1367  }
1368  m_currentHdr.SetDuration (duration);
1369 
1370  m_currentPacket->AddHeader (m_currentHdr);
1371  WifiMacTrailer fcs;
1372  m_currentPacket->AddTrailer (fcs);
1373 
1374  ForwardDown (m_currentPacket, &m_currentHdr, dataTxMode);
1375  m_currentPacket = 0;
1376 }
1377 
1378 bool
1379 MacLow::IsNavZero (void) const
1380 {
1381  if (m_lastNavStart + m_lastNavDuration < Simulator::Now ())
1382  {
1383  return true;
1384  }
1385  else
1386  {
1387  return false;
1388  }
1389 }
1390 
1391 void
1392 MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode rtsTxMode, double rtsSnr)
1393 {
1394  NS_LOG_FUNCTION (this << source << duration << rtsTxMode << rtsSnr);
1395  /* send a CTS when you receive a RTS
1396  * right after SIFS.
1397  */
1398  WifiMode ctsTxMode = GetCtsTxModeForRts (source, rtsTxMode);
1399  WifiMacHeader cts;
1400  cts.SetType (WIFI_MAC_CTL_CTS);
1401  cts.SetDsNotFrom ();
1402  cts.SetDsNotTo ();
1403  cts.SetNoMoreFragments ();
1404  cts.SetNoRetry ();
1405  cts.SetAddr1 (source);
1406  duration -= GetCtsDuration (source, rtsTxMode);
1407  duration -= GetSifs ();
1408  NS_ASSERT (duration >= MicroSeconds (0));
1409  cts.SetDuration (duration);
1410 
1411  Ptr<Packet> packet = Create<Packet> ();
1412  packet->AddHeader (cts);
1413  WifiMacTrailer fcs;
1414  packet->AddTrailer (fcs);
1415 
1416  SnrTag tag;
1417  tag.Set (rtsSnr);
1418  packet->AddPacketTag (tag);
1419 
1420  ForwardDown (packet, &cts, ctsTxMode);
1421 }
1422 
1423 void
1424 MacLow::SendDataAfterCts (Mac48Address source, Time duration, WifiMode txMode)
1425 {
1426  NS_LOG_FUNCTION (this);
1427  /* send the third step in a
1428  * RTS/CTS/DATA/ACK hanshake
1429  */
1430  NS_ASSERT (m_currentPacket != 0);
1431  StartDataTxTimers ();
1432 
1433  WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
1434  Time newDuration = Seconds (0);
1435  newDuration += GetSifs ();
1436  newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
1437  Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr),
1438  dataTxMode, WIFI_PREAMBLE_LONG);
1439  duration -= txDuration;
1440  duration -= GetSifs ();
1441 
1442  duration = std::max (duration, newDuration);
1443  NS_ASSERT (duration >= MicroSeconds (0));
1444  m_currentHdr.SetDuration (duration);
1445 
1446  m_currentPacket->AddHeader (m_currentHdr);
1447  WifiMacTrailer fcs;
1448  m_currentPacket->AddTrailer (fcs);
1449 
1450  ForwardDown (m_currentPacket, &m_currentHdr, dataTxMode);
1451  m_currentPacket = 0;
1452 }
1453 
1454 void
1455 MacLow::WaitSifsAfterEndTx (void)
1456 {
1457  m_listener->StartNext ();
1458 }
1459 
1460 void
1461 MacLow::EndTxNoAck (void)
1462 {
1463  MacLowTransmissionListener *listener = m_listener;
1464  m_listener = 0;
1465  listener->EndTxNoAck ();
1466 }
1467 
1468 void
1469 MacLow::FastAckFailedTimeout (void)
1470 {
1471  NS_LOG_FUNCTION (this);
1472  MacLowTransmissionListener *listener = m_listener;
1473  m_listener = 0;
1474  listener->MissedAck ();
1475  NS_LOG_DEBUG ("fast Ack busy but missed");
1476 }
1477 
1478 void
1479 MacLow::SendAckAfterData (Mac48Address source, Time duration, WifiMode dataTxMode, double dataSnr)
1480 {
1481  NS_LOG_FUNCTION (this);
1482  /* send an ACK when you receive
1483  * a packet after SIFS.
1484  */
1485  WifiMode ackTxMode = GetAckTxModeForData (source, dataTxMode);
1486  WifiMacHeader ack;
1487  ack.SetType (WIFI_MAC_CTL_ACK);
1488  ack.SetDsNotFrom ();
1489  ack.SetDsNotTo ();
1490  ack.SetNoRetry ();
1491  ack.SetNoMoreFragments ();
1492  ack.SetAddr1 (source);
1493  duration -= GetAckDuration (source, dataTxMode);
1494  duration -= GetSifs ();
1495  NS_ASSERT (duration >= MicroSeconds (0));
1496  ack.SetDuration (duration);
1497 
1498  Ptr<Packet> packet = Create<Packet> ();
1499  packet->AddHeader (ack);
1500  WifiMacTrailer fcs;
1501  packet->AddTrailer (fcs);
1502 
1503  SnrTag tag;
1504  tag.Set (dataSnr);
1505  packet->AddPacketTag (tag);
1506 
1507  ForwardDown (packet, &ack, ackTxMode);
1508 }
1509 
1510 bool
1511 MacLow::StoreMpduIfNeeded (Ptr<Packet> packet, WifiMacHeader hdr)
1512 {
1513  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1514  if (it != m_bAckAgreements.end ())
1515  {
1516  WifiMacTrailer fcs;
1517  packet->RemoveTrailer (fcs);
1518  BufferedPacket bufferedPacket (packet, hdr);
1519 
1520  uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
1521  uint16_t mappedSeqControl = QosUtilsMapSeqControlToUniqueInteger (hdr.GetSequenceControl (), endSequence);
1522 
1523  BufferedPacketI i = (*it).second.second.begin ();
1524  for (; i != (*it).second.second.end ()
1525  && QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceControl (), endSequence) < mappedSeqControl; i++)
1526  {
1527  ;
1528  }
1529  (*it).second.second.insert (i, bufferedPacket);
1530 
1531  //Update block ack cache
1532  BlockAckCachesI j = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1533  NS_ASSERT (j != m_bAckCaches.end ());
1534  (*j).second.UpdateWithMpdu (&hdr);
1535 
1536  return true;
1537  }
1538  return false;
1539 }
1540 
1541 void
1543  uint16_t startingSeq)
1544 {
1545  uint8_t tid = respHdr->GetTid ();
1546  BlockAckAgreement agreement (originator, tid);
1547  if (respHdr->IsImmediateBlockAck ())
1548  {
1549  agreement.SetImmediateBlockAck ();
1550  }
1551  else
1552  {
1553  agreement.SetDelayedBlockAck ();
1554  }
1555  agreement.SetAmsduSupport (respHdr->IsAmsduSupported ());
1556  agreement.SetBufferSize (respHdr->GetBufferSize () + 1);
1557  agreement.SetTimeout (respHdr->GetTimeout ());
1558  agreement.SetStartingSequence (startingSeq);
1559 
1560  std::list<BufferedPacket> buffer (0);
1561  AgreementKey key (originator, respHdr->GetTid ());
1562  AgreementValue value (agreement, buffer);
1563  m_bAckAgreements.insert (std::make_pair (key, value));
1564 
1565  BlockAckCache cache;
1566  cache.Init (startingSeq, respHdr->GetBufferSize () + 1);
1567  m_bAckCaches.insert (std::make_pair (key, cache));
1568 
1569  if (respHdr->GetTimeout () != 0)
1570  {
1571  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, respHdr->GetTid ()));
1572  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
1573 
1574  AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
1575 
1576  it->second.first.m_inactivityEvent = Simulator::Schedule (timeout,
1578  m_edcaListeners[ac],
1579  originator, tid);
1580  }
1581 }
1582 
1583 void
1585 {
1586  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1587  if (it != m_bAckAgreements.end ())
1588  {
1589  RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (), originator, tid);
1590  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
1591  m_bAckAgreements.erase (it);
1592 
1593  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
1594  NS_ASSERT (i != m_bAckCaches.end ());
1595  m_bAckCaches.erase (i);
1596  }
1597 }
1598 
1599 void
1601 {
1602  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1603  if (it != m_bAckAgreements.end ())
1604  {
1605  uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
1606  uint16_t mappedStart = QosUtilsMapSeqControlToUniqueInteger (seq, endSequence);
1607  uint16_t guard = (*it).second.second.begin ()->second.GetSequenceControl () & 0xfff0;
1608  BufferedPacketI last = (*it).second.second.begin ();
1609 
1610  BufferedPacketI i = (*it).second.second.begin ();
1611  for (; i != (*it).second.second.end ()
1612  && QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceNumber (), endSequence) < mappedStart;)
1613  {
1614  if (guard == (*i).second.GetSequenceControl ())
1615  {
1616  if (!(*i).second.IsMoreFragments ())
1617  {
1618  while (last != i)
1619  {
1620  m_rxCallback ((*last).first, &(*last).second);
1621  last++;
1622  }
1623  m_rxCallback ((*last).first, &(*last).second);
1624  last++;
1625  /* go to next packet */
1626  while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
1627  {
1628  i++;
1629  }
1630  if (i != (*it).second.second.end ())
1631  {
1632  guard = (*i).second.GetSequenceControl () & 0xfff0;
1633  last = i;
1634  }
1635  }
1636  else
1637  {
1638  guard++;
1639  }
1640  }
1641  else
1642  {
1643  /* go to next packet */
1644  while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
1645  {
1646  i++;
1647  }
1648  if (i != (*it).second.second.end ())
1649  {
1650  guard = (*i).second.GetSequenceControl () & 0xfff0;
1651  last = i;
1652  }
1653  }
1654  }
1655  (*it).second.second.erase ((*it).second.second.begin (), i);
1656  }
1657 }
1658 
1659 void
1661 {
1662  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1663  if (it != m_bAckAgreements.end ())
1664  {
1665  uint16_t startingSeqCtrl = ((*it).second.first.GetStartingSequence () << 4) & 0xfff0;
1666  uint16_t guard = startingSeqCtrl;
1667 
1668  BufferedPacketI lastComplete = (*it).second.second.begin ();
1669  BufferedPacketI i = (*it).second.second.begin ();
1670  for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
1671  {
1672  if (!(*i).second.IsMoreFragments ())
1673  {
1674  while (lastComplete != i)
1675  {
1676  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
1677  lastComplete++;
1678  }
1679  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
1680  lastComplete++;
1681  }
1682  guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
1683  }
1684  (*it).second.first.SetStartingSequence ((guard >> 4) & 0x0fff);
1685  /* All packets already forwarded to WifiMac must be removed from buffer:
1686  [begin (), lastComplete) */
1687  (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
1688  }
1689 }
1690 
1691 void
1692 MacLow::SendBlockAckResponse (const CtrlBAckResponseHeader* blockAck, Mac48Address originator, bool immediate,
1693  Time duration, WifiMode blockAckReqTxMode)
1694 {
1695  Ptr<Packet> packet = Create<Packet> ();
1696  packet->AddHeader (*blockAck);
1697 
1698  WifiMacHeader hdr;
1699  hdr.SetType (WIFI_MAC_CTL_BACKRESP);
1700  hdr.SetAddr1 (originator);
1701  hdr.SetAddr2 (GetAddress ());
1702  hdr.SetDsNotFrom ();
1703  hdr.SetDsNotTo ();
1704  hdr.SetNoRetry ();
1705  hdr.SetNoMoreFragments ();
1706 
1707  m_currentPacket = packet;
1708  m_currentHdr = hdr;
1709  if (immediate)
1710  {
1711  m_txParams.DisableAck ();
1712  duration -= GetSifs ();
1713  if (blockAck->IsBasic ())
1714  {
1715  duration -= GetBlockAckDuration (originator, blockAckReqTxMode, BASIC_BLOCK_ACK);
1716  }
1717  else if (blockAck->IsCompressed ())
1718  {
1719  duration -= GetBlockAckDuration (originator, blockAckReqTxMode, COMPRESSED_BLOCK_ACK);
1720  }
1721  else if (blockAck->IsMultiTid ())
1722  {
1723  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
1724  }
1725  }
1726  else
1727  {
1728  m_txParams.EnableAck ();
1729  duration += GetSifs ();
1730  duration += GetAckDuration (originator, blockAckReqTxMode);
1731  }
1732  m_txParams.DisableNextData ();
1733 
1734  if (!immediate)
1735  {
1736  StartDataTxTimers ();
1737  }
1738 
1739  NS_ASSERT (duration >= MicroSeconds (0));
1740  hdr.SetDuration (duration);
1741  //here should be present a control about immediate or delayed block ack
1742  //for now we assume immediate
1743  packet->AddHeader (hdr);
1744  WifiMacTrailer fcs;
1745  packet->AddTrailer (fcs);
1746  ForwardDown (packet, &hdr, blockAckReqTxMode);
1747  m_currentPacket = 0;
1748 }
1749 
1750 void
1751 MacLow::SendBlockAckAfterBlockAckRequest (const CtrlBAckRequestHeader reqHdr, Mac48Address originator,
1752  Time duration, WifiMode blockAckReqTxMode)
1753 {
1754  NS_LOG_FUNCTION (this);
1755  CtrlBAckResponseHeader blockAck;
1756  uint8_t tid;
1757  bool immediate = false;
1758  if (!reqHdr.IsMultiTid ())
1759  {
1760  tid = reqHdr.GetTidInfo ();
1761  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1762  if (it != m_bAckAgreements.end ())
1763  {
1764  blockAck.SetStartingSequence (reqHdr.GetStartingSequence ());
1765  blockAck.SetTidInfo (tid);
1766  immediate = (*it).second.first.IsImmediateBlockAck ();
1767  if (reqHdr.IsBasic ())
1768  {
1769  blockAck.SetType (BASIC_BLOCK_ACK);
1770  }
1771  else if (reqHdr.IsCompressed ())
1772  {
1773  blockAck.SetType (COMPRESSED_BLOCK_ACK);
1774  }
1775  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
1776  NS_ASSERT (i != m_bAckCaches.end ());
1777  (*i).second.FillBlockAckBitmap (&blockAck);
1778 
1779  /* All packets with smaller sequence than starting sequence control must be passed up to Wifimac
1780  * See 9.10.3 in IEEE8022.11e standard.
1781  */
1782  RxCompleteBufferedPacketsWithSmallerSequence (reqHdr.GetStartingSequence (), originator, tid);
1783  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
1784  }
1785  else
1786  {
1787  NS_LOG_DEBUG ("there's not a valid block ack agreement with " << originator);
1788  }
1789  }
1790  else
1791  {
1792  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
1793  }
1794 
1795  SendBlockAckResponse (&blockAck, originator, immediate, duration, blockAckReqTxMode);
1796 }
1797 
1798 void
1799 MacLow::ResetBlockAckInactivityTimerIfNeeded (BlockAckAgreement &agreement)
1800 {
1801  if (agreement.GetTimeout () != 0)
1802  {
1803  NS_ASSERT (agreement.m_inactivityEvent.IsRunning ());
1804  agreement.m_inactivityEvent.Cancel ();
1805  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
1806 
1807  AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
1808  //std::map<AcIndex, MacLowTransmissionListener*>::iterator it = m_edcaListeners.find (ac);
1809  //NS_ASSERT (it != m_edcaListeners.end ());
1810 
1811  agreement.m_inactivityEvent = Simulator::Schedule (timeout,
1813  m_edcaListeners[ac],
1814  agreement.GetPeer (),
1815  agreement.GetTid ());
1816  }
1817 }
1818 
1819 void
1821 {
1822  m_edcaListeners.insert (std::make_pair (ac, listener));
1823 }
1824 
1825 void
1826 MacLow::SetTxRadio(bool isTx)
1827 {
1828  m_tx = isTx;
1829 }
1830 
1831 bool
1832 MacLow::IsTxRadio()
1833 {
1834  return m_tx;
1835 }
1836 
1837 void
1838 MacLow::SetRxRadio(bool isRx)
1839 {
1840  m_rx = isRx;
1841 }
1842 
1843 bool
1844 MacLow::IsRxRadio()
1845 {
1846  return m_rx;
1847 }
1848 } // namespace ns3
uint32_t RemoveHeader(Header &header)
Definition: packet.cc:285
bool MustSendRts(void) const
Definition: mac-low.cc:183
keep track of time unit.
Definition: nstime.h:149
virtual void SendPacket(Ptr< const Packet > packet, WifiMode mode, enum WifiPreamble preamble, uint8_t txPowerLevel)=0
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
Callback template class.
Definition: callback.h:369
virtual void GotAck(double snr, WifiMode txMode)=0
virtual void MissedAck(void)=0
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
virtual void NotifyRxEndError(void)
Definition: mac-low.cc:267
virtual void BlockAckInactivityTimeout(Mac48Address originator, uint8_t tid)=0
bool HasDurationId(void) const
Definition: mac-low.cc:188
bool IsRunning(void) const
Definition: event-id.cc:59
void SetRxCallback(Callback< void, Ptr< Packet >, const WifiMacHeader * > callback)
Definition: mac-low.cc:529
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
listen to events coming from ns3::MacLow.
Definition: mac-low.h:55
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:88
bool MustWaitFastAck(void) const
Definition: mac-low.cc:158
control how a packet is transmitted.The ns3::MacLow::StartTransmission method expects an instance of ...
Definition: mac-low.h:194
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
virtual bool IsStateIdle(void)=0
WifiPreamble
Definition: wifi-preamble.h:29
void DestroyBlockAckAgreement(Mac48Address originator, uint8_t tid)
Definition: mac-low.cc:1584
virtual uint32_t GetSerializedSize(void) const
virtual void SetReceiveErrorCallback(RxErrorCallback callback)=0
void CreateBlockAckAgreement(const MgtAddBaResponseHeader *respHdr, Mac48Address originator, uint16_t startingSeq)
Definition: mac-low.cc:1542
receive notifications about phy events.
Definition: wifi-phy.h:44
virtual void StartNext(void)=0
virtual void EndTxNoAck(void)=0
virtual void GotCts(double snr, WifiMode txMode)=0
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Definition: qos-utils.cc:27
virtual void NotifyRxStart(Time duration)
Definition: mac-low.cc:261
bool MustWaitMultiTidBlockAck(void) const
Definition: mac-low.cc:178
Headers for Block ack response.
Definition: ctrl-headers.h:102
uint32_t GetNextPacketSize(void) const
Definition: mac-low.cc:204
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
bool HasNextPacket(void) const
Definition: mac-low.cc:199
static Time CalculateTxDuration(uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble)
Definition: wifi-phy.cc:294
void RegisterDcfListener(MacLowDcfListener *listener)
Definition: mac-low.cc:534
void NotifySwitchingStartNow(Time duration)
Definition: mac-low.cc:600
void StartTransmission(Ptr< const Packet > packet, const WifiMacHeader *hdr, MacLowTransmissionParameters parameters, MacLowTransmissionListener *listener)
Definition: mac-low.cc:541
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:43
Ptr< Packet > Copy(void) const
Definition: packet.cc:131
listen for block ack events.
Definition: mac-low.h:169
bool IsGroup(void) const
Time CalculateTransmissionTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters &parameters) const
Definition: mac-low.cc:1015
void AddTrailer(const Trailer &trailer)
Definition: packet.cc:301
bool MustWaitBasicBlockAck(void) const
Definition: mac-low.cc:168
bool MustWaitCompressedBlockAck(void) const
Definition: mac-low.cc:173
uint32_t RemoveTrailer(Trailer &trailer)
Definition: packet.cc:317
an EUI-48 address
Definition: mac48-address.h:41
virtual void Cancel(void)=0
void NotifyNav(const WifiMacHeader &hdr, WifiMode txMode, WifiPreamble preamble)
Definition: mac-low.cc:1030
virtual void NotifySensingStart(Time duration)
Definition: mac-low.cc:280
listen to NAV eventsThis class is typically connected to an instance of ns3::Dcf and calls to its met...
Definition: mac-low.h:146
static Time Now(void)
Definition: simulator.cc:179
void RxCompleteBufferedPacketsWithSmallerSequence(uint16_t seq, Mac48Address originator, uint8_t tid)
Definition: mac-low.cc:1600
virtual bool IsStateTx(void)=0
Time GetDurationId(void) const
Definition: mac-low.cc:193
virtual void MissedBlockAck(void)
Definition: mac-low.cc:58
void ReceiveError(Ptr< const Packet > packet, double rxSnr)
Definition: mac-low.cc:586
virtual void NotifyMaybeCcaBusyStart(Time duration)
Definition: mac-low.cc:273
handle RTS/CTS/DATA/ACK transactions.
Definition: mac-low.h:379
virtual void MissedCts(void)=0
virtual void DoDispose(void)
Definition: mac-low.cc:326
bool MustWaitSuperFastAck(void) const
Definition: mac-low.cc:163
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
Maintains information for a block ack agreement.
uint32_t QosUtilsMapSeqControlToUniqueInteger(uint16_t seqControl, uint16_t endSequence)
Definition: qos-utils.cc:75
bool RemovePacketTag(Tag &tag)
Definition: packet.cc:874
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
virtual void NotifyTxStart(Time duration)
Definition: mac-low.cc:270
virtual void GotBlockAck(const CtrlBAckResponseHeader *blockAck, Mac48Address source)
Definition: mac-low.cc:53
void NotifySensingStartNow(Time duration)
Definition: mac-low.cc:616
virtual void NotifySwitchingStart(Time duration, uint16_t toChannel)
Definition: mac-low.cc:276
void EnableOverrideDurationId(Time durationId)
Definition: mac-low.cc:93
virtual void SetReceiveOkCallback(RxOkCallback callback)=0
void Cancel(void)
Definition: event-id.cc:47
void EnableNextData(uint32_t size)
Definition: mac-low.cc:83
void ReceiveOk(Ptr< Packet > packet, double rxSnr, WifiMode txMode, WifiPreamble preamble)
Definition: mac-low.cc:632
bool MustWaitAck(void) const
Definition: mac-low.cc:148
Headers for Block ack request.
Definition: ctrl-headers.h:46
void RegisterBlockAckListenerForAc(enum AcIndex ac, MacLowBlockAckEventListener *listener)
Definition: mac-low.cc:1820
bool IsExpired(void) const
Definition: event-id.cc:53
AcIndex
Definition: qos-utils.h:35
Time MicroSeconds(uint64_t us)
create ns3::Time instances in units of microseconds.
Definition: nstime.h:615
bool MustWaitNormalAck(void) const
Definition: mac-low.cc:153
void AddHeader(const Header &header)
Definition: packet.cc:270
virtual void NotifyRxEndOk(void)
Definition: mac-low.cc:264
void RxCompleteBufferedPacketsUntilFirstLost(Mac48Address originator, uint8_t tid)
Definition: mac-low.cc:1660