A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
mac-low.cc
Go to the documentation of this file.
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 
47 {
48 }
50 {
51 }
52 void
54  Mac48Address source)
55 {
56 }
57 void
59 {
60 }
62 {
63 }
65 {
66 }
67 
69 {
70 }
72 {
73 }
74 
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 {
101 }
102 void
104 {
106 }
107 void
109 {
111 }
112 void
114 {
116 }
117 void
119 {
121 }
122 void
124 {
126 }
127 void
129 {
131 }
132 void
134 {
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 {
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  {
220  os << "none";
221  break;
223  os << "normal";
224  break;
226  os << "fast";
227  break;
229  os << "super-fast";
230  break;
232  os << "basic-block-ack";
233  break;
235  os << "compressed-block-ack";
236  break;
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  }
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)
277  {
278  m_macLow->NotifySwitchingStartNow (duration);
279  }
280 private:
282 };
283 
284 
286  : m_normalAckTimeoutEvent (),
287  m_fastAckTimeoutEvent (),
288  m_superFastAckTimeoutEvent (),
289  m_fastAckFailedTimeoutEvent (),
290  m_blockAckTimeoutEvent (),
291  m_ctsTimeoutEvent (),
292  m_sendCtsEvent (),
293  m_sendAckEvent (),
294  m_sendDataEvent (),
295  m_waitSifsEvent (),
296  m_endTxNoAckEvent (),
297  m_currentPacket (0),
298  m_listener (0)
299 {
300  NS_LOG_FUNCTION (this);
302  m_lastNavStart = Seconds (0);
303  m_promisc = false;
304 }
305 
307 {
308  NS_LOG_FUNCTION (this);
309 }
310 
311 void
313 {
316 }
317 
318 
319 void
321 {
322  NS_LOG_FUNCTION (this);
334  m_phy = 0;
335  m_stationManager = 0;
336  delete m_phyMacLowListener;
338 }
339 
340 void
342 {
343  NS_LOG_FUNCTION (this);
344  bool oneRunning = false;
346  {
348  oneRunning = true;
349  }
351  {
353  oneRunning = true;
354  }
356  {
358  oneRunning = true;
359  }
361  {
363  oneRunning = true;
364  }
366  {
368  oneRunning = true;
369  }
371  {
373  oneRunning = true;
374  }
375  if (m_sendCtsEvent.IsRunning ())
376  {
378  oneRunning = true;
379  }
380  if (m_sendAckEvent.IsRunning ())
381  {
383  oneRunning = true;
384  }
385  if (m_sendDataEvent.IsRunning ())
386  {
388  oneRunning = true;
389  }
390  if (m_waitSifsEvent.IsRunning ())
391  {
393  oneRunning = true;
394  }
396  {
398  oneRunning = true;
399  }
400  if (oneRunning && m_listener != 0)
401  {
402  m_listener->Cancel ();
403  m_listener = 0;
404  }
405 }
406 
407 void
409 {
410  m_phy = phy;
414 }
415 void
417 {
418  m_stationManager = manager;
419 }
420 
421 void
423 {
424  m_self = ad;
425 }
426 void
428 {
429  m_ackTimeout = ackTimeout;
430 }
431 void
433 {
434  m_basicBlockAckTimeout = blockAckTimeout;
435 }
436 void
438 {
439  m_compressedBlockAckTimeout = blockAckTimeout;
440 }
441 void
443 {
444  m_ctsTimeout = ctsTimeout;
445 }
446 void
448 {
449  m_sifs = sifs;
450 }
451 void
453 {
454  m_slotTime = slotTime;
455 }
456 void
458 {
459  m_pifs = pifs;
460 }
461 void
463 {
464  m_bssid = bssid;
465 }
466 void
468 {
469  m_promisc = true;
470 }
472 MacLow::GetAddress (void) const
473 {
474  return m_self;
475 }
476 Time
478 {
479  return m_ackTimeout;
480 }
481 Time
483 {
484  return m_basicBlockAckTimeout;
485 }
486 Time
488 {
490 }
491 Time
493 {
494  return m_ctsTimeout;
495 }
496 Time
497 MacLow::GetSifs (void) const
498 {
499  return m_sifs;
500 }
501 Time
503 {
504  return m_slotTime;
505 }
506 Time
507 MacLow::GetPifs (void) const
508 {
509  return m_pifs;
510 }
512 MacLow::GetBssid (void) const
513 {
514  return m_bssid;
515 }
516 
517 void
519 {
520  m_rxCallback = callback;
521 }
522 void
524 {
525  m_dcfListeners.push_back (listener);
526 }
527 
528 
529 void
531  const WifiMacHeader* hdr,
533  MacLowTransmissionListener *listener)
534 {
535  NS_LOG_FUNCTION (this << packet << hdr << params << listener);
536  /* m_currentPacket is not NULL because someone started
537  * a transmission and was interrupted before one of:
538  * - ctsTimeout
539  * - sendDataAfterCTS
540  * expired. This means that one of these timers is still
541  * running. They are all cancelled below anyway by the
542  * call to CancelAllEvents (because of at least one
543  * of these two timer) which will trigger a call to the
544  * previous listener's cancel method.
545  *
546  * This typically happens because the high-priority
547  * QapScheduler has taken access to the channel from
548  * one of the Edca of the QAP.
549  */
550  m_currentPacket = packet->Copy ();
551  m_currentHdr = *hdr;
552  CancelAllEvents ();
553  m_listener = listener;
554  m_txParams = params;
555 
556  //NS_ASSERT (m_phy->IsStateIdle ());
557 
558  NS_LOG_DEBUG ("startTx size=" << GetSize (m_currentPacket, &m_currentHdr) <<
559  ", to=" << m_currentHdr.GetAddr1 () << ", listener=" << m_listener);
560 
561  if (m_txParams.MustSendRts ())
562  {
563  SendRtsForPacket ();
564  }
565  else
566  {
567  SendDataPacket ();
568  }
569 
570  /* When this method completes, we have taken ownership of the medium. */
571  NS_ASSERT (m_phy->IsStateTx ());
572 }
573 
574 void
576 {
577  NS_LOG_FUNCTION (this << packet << rxSnr);
578  NS_LOG_DEBUG ("rx failed ");
580  {
584  }
585  return;
586 }
587 
588 void
590 {
591  NS_LOG_DEBUG ("switching channel. Cancelling MAC pending events");
593  CancelAllEvents ();
595  {
597  }
600  m_currentPacket = 0;
601  m_listener = 0;
602 }
603 
604 void
605 MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamble preamble)
606 {
607  NS_LOG_FUNCTION (this << packet << rxSnr << txMode << preamble);
608  /* A packet is received from the PHY.
609  * When we have handled this packet,
610  * we handle any packet present in the
611  * packet queue.
612  */
613  WifiMacHeader hdr;
614  packet->RemoveHeader (hdr);
615 
616  bool isPrevNavZero = IsNavZero ();
617  NS_LOG_DEBUG ("duration/id=" << hdr.GetDuration ());
618  NotifyNav (hdr, txMode, preamble);
619  if (hdr.IsRts ())
620  {
621  /* see section 9.2.5.7 802.11-1999
622  * A STA that is addressed by an RTS frame shall transmit a CTS frame after a SIFS
623  * period if the NAV at the STA receiving the RTS frame indicates that the medium is
624  * idle. If the NAV at the STA receiving the RTS indicates the medium is not idle,
625  * that STA shall not respond to the RTS frame.
626  */
627  if (isPrevNavZero
628  && hdr.GetAddr1 () == m_self)
629  {
630  NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
632  m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
633  rxSnr, txMode);
636  hdr.GetAddr2 (),
637  hdr.GetDuration (),
638  txMode,
639  rxSnr);
640  }
641  else
642  {
643  NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
644  }
645  }
646  else if (hdr.IsCts ()
647  && hdr.GetAddr1 () == m_self
649  && m_currentPacket != 0)
650  {
651  NS_LOG_DEBUG ("receive cts from=" << m_currentHdr.GetAddr1 ());
652  SnrTag tag;
653  packet->RemovePacketTag (tag);
655  rxSnr, txMode);
657  rxSnr, txMode, tag.Get ());
658 
661  m_listener->GotCts (rxSnr, txMode);
665  hdr.GetAddr1 (),
666  hdr.GetDuration (),
667  txMode);
668  }
669  else if (hdr.IsAck ()
670  && hdr.GetAddr1 () == m_self
674  && m_txParams.MustWaitAck ())
675  {
676  NS_LOG_DEBUG ("receive ack from=" << m_currentHdr.GetAddr1 ());
677  SnrTag tag;
678  packet->RemovePacketTag (tag);
680  rxSnr, txMode);
682  rxSnr, txMode, tag.Get ());
683  bool gotAck = false;
686  {
689  gotAck = true;
690  }
693  {
696  gotAck = true;
697  }
698  if (gotAck)
699  {
700  m_listener->GotAck (rxSnr, txMode);
701  }
702  if (m_txParams.HasNextPacket ())
703  {
706  }
707  }
708  else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self
711  {
712  NS_LOG_DEBUG ("got block ack from " << hdr.GetAddr2 ());
713  CtrlBAckResponseHeader blockAck;
714  packet->RemoveHeader (blockAck);
716  m_listener->GotBlockAck (&blockAck, hdr.GetAddr2 ());
717  }
718  else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
719  {
720  CtrlBAckRequestHeader blockAckReq;
721  packet->RemoveHeader (blockAckReq);
722  if (!blockAckReq.IsMultiTid ())
723  {
724  uint8_t tid = blockAckReq.GetTidInfo ();
725  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), tid));
726  if (it != m_bAckAgreements.end ())
727  {
728  //Update block ack cache
729  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), tid));
730  NS_ASSERT (i != m_bAckCaches.end ());
731  (*i).second.UpdateWithBlockAckReq (blockAckReq.GetStartingSequence ());
732 
734  /* See section 11.5.3 in IEEE802.11 for mean of this timer */
735  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
736  if ((*it).second.first.IsImmediateBlockAck ())
737  {
738  NS_LOG_DEBUG ("rx blockAckRequest/sendImmediateBlockAck from=" << hdr.GetAddr2 ());
741  blockAckReq,
742  hdr.GetAddr2 (),
743  hdr.GetDuration (),
744  txMode);
745  }
746  else
747  {
748  NS_FATAL_ERROR ("Delayed block ack not supported.");
749  }
750  }
751  else
752  {
753  NS_LOG_DEBUG ("There's not a valid agreement for this block ack request.");
754  }
755  }
756  else
757  {
758  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
759  }
760  }
761  else if (hdr.IsCtl ())
762  {
763  NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ());
764  }
765  else if (hdr.GetAddr1 () == m_self)
766  {
767  m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
768  rxSnr, txMode);
769 
770  if (hdr.IsQosData () && StoreMpduIfNeeded (packet, hdr))
771  {
772  /* From section 9.10.4 in IEEE802.11:
773  Upon the receipt of a QoS data frame from the originator for which
774  the Block Ack agreement exists, the recipient shall buffer the MSDU
775  regardless of the value of the Ack Policy subfield within the
776  QoS Control field of the QoS data frame. */
777  if (hdr.IsQosAck ())
778  {
779  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
780  RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (),
781  hdr.GetAddr2 (), hdr.GetQosTid ());
786  hdr.GetAddr2 (),
787  hdr.GetDuration (),
788  txMode,
789  rxSnr);
790  }
791  else if (hdr.IsQosBlockAck ())
792  {
793  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
794  /* See section 11.5.3 in IEEE802.11 for mean of this timer */
795  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
796  }
797  return;
798  }
799  else if (hdr.IsQosData () && hdr.IsQosBlockAck ())
800  {
801  /* This happens if a packet with ack policy Block Ack is received and a block ack
802  agreement for that packet doesn't exist.
803 
804  From section 11.5.3 in IEEE802.11e:
805  When a recipient does not have an active Block ack for a TID, but receives
806  data MPDUs with the Ack Policy subfield set to Block Ack, it shall discard
807  them and shall send a DELBA frame using the normal access
808  mechanisms. */
809  AcIndex ac = QosUtilsMapTidToAc (hdr.GetQosTid ());
810  m_edcaListeners[ac]->BlockAckInactivityTimeout (hdr.GetAddr2 (), hdr.GetQosTid ());
811  return;
812  }
813  else if (hdr.IsQosData () && hdr.IsQosNoAck ())
814  {
815  NS_LOG_DEBUG ("rx unicast/noAck from=" << hdr.GetAddr2 ());
816  }
817  else if (hdr.IsData () || hdr.IsMgt ())
818  {
819  NS_LOG_DEBUG ("rx unicast/sendAck from=" << hdr.GetAddr2 ());
823  hdr.GetAddr2 (),
824  hdr.GetDuration (),
825  txMode,
826  rxSnr);
827  }
828  goto rxPacket;
829  }
830  else if (hdr.GetAddr1 ().IsGroup ())
831  {
832  if (hdr.IsData () || hdr.IsMgt ())
833  {
834  NS_LOG_DEBUG ("rx group from=" << hdr.GetAddr2 ());
835  goto rxPacket;
836  }
837  else
838  {
839  // DROP
840  }
841  }
842  else if (m_promisc)
843  {
844  NS_ASSERT (hdr.GetAddr1 () != m_self);
845  if (hdr.IsData ())
846  {
847  goto rxPacket;
848  }
849  }
850  else
851  {
852  //NS_LOG_DEBUG_VERBOSE ("rx not-for-me from %d", GetSource (packet));
853  }
854  return;
855 rxPacket:
856  WifiMacTrailer fcs;
857  packet->RemoveTrailer (fcs);
858  m_rxCallback (packet, &hdr);
859  return;
860 }
861 
862 uint32_t
863 MacLow::GetAckSize (void) const
864 {
865  WifiMacHeader ack;
867  return ack.GetSize () + 4;
868 }
869 uint32_t
871 {
872  WifiMacHeader hdr;
874  CtrlBAckResponseHeader blockAck;
875  if (type == BASIC_BLOCK_ACK)
876  {
877  blockAck.SetType (BASIC_BLOCK_ACK);
878  }
879  else if (type == COMPRESSED_BLOCK_ACK)
880  {
881  blockAck.SetType (COMPRESSED_BLOCK_ACK);
882  }
883  else if (type == MULTI_TID_BLOCK_ACK)
884  {
885  //Not implemented
886  NS_ASSERT (false);
887  }
888  return hdr.GetSize () + blockAck.GetSerializedSize () + 4;
889 }
890 uint32_t
891 MacLow::GetRtsSize (void) const
892 {
893  WifiMacHeader rts;
895  return rts.GetSize () + 4;
896 }
897 Time
899 {
900  WifiMode ackMode = GetAckTxModeForData (to, dataTxMode);
902 }
903 Time
904 MacLow::GetBlockAckDuration (Mac48Address to, WifiMode blockAckReqTxMode, enum BlockAckType type) const
905 {
906  /*
907  * For immediate BlockAck we should transmit the frame with the same WifiMode
908  * as the BlockAckReq.
909  *
910  * from section 9.6 in IEEE802.11e:
911  * The BlockAck control frame shall be sent at the same rate and modulation class as
912  * the BlockAckReq frame if it is sent in response to a BlockAckReq frame.
913  */
914  return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxMode, WIFI_PREAMBLE_LONG);
915 }
916 Time
918 {
919  WifiMode ctsMode = GetCtsTxModeForRts (to, rtsTxMode);
921 }
922 uint32_t
923 MacLow::GetCtsSize (void) const
924 {
925  WifiMacHeader cts;
927  return cts.GetSize () + 4;
928 }
929 uint32_t
931 {
932  WifiMacTrailer fcs;
933  return packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
934 }
935 
936 WifiMode
938 {
939  Mac48Address to = hdr->GetAddr1 ();
940  return m_stationManager->GetRtsMode (to, hdr, packet);
941 }
942 WifiMode
944 {
945  Mac48Address to = hdr->GetAddr1 ();
946  WifiMacTrailer fcs;
947  uint32_t size = packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
948  return m_stationManager->GetDataMode (to, hdr, packet, size);
949 }
950 
951 WifiMode
953 {
954  return m_stationManager->GetCtsMode (to, rtsTxMode);
955 }
956 WifiMode
958 {
959  return m_stationManager->GetAckMode (to, dataTxMode);
960 }
961 
962 
963 Time
965  const WifiMacHeader* hdr,
966  const MacLowTransmissionParameters& params) const
967 {
968  Time txTime = Seconds (0);
969  WifiMode rtsMode = GetRtsTxMode (packet, hdr);
970  WifiMode dataMode = GetDataTxMode (packet, hdr);
971  if (params.MustSendRts ())
972  {
973  txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsMode, WIFI_PREAMBLE_LONG);
974  txTime += GetCtsDuration (hdr->GetAddr1 (), rtsMode);
975  txTime += Time (GetSifs () * 2);
976  }
977  uint32_t dataSize = GetSize (packet, hdr);
978  txTime += m_phy->CalculateTxDuration (dataSize, dataMode, WIFI_PREAMBLE_LONG);
979  if (params.MustWaitAck ())
980  {
981  txTime += GetSifs ();
982  txTime += GetAckDuration (hdr->GetAddr1 (), dataMode);
983  }
984  return txTime;
985 }
986 
987 Time
989  const WifiMacHeader* hdr,
990  const MacLowTransmissionParameters& params) const
991 {
992  Time txTime = CalculateOverallTxTime (packet, hdr, params);
993  if (params.HasNextPacket ())
994  {
995  WifiMode dataMode = GetDataTxMode (packet, hdr);
996  txTime += GetSifs ();
997  txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataMode, WIFI_PREAMBLE_LONG);
998  }
999  return txTime;
1000 }
1001 
1002 void
1004 {
1006  Time duration = hdr.GetDuration ();
1007 
1008  if (hdr.IsCfpoll ()
1009  && hdr.GetAddr2 () == m_bssid)
1010  {
1011  // see section 9.3.2.2 802.11-1999
1012  DoNavResetNow (duration);
1013  return;
1014  }
1015  // XXX Note that we should also handle CF_END specially here
1016  // but we don't for now because we do not generate them.
1017  else if (hdr.GetAddr1 () != m_self)
1018  {
1019  // see section 9.2.5.4 802.11-1999
1020  bool navUpdated = DoNavStartNow (duration);
1021  if (hdr.IsRts () && navUpdated)
1022  {
1031  WifiMacHeader cts;
1032  cts.SetType (WIFI_MAC_CTL_CTS);
1033  Time navCounterResetCtsMissedDelay =
1034  m_phy->CalculateTxDuration (cts.GetSerializedSize (), txMode, preamble) +
1035  Time (2 * GetSifs ()) + Time (2 * GetSlotTime ());
1036  m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay,
1038  Simulator::Now ());
1039  }
1040  }
1041 }
1042 
1043 void
1045 {
1046  if (m_phy->GetLastRxStartTime () > rtsEndRxTime)
1047  {
1048  DoNavResetNow (Seconds (0.0));
1049  }
1050 }
1051 
1052 void
1054 {
1055  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1056  {
1057  (*i)->NavReset (duration);
1058  }
1060  m_lastNavStart = duration;
1061 }
1062 bool
1064 {
1065  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1066  {
1067  (*i)->NavStart (duration);
1068  }
1069  Time newNavEnd = Simulator::Now () + duration;
1070  Time oldNavEnd = m_lastNavStart + m_lastNavDuration;
1071  if (newNavEnd > oldNavEnd)
1072  {
1074  m_lastNavDuration = duration;
1075  return true;
1076  }
1077  return false;
1078 }
1079 void
1081 {
1082  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1083  {
1084  (*i)->AckTimeoutStart (duration);
1085  }
1086 }
1087 void
1089 {
1090  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1091  {
1092  (*i)->AckTimeoutReset ();
1093  }
1094 }
1095 void
1097 {
1098  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1099  {
1100  (*i)->CtsTimeoutStart (duration);
1101  }
1102 }
1103 void
1105 {
1106  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1107  {
1108  (*i)->CtsTimeoutReset ();
1109  }
1110 }
1111 
1112 void
1114  WifiMode txMode)
1115 {
1116  NS_LOG_FUNCTION (this << packet << hdr << txMode);
1117  NS_LOG_DEBUG ("send " << hdr->GetTypeString () <<
1118  ", to=" << hdr->GetAddr1 () <<
1119  ", size=" << packet->GetSize () <<
1120  ", mode=" << txMode <<
1121  ", duration=" << hdr->GetDuration () <<
1122  ", seq=0x" << std::hex << m_currentHdr.GetSequenceControl () << std::dec);
1123  m_phy->SendPacket (packet, txMode, WIFI_PREAMBLE_LONG, 0);
1124 }
1125 
1126 void
1128 {
1129  NS_LOG_FUNCTION (this);
1130  NS_LOG_DEBUG ("cts timeout");
1131  // XXX: should check that there was no rx start before now.
1132  // we should restart a new cts timeout now until the expected
1133  // end of rx if there was a rx start before now.
1135  m_currentPacket = 0;
1137  m_listener = 0;
1138  listener->MissedCts ();
1139 }
1140 void
1142 {
1143  NS_LOG_FUNCTION (this);
1144  NS_LOG_DEBUG ("normal ack timeout");
1145  // XXX: should check that there was no rx start before now.
1146  // we should restart a new ack timeout now until the expected
1147  // end of rx if there was a rx start before now.
1150  m_listener = 0;
1151  listener->MissedAck ();
1152 }
1153 void
1155 {
1156  NS_LOG_FUNCTION (this);
1159  m_listener = 0;
1160  if (m_phy->IsStateIdle ())
1161  {
1162  NS_LOG_DEBUG ("fast Ack idle missed");
1163  listener->MissedAck ();
1164  }
1165  else
1166  {
1167  NS_LOG_DEBUG ("fast Ack ok");
1168  }
1169 }
1170 void
1172 {
1173  NS_LOG_FUNCTION (this);
1174  NS_LOG_DEBUG ("block ack timeout");
1175 
1178  m_listener = 0;
1179  listener->MissedBlockAck ();
1180 }
1181 void
1183 {
1184  NS_LOG_FUNCTION (this);
1187  m_listener = 0;
1188  if (m_phy->IsStateIdle ())
1189  {
1190  NS_LOG_DEBUG ("super fast Ack failed");
1191  listener->MissedAck ();
1192  }
1193  else
1194  {
1195  NS_LOG_DEBUG ("super fast Ack ok");
1196  listener->GotAck (0.0, WifiMode ());
1197  }
1198 }
1199 
1200 void
1202 {
1203  NS_LOG_FUNCTION (this);
1204  /* send an RTS for this packet. */
1205  WifiMacHeader rts;
1206  rts.SetType (WIFI_MAC_CTL_RTS);
1207  rts.SetDsNotFrom ();
1208  rts.SetDsNotTo ();
1209  rts.SetNoRetry ();
1210  rts.SetNoMoreFragments ();
1211  rts.SetAddr1 (m_currentHdr.GetAddr1 ());
1212  rts.SetAddr2 (m_self);
1214  Time duration = Seconds (0);
1215  if (m_txParams.HasDurationId ())
1216  {
1217  duration += m_txParams.GetDurationId ();
1218  }
1219  else
1220  {
1222  duration += GetSifs ();
1223  duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxMode);
1224  duration += GetSifs ();
1226  dataTxMode, WIFI_PREAMBLE_LONG);
1227  duration += GetSifs ();
1228  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
1229  }
1230  rts.SetDuration (duration);
1231 
1232  Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxMode, WIFI_PREAMBLE_LONG);
1233  Time timerDelay = txDuration + GetCtsTimeout ();
1234 
1236  NotifyCtsTimeoutStartNow (timerDelay);
1238 
1239  Ptr<Packet> packet = Create<Packet> ();
1240  packet->AddHeader (rts);
1241  WifiMacTrailer fcs;
1242  packet->AddTrailer (fcs);
1243 
1244  ForwardDown (packet, &rts, rtsTxMode);
1245 }
1246 
1247 void
1249 {
1253  {
1254  Time timerDelay = txDuration + GetAckTimeout ();
1256  NotifyAckTimeoutStartNow (timerDelay);
1258  }
1259  else if (m_txParams.MustWaitFastAck ())
1260  {
1261  Time timerDelay = txDuration + GetPifs ();
1263  NotifyAckTimeoutStartNow (timerDelay);
1265  }
1266  else if (m_txParams.MustWaitSuperFastAck ())
1267  {
1268  Time timerDelay = txDuration + GetPifs ();
1270  NotifyAckTimeoutStartNow (timerDelay);
1273  }
1274  else if (m_txParams.MustWaitBasicBlockAck ())
1275  {
1276  Time timerDelay = txDuration + GetBasicBlockAckTimeout ();
1279  }
1281  {
1282  Time timerDelay = txDuration + GetCompressedBlockAckTimeout ();
1285  }
1286  else if (m_txParams.HasNextPacket ())
1287  {
1288  Time delay = txDuration + GetSifs ();
1291  }
1292  else
1293  {
1294  // since we do not expect any timer to be triggered.
1295  Simulator::Schedule(txDuration, &MacLow::EndTxNoAck, this);
1296  }
1297 }
1298 
1299 void
1301 {
1302  NS_LOG_FUNCTION (this);
1303  /* send this packet directly. No RTS is needed. */
1304  StartDataTxTimers ();
1305 
1307  Time duration = Seconds (0.0);
1308  if (m_txParams.HasDurationId ())
1309  {
1310  duration += m_txParams.GetDurationId ();
1311  }
1312  else
1313  {
1315  {
1316  duration += GetSifs ();
1317  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxMode, BASIC_BLOCK_ACK);
1318  }
1320  {
1321  duration += GetSifs ();
1322  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxMode, COMPRESSED_BLOCK_ACK);
1323  }
1324  else if (m_txParams.MustWaitAck ())
1325  {
1326  duration += GetSifs ();
1327  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
1328  }
1329  if (m_txParams.HasNextPacket ())
1330  {
1331  duration += GetSifs ();
1333  dataTxMode, WIFI_PREAMBLE_LONG);
1334  if (m_txParams.MustWaitAck ())
1335  {
1336  duration += GetSifs ();
1337  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
1338  }
1339  }
1340  }
1341  m_currentHdr.SetDuration (duration);
1342 
1344  WifiMacTrailer fcs;
1345  m_currentPacket->AddTrailer (fcs);
1346 
1347  ForwardDown (m_currentPacket, &m_currentHdr, dataTxMode);
1348  m_currentPacket = 0;
1349 }
1350 
1351 bool
1352 MacLow::IsNavZero (void) const
1353 {
1355  {
1356  return true;
1357  }
1358  else
1359  {
1360  return false;
1361  }
1362 }
1363 
1364 void
1365 MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode rtsTxMode, double rtsSnr)
1366 {
1367  NS_LOG_FUNCTION (this << source << duration << rtsTxMode << rtsSnr);
1368  /* send a CTS when you receive a RTS
1369  * right after SIFS.
1370  */
1371  WifiMode ctsTxMode = GetCtsTxModeForRts (source, rtsTxMode);
1372  WifiMacHeader cts;
1373  cts.SetType (WIFI_MAC_CTL_CTS);
1374  cts.SetDsNotFrom ();
1375  cts.SetDsNotTo ();
1376  cts.SetNoMoreFragments ();
1377  cts.SetNoRetry ();
1378  cts.SetAddr1 (source);
1379  duration -= GetCtsDuration (source, rtsTxMode);
1380  duration -= GetSifs ();
1381  NS_ASSERT (duration >= MicroSeconds (0));
1382  cts.SetDuration (duration);
1383 
1384  Ptr<Packet> packet = Create<Packet> ();
1385  packet->AddHeader (cts);
1386  WifiMacTrailer fcs;
1387  packet->AddTrailer (fcs);
1388 
1389  SnrTag tag;
1390  tag.Set (rtsSnr);
1391  packet->AddPacketTag (tag);
1392 
1393  ForwardDown (packet, &cts, ctsTxMode);
1394 }
1395 
1396 void
1398 {
1399  NS_LOG_FUNCTION (this);
1400  /* send the third step in a
1401  * RTS/CTS/DATA/ACK hanshake
1402  */
1403  NS_ASSERT (m_currentPacket != 0);
1404  StartDataTxTimers ();
1405 
1407  Time newDuration = Seconds (0);
1408  newDuration += GetSifs ();
1409  newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
1411  dataTxMode, WIFI_PREAMBLE_LONG);
1412  duration -= txDuration;
1413  duration -= GetSifs ();
1414 
1415  duration = std::max (duration, newDuration);
1416  NS_ASSERT (duration >= MicroSeconds (0));
1417  m_currentHdr.SetDuration (duration);
1418 
1420  WifiMacTrailer fcs;
1421  m_currentPacket->AddTrailer (fcs);
1422 
1423  ForwardDown (m_currentPacket, &m_currentHdr, dataTxMode);
1424  m_currentPacket = 0;
1425 }
1426 
1427 void
1429 {
1430  m_listener->StartNext ();
1431 }
1432 
1433 void
1435 {
1437  m_listener = 0;
1438  listener->EndTxNoAck ();
1439 }
1440 
1441 void
1443 {
1444  NS_LOG_FUNCTION (this);
1446  m_listener = 0;
1447  listener->MissedAck ();
1448  NS_LOG_DEBUG ("fast Ack busy but missed");
1449 }
1450 
1451 void
1452 MacLow::SendAckAfterData (Mac48Address source, Time duration, WifiMode dataTxMode, double dataSnr)
1453 {
1454  NS_LOG_FUNCTION (this);
1455  /* send an ACK when you receive
1456  * a packet after SIFS.
1457  */
1458  WifiMode ackTxMode = GetAckTxModeForData (source, dataTxMode);
1459  WifiMacHeader ack;
1460  ack.SetType (WIFI_MAC_CTL_ACK);
1461  ack.SetDsNotFrom ();
1462  ack.SetDsNotTo ();
1463  ack.SetNoRetry ();
1464  ack.SetNoMoreFragments ();
1465  ack.SetAddr1 (source);
1466  duration -= GetAckDuration (source, dataTxMode);
1467  duration -= GetSifs ();
1468  NS_ASSERT (duration >= MicroSeconds (0));
1469  ack.SetDuration (duration);
1470 
1471  Ptr<Packet> packet = Create<Packet> ();
1472  packet->AddHeader (ack);
1473  WifiMacTrailer fcs;
1474  packet->AddTrailer (fcs);
1475 
1476  SnrTag tag;
1477  tag.Set (dataSnr);
1478  packet->AddPacketTag (tag);
1479 
1480  ForwardDown (packet, &ack, ackTxMode);
1481 }
1482 
1483 bool
1485 {
1486  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1487  if (it != m_bAckAgreements.end ())
1488  {
1489  WifiMacTrailer fcs;
1490  packet->RemoveTrailer (fcs);
1491  BufferedPacket bufferedPacket (packet, hdr);
1492 
1493  uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
1494  uint16_t mappedSeqControl = QosUtilsMapSeqControlToUniqueInteger (hdr.GetSequenceControl (), endSequence);
1495 
1496  BufferedPacketI i = (*it).second.second.begin ();
1497  for (; i != (*it).second.second.end ()
1498  && QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceControl (), endSequence) < mappedSeqControl; i++)
1499  {
1500  ;
1501  }
1502  (*it).second.second.insert (i, bufferedPacket);
1503 
1504  //Update block ack cache
1505  BlockAckCachesI j = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1506  NS_ASSERT (j != m_bAckCaches.end ());
1507  (*j).second.UpdateWithMpdu (&hdr);
1508 
1509  return true;
1510  }
1511  return false;
1512 }
1513 
1514 void
1516  uint16_t startingSeq)
1517 {
1518  uint8_t tid = respHdr->GetTid ();
1519  BlockAckAgreement agreement (originator, tid);
1520  if (respHdr->IsImmediateBlockAck ())
1521  {
1522  agreement.SetImmediateBlockAck ();
1523  }
1524  else
1525  {
1526  agreement.SetDelayedBlockAck ();
1527  }
1528  agreement.SetAmsduSupport (respHdr->IsAmsduSupported ());
1529  agreement.SetBufferSize (respHdr->GetBufferSize () + 1);
1530  agreement.SetTimeout (respHdr->GetTimeout ());
1531  agreement.SetStartingSequence (startingSeq);
1532 
1533  std::list<BufferedPacket> buffer (0);
1534  AgreementKey key (originator, respHdr->GetTid ());
1535  AgreementValue value (agreement, buffer);
1536  m_bAckAgreements.insert (std::make_pair (key, value));
1537 
1538  BlockAckCache cache;
1539  cache.Init (startingSeq, respHdr->GetBufferSize () + 1);
1540  m_bAckCaches.insert (std::make_pair (key, cache));
1541 
1542  if (respHdr->GetTimeout () != 0)
1543  {
1544  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, respHdr->GetTid ()));
1545  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
1546 
1547  AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
1548 
1549  it->second.first.m_inactivityEvent = Simulator::Schedule (timeout,
1551  m_edcaListeners[ac],
1552  originator, tid);
1553  }
1554 }
1555 
1556 void
1558 {
1559  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1560  if (it != m_bAckAgreements.end ())
1561  {
1562  RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (), originator, tid);
1563  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
1564  m_bAckAgreements.erase (it);
1565 
1566  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
1567  NS_ASSERT (i != m_bAckCaches.end ());
1568  m_bAckCaches.erase (i);
1569  }
1570 }
1571 
1572 void
1574 {
1575  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1576  if (it != m_bAckAgreements.end ())
1577  {
1578  uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
1579  uint16_t mappedStart = QosUtilsMapSeqControlToUniqueInteger (seq, endSequence);
1580  uint16_t guard = (*it).second.second.begin ()->second.GetSequenceControl () & 0xfff0;
1581  BufferedPacketI last = (*it).second.second.begin ();
1582 
1583  BufferedPacketI i = (*it).second.second.begin ();
1584  for (; i != (*it).second.second.end ()
1585  && QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceNumber (), endSequence) < mappedStart;)
1586  {
1587  if (guard == (*i).second.GetSequenceControl ())
1588  {
1589  if (!(*i).second.IsMoreFragments ())
1590  {
1591  while (last != i)
1592  {
1593  m_rxCallback ((*last).first, &(*last).second);
1594  last++;
1595  }
1596  m_rxCallback ((*last).first, &(*last).second);
1597  last++;
1598  /* go to next packet */
1599  while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
1600  {
1601  i++;
1602  }
1603  if (i != (*it).second.second.end ())
1604  {
1605  guard = (*i).second.GetSequenceControl () & 0xfff0;
1606  last = i;
1607  }
1608  }
1609  else
1610  {
1611  guard++;
1612  }
1613  }
1614  else
1615  {
1616  /* go to next packet */
1617  while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
1618  {
1619  i++;
1620  }
1621  if (i != (*it).second.second.end ())
1622  {
1623  guard = (*i).second.GetSequenceControl () & 0xfff0;
1624  last = i;
1625  }
1626  }
1627  }
1628  (*it).second.second.erase ((*it).second.second.begin (), i);
1629  }
1630 }
1631 
1632 void
1634 {
1635  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1636  if (it != m_bAckAgreements.end ())
1637  {
1638  uint16_t startingSeqCtrl = ((*it).second.first.GetStartingSequence () << 4) & 0xfff0;
1639  uint16_t guard = startingSeqCtrl;
1640 
1641  BufferedPacketI lastComplete = (*it).second.second.begin ();
1642  BufferedPacketI i = (*it).second.second.begin ();
1643  for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
1644  {
1645  if (!(*i).second.IsMoreFragments ())
1646  {
1647  while (lastComplete != i)
1648  {
1649  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
1650  lastComplete++;
1651  }
1652  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
1653  lastComplete++;
1654  }
1655  guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
1656  }
1657  (*it).second.first.SetStartingSequence ((guard >> 4) & 0x0fff);
1658  /* All packets already forwarded to WifiMac must be removed from buffer:
1659  [begin (), lastComplete) */
1660  (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
1661  }
1662 }
1663 
1664 void
1665 MacLow::SendBlockAckResponse (const CtrlBAckResponseHeader* blockAck, Mac48Address originator, bool immediate,
1666  Time duration, WifiMode blockAckReqTxMode)
1667 {
1668  Ptr<Packet> packet = Create<Packet> ();
1669  packet->AddHeader (*blockAck);
1670 
1671  WifiMacHeader hdr;
1673  hdr.SetAddr1 (originator);
1674  hdr.SetAddr2 (GetAddress ());
1675  hdr.SetDsNotFrom ();
1676  hdr.SetDsNotTo ();
1677  hdr.SetNoRetry ();
1678  hdr.SetNoMoreFragments ();
1679 
1680  m_currentPacket = packet;
1681  m_currentHdr = hdr;
1682  if (immediate)
1683  {
1685  duration -= GetSifs ();
1686  if (blockAck->IsBasic ())
1687  {
1688  duration -= GetBlockAckDuration (originator, blockAckReqTxMode, BASIC_BLOCK_ACK);
1689  }
1690  else if (blockAck->IsCompressed ())
1691  {
1692  duration -= GetBlockAckDuration (originator, blockAckReqTxMode, COMPRESSED_BLOCK_ACK);
1693  }
1694  else if (blockAck->IsMultiTid ())
1695  {
1696  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
1697  }
1698  }
1699  else
1700  {
1701  m_txParams.EnableAck ();
1702  duration += GetSifs ();
1703  duration += GetAckDuration (originator, blockAckReqTxMode);
1704  }
1706 
1707  if (!immediate)
1708  {
1709  StartDataTxTimers ();
1710  }
1711 
1712  NS_ASSERT (duration >= MicroSeconds (0));
1713  hdr.SetDuration (duration);
1714  //here should be present a control about immediate or delayed block ack
1715  //for now we assume immediate
1716  packet->AddHeader (hdr);
1717  WifiMacTrailer fcs;
1718  packet->AddTrailer (fcs);
1719  ForwardDown (packet, &hdr, blockAckReqTxMode);
1720  m_currentPacket = 0;
1721 }
1722 
1723 void
1725  Time duration, WifiMode blockAckReqTxMode)
1726 {
1727  NS_LOG_FUNCTION (this);
1728  CtrlBAckResponseHeader blockAck;
1729  uint8_t tid;
1730  bool immediate = false;
1731  if (!reqHdr.IsMultiTid ())
1732  {
1733  tid = reqHdr.GetTidInfo ();
1734  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1735  if (it != m_bAckAgreements.end ())
1736  {
1737  blockAck.SetStartingSequence (reqHdr.GetStartingSequence ());
1738  blockAck.SetTidInfo (tid);
1739  immediate = (*it).second.first.IsImmediateBlockAck ();
1740  if (reqHdr.IsBasic ())
1741  {
1742  blockAck.SetType (BASIC_BLOCK_ACK);
1743  }
1744  else if (reqHdr.IsCompressed ())
1745  {
1746  blockAck.SetType (COMPRESSED_BLOCK_ACK);
1747  }
1748  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
1749  NS_ASSERT (i != m_bAckCaches.end ());
1750  (*i).second.FillBlockAckBitmap (&blockAck);
1751 
1752  /* All packets with smaller sequence than starting sequence control must be passed up to Wifimac
1753  * See 9.10.3 in IEEE8022.11e standard.
1754  */
1756  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
1757  }
1758  else
1759  {
1760  NS_LOG_DEBUG ("there's not a valid block ack agreement with " << originator);
1761  }
1762  }
1763  else
1764  {
1765  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
1766  }
1767 
1768  SendBlockAckResponse (&blockAck, originator, immediate, duration, blockAckReqTxMode);
1769 }
1770 
1771 void
1773 {
1774  if (agreement.GetTimeout () != 0)
1775  {
1776  NS_ASSERT (agreement.m_inactivityEvent.IsRunning ());
1777  agreement.m_inactivityEvent.Cancel ();
1778  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
1779 
1780  AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
1781  //std::map<AcIndex, MacLowTransmissionListener*>::iterator it = m_edcaListeners.find (ac);
1782  //NS_ASSERT (it != m_edcaListeners.end ());
1783 
1784  agreement.m_inactivityEvent = Simulator::Schedule (timeout,
1786  m_edcaListeners[ac],
1787  agreement.GetPeer (),
1788  agreement.GetTid ());
1789  }
1790 }
1791 
1792 void
1794 {
1795  m_edcaListeners.insert (std::make_pair (ac, listener));
1796 }
1797 
1798 } // namespace ns3