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