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_endTxNoAckEvent (),
364  m_currentPacket (0),
365  m_listener (0)
366 {
367  NS_LOG_FUNCTION (this);
369  m_lastNavStart = Seconds (0);
370  m_promisc = false;
371 }
372 
374 {
375  NS_LOG_FUNCTION (this);
376 }
377 
378 void
380 {
383 }
384 
385 
386 void
388 {
389  NS_LOG_FUNCTION (this);
401  m_phy = 0;
402  m_stationManager = 0;
403  delete m_phyMacLowListener;
405 }
406 
407 void
409 {
410  NS_LOG_FUNCTION (this);
411  bool oneRunning = false;
413  {
415  oneRunning = true;
416  }
418  {
420  oneRunning = true;
421  }
423  {
425  oneRunning = true;
426  }
428  {
430  oneRunning = true;
431  }
433  {
435  oneRunning = true;
436  }
438  {
440  oneRunning = true;
441  }
442  if (m_sendCtsEvent.IsRunning ())
443  {
445  oneRunning = true;
446  }
447  if (m_sendAckEvent.IsRunning ())
448  {
450  oneRunning = true;
451  }
452  if (m_sendDataEvent.IsRunning ())
453  {
455  oneRunning = true;
456  }
457  if (m_waitSifsEvent.IsRunning ())
458  {
460  oneRunning = true;
461  }
463  {
465  oneRunning = true;
466  }
467  if (oneRunning && m_listener != 0)
468  {
469  m_listener->Cancel ();
470  m_listener = 0;
471  }
472 }
473 
474 void
476 {
477  m_phy = phy;
481 }
482 void
484 {
485  m_stationManager = manager;
486 }
487 
488 void
490 {
491  m_self = ad;
492 }
493 void
495 {
496  m_ackTimeout = ackTimeout;
497 }
498 void
500 {
501  m_basicBlockAckTimeout = blockAckTimeout;
502 }
503 void
505 {
506  m_compressedBlockAckTimeout = blockAckTimeout;
507 }
508 void
510 {
511  m_ctsTimeout = ctsTimeout;
512 }
513 void
515 {
516  m_sifs = sifs;
517 }
518 void
520 {
521  m_slotTime = slotTime;
522 }
523 void
525 {
526  m_pifs = pifs;
527 }
528 void
530 {
531  m_bssid = bssid;
532 }
533 void
535 {
536  m_promisc = true;
537 }
539 MacLow::GetAddress (void) const
540 {
541  return m_self;
542 }
543 Time
545 {
546  return m_ackTimeout;
547 }
548 Time
550 {
551  return m_basicBlockAckTimeout;
552 }
553 Time
555 {
557 }
558 Time
560 {
561  return m_ctsTimeout;
562 }
563 Time
564 MacLow::GetSifs (void) const
565 {
566  return m_sifs;
567 }
568 Time
570 {
571  return m_slotTime;
572 }
573 Time
574 MacLow::GetPifs (void) const
575 {
576  return m_pifs;
577 }
579 MacLow::GetBssid (void) const
580 {
581  return m_bssid;
582 }
583 
584 void
586 {
587  m_rxCallback = callback;
588 }
589 void
591 {
592  m_dcfListeners.push_back (listener);
593 }
594 
595 
596 void
598  const WifiMacHeader* hdr,
600  MacLowTransmissionListener *listener)
601 {
602  NS_LOG_FUNCTION (this << packet << hdr << params << listener);
603  /* m_currentPacket is not NULL because someone started
604  * a transmission and was interrupted before one of:
605  * - ctsTimeout
606  * - sendDataAfterCTS
607  * expired. This means that one of these timers is still
608  * running. They are all cancelled below anyway by the
609  * call to CancelAllEvents (because of at least one
610  * of these two timer) which will trigger a call to the
611  * previous listener's cancel method.
612  *
613  * This typically happens because the high-priority
614  * QapScheduler has taken access to the channel from
615  * one of the Edca of the QAP.
616  */
617  m_currentPacket = packet->Copy ();
618  m_currentHdr = *hdr;
619  CancelAllEvents ();
620  m_listener = listener;
621  m_txParams = params;
622 
623  //NS_ASSERT (m_phy->IsStateIdle ());
624 
625  NS_LOG_DEBUG ("startTx size=" << GetSize (m_currentPacket, &m_currentHdr) <<
626  ", to=" << m_currentHdr.GetAddr1 () << ", listener=" << m_listener);
627 
628  if (m_txParams.MustSendRts ())
629  {
630  SendRtsForPacket ();
631  }
632  else
633  {
634  SendDataPacket ();
635  }
636 
637  /* When this method completes, we have taken ownership of the medium. */
638  NS_ASSERT (m_phy->IsStateTx ());
639 }
640 
641 void
643 {
644  NS_LOG_FUNCTION (this << packet << rxSnr);
645  NS_LOG_DEBUG ("rx failed ");
647  {
651  }
652  return;
653 }
654 
655 void
657 {
658  NS_LOG_DEBUG ("switching channel. Cancelling MAC pending events");
660  CancelAllEvents ();
662  {
664  }
667  m_currentPacket = 0;
668  m_listener = 0;
669 }
670 
671 void
672 MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamble preamble)
673 {
674  NS_LOG_FUNCTION (this << packet << rxSnr << txMode << preamble);
675  /* A packet is received from the PHY.
676  * When we have handled this packet,
677  * we handle any packet present in the
678  * packet queue.
679  */
680  WifiMacHeader hdr;
681  packet->RemoveHeader (hdr);
682 
683  bool isPrevNavZero = IsNavZero ();
684  NS_LOG_DEBUG ("duration/id=" << hdr.GetDuration ());
685  NotifyNav (hdr, txMode, preamble);
686  if (hdr.IsRts ())
687  {
688  /* see section 9.2.5.7 802.11-1999
689  * A STA that is addressed by an RTS frame shall transmit a CTS frame after a SIFS
690  * period if the NAV at the STA receiving the RTS frame indicates that the medium is
691  * idle. If the NAV at the STA receiving the RTS indicates the medium is not idle,
692  * that STA shall not respond to the RTS frame.
693  */
694  if (isPrevNavZero
695  && hdr.GetAddr1 () == m_self)
696  {
697  NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
699  m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
700  rxSnr, txMode);
703  hdr.GetAddr2 (),
704  hdr.GetDuration (),
705  txMode,
706  rxSnr);
707  }
708  else
709  {
710  NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
711  }
712  }
713  else if (hdr.IsCts ()
714  && hdr.GetAddr1 () == m_self
716  && m_currentPacket != 0)
717  {
718  NS_LOG_DEBUG ("receive cts from=" << m_currentHdr.GetAddr1 ());
719  SnrTag tag;
720  packet->RemovePacketTag (tag);
722  rxSnr, txMode);
724  rxSnr, txMode, tag.Get ());
725 
728  m_listener->GotCts (rxSnr, txMode);
732  hdr.GetAddr1 (),
733  hdr.GetDuration (),
734  txMode);
735  }
736  else if (hdr.IsAck ()
737  && hdr.GetAddr1 () == m_self
741  && m_txParams.MustWaitAck ())
742  {
743  NS_LOG_DEBUG ("receive ack from=" << m_currentHdr.GetAddr1 ());
744  SnrTag tag;
745  packet->RemovePacketTag (tag);
747  rxSnr, txMode);
749  rxSnr, txMode, tag.Get ());
750  bool gotAck = false;
753  {
756  gotAck = true;
757  }
760  {
763  gotAck = true;
764  }
765  if (gotAck)
766  {
767  m_listener->GotAck (rxSnr, txMode);
768  }
769  if (m_txParams.HasNextPacket ())
770  {
773  }
774  }
775  else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self
778  {
779  NS_LOG_DEBUG ("got block ack from " << hdr.GetAddr2 ());
780  CtrlBAckResponseHeader blockAck;
781  packet->RemoveHeader (blockAck);
783  m_listener->GotBlockAck (&blockAck, hdr.GetAddr2 ());
784  }
785  else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
786  {
787  CtrlBAckRequestHeader blockAckReq;
788  packet->RemoveHeader (blockAckReq);
789  if (!blockAckReq.IsMultiTid ())
790  {
791  uint8_t tid = blockAckReq.GetTidInfo ();
792  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), tid));
793  if (it != m_bAckAgreements.end ())
794  {
795  //Update block ack cache
796  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), tid));
797  NS_ASSERT (i != m_bAckCaches.end ());
798  (*i).second.UpdateWithBlockAckReq (blockAckReq.GetStartingSequence ());
799 
801  /* See section 11.5.3 in IEEE802.11 for mean of this timer */
802  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
803  if ((*it).second.first.IsImmediateBlockAck ())
804  {
805  NS_LOG_DEBUG ("rx blockAckRequest/sendImmediateBlockAck from=" << hdr.GetAddr2 ());
808  blockAckReq,
809  hdr.GetAddr2 (),
810  hdr.GetDuration (),
811  txMode);
812  }
813  else
814  {
815  NS_FATAL_ERROR ("Delayed block ack not supported.");
816  }
817  }
818  else
819  {
820  NS_LOG_DEBUG ("There's not a valid agreement for this block ack request.");
821  }
822  }
823  else
824  {
825  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
826  }
827  }
828  else if (hdr.IsCtl ())
829  {
830  NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ());
831  }
832  else if (hdr.GetAddr1 () == m_self)
833  {
834  m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
835  rxSnr, txMode);
836 
837  if (hdr.IsQosData () && StoreMpduIfNeeded (packet, hdr))
838  {
839  /* From section 9.10.4 in IEEE802.11:
840  Upon the receipt of a QoS data frame from the originator for which
841  the Block Ack agreement exists, the recipient shall buffer the MSDU
842  regardless of the value of the Ack Policy subfield within the
843  QoS Control field of the QoS data frame. */
844  if (hdr.IsQosAck ())
845  {
846  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
847  RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (),
848  hdr.GetAddr2 (), hdr.GetQosTid ());
853  hdr.GetAddr2 (),
854  hdr.GetDuration (),
855  txMode,
856  rxSnr);
857  }
858  else if (hdr.IsQosBlockAck ())
859  {
860  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
861  /* See section 11.5.3 in IEEE802.11 for mean of this timer */
862  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
863  }
864  return;
865  }
866  else if (hdr.IsQosData () && hdr.IsQosBlockAck ())
867  {
868  /* This happens if a packet with ack policy Block Ack is received and a block ack
869  agreement for that packet doesn't exist.
870 
871  From section 11.5.3 in IEEE802.11e:
872  When a recipient does not have an active Block ack for a TID, but receives
873  data MPDUs with the Ack Policy subfield set to Block Ack, it shall discard
874  them and shall send a DELBA frame using the normal access
875  mechanisms. */
876  AcIndex ac = QosUtilsMapTidToAc (hdr.GetQosTid ());
877  m_edcaListeners[ac]->BlockAckInactivityTimeout (hdr.GetAddr2 (), hdr.GetQosTid ());
878  return;
879  }
880  else if (hdr.IsQosData () && hdr.IsQosNoAck ())
881  {
882  NS_LOG_DEBUG ("rx unicast/noAck from=" << hdr.GetAddr2 ());
883  }
884  else if (hdr.IsData () || hdr.IsMgt ())
885  {
886  NS_LOG_DEBUG ("rx unicast/sendAck from=" << hdr.GetAddr2 ());
890  hdr.GetAddr2 (),
891  hdr.GetDuration (),
892  txMode,
893  rxSnr);
894  }
895  goto rxPacket;
896  }
897  else if (hdr.GetAddr1 ().IsGroup ())
898  {
899  if (hdr.IsData () || hdr.IsMgt ())
900  {
901  NS_LOG_DEBUG ("rx group from=" << hdr.GetAddr2 ());
902  goto rxPacket;
903  }
904  else
905  {
906  // DROP
907  }
908  }
909  else if (m_promisc)
910  {
911  NS_ASSERT (hdr.GetAddr1 () != m_self);
912  if (hdr.IsData ())
913  {
914  goto rxPacket;
915  }
916  }
917  else
918  {
919  //NS_LOG_DEBUG_VERBOSE ("rx not-for-me from %d", GetSource (packet));
920  }
921  return;
922 rxPacket:
923  WifiMacTrailer fcs;
924  packet->RemoveTrailer (fcs);
925  m_rxCallback (packet, &hdr);
926  return;
927 }
928 
929 uint32_t
930 MacLow::GetAckSize (void) const
931 {
932  WifiMacHeader ack;
934  return ack.GetSize () + 4;
935 }
936 uint32_t
938 {
939  WifiMacHeader hdr;
941  CtrlBAckResponseHeader blockAck;
942  if (type == BASIC_BLOCK_ACK)
943  {
944  blockAck.SetType (BASIC_BLOCK_ACK);
945  }
946  else if (type == COMPRESSED_BLOCK_ACK)
947  {
948  blockAck.SetType (COMPRESSED_BLOCK_ACK);
949  }
950  else if (type == MULTI_TID_BLOCK_ACK)
951  {
952  //Not implemented
953  NS_ASSERT (false);
954  }
955  return hdr.GetSize () + blockAck.GetSerializedSize () + 4;
956 }
957 uint32_t
958 MacLow::GetRtsSize (void) const
959 {
960  WifiMacHeader rts;
962  return rts.GetSize () + 4;
963 }
964 Time
966 {
967  WifiMode ackMode = GetAckTxModeForData (to, dataTxMode);
969 }
970 Time
971 MacLow::GetBlockAckDuration (Mac48Address to, WifiMode blockAckReqTxMode, enum BlockAckType type) const
972 {
973  /*
974  * For immediate BlockAck we should transmit the frame with the same WifiMode
975  * as the BlockAckReq.
976  *
977  * from section 9.6 in IEEE802.11e:
978  * The BlockAck control frame shall be sent at the same rate and modulation class as
979  * the BlockAckReq frame if it is sent in response to a BlockAckReq frame.
980  */
981  return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxMode, WIFI_PREAMBLE_LONG);
982 }
983 Time
985 {
986  WifiMode ctsMode = GetCtsTxModeForRts (to, rtsTxMode);
988 }
989 uint32_t
990 MacLow::GetCtsSize (void) const
991 {
992  WifiMacHeader cts;
994  return cts.GetSize () + 4;
995 }
996 uint32_t
998 {
999  WifiMacTrailer fcs;
1000  return packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
1001 }
1002 
1003 WifiMode
1005 {
1006  Mac48Address to = hdr->GetAddr1 ();
1007  return m_stationManager->GetRtsMode (to, hdr, packet);
1008 }
1009 WifiMode
1011 {
1012  Mac48Address to = hdr->GetAddr1 ();
1013  WifiMacTrailer fcs;
1014  uint32_t size = packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
1015  return m_stationManager->GetDataMode (to, hdr, packet, size);
1016 }
1017 
1018 WifiMode
1020 {
1021  return m_stationManager->GetCtsMode (to, rtsTxMode);
1022 }
1023 WifiMode
1025 {
1026  return m_stationManager->GetAckMode (to, dataTxMode);
1027 }
1028 
1029 
1030 Time
1032  const WifiMacHeader* hdr,
1033  const MacLowTransmissionParameters& params) const
1034 {
1035  Time txTime = Seconds (0);
1036  WifiMode rtsMode = GetRtsTxMode (packet, hdr);
1037  WifiMode dataMode = GetDataTxMode (packet, hdr);
1038  if (params.MustSendRts ())
1039  {
1040  txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsMode, WIFI_PREAMBLE_LONG);
1041  txTime += GetCtsDuration (hdr->GetAddr1 (), rtsMode);
1042  txTime += Time (GetSifs () * 2);
1043  }
1044  uint32_t dataSize = GetSize (packet, hdr);
1045  txTime += m_phy->CalculateTxDuration (dataSize, dataMode, WIFI_PREAMBLE_LONG);
1046  if (params.MustWaitAck ())
1047  {
1048  txTime += GetSifs ();
1049  txTime += GetAckDuration (hdr->GetAddr1 (), dataMode);
1050  }
1051  return txTime;
1052 }
1053 
1054 Time
1056  const WifiMacHeader* hdr,
1057  const MacLowTransmissionParameters& params) const
1058 {
1059  Time txTime = CalculateOverallTxTime (packet, hdr, params);
1060  if (params.HasNextPacket ())
1061  {
1062  WifiMode dataMode = GetDataTxMode (packet, hdr);
1063  txTime += GetSifs ();
1064  txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataMode, WIFI_PREAMBLE_LONG);
1065  }
1066  return txTime;
1067 }
1068 
1069 void
1071 {
1073  Time duration = hdr.GetDuration ();
1074 
1075  if (hdr.IsCfpoll ()
1076  && hdr.GetAddr2 () == m_bssid)
1077  {
1078  // see section 9.3.2.2 802.11-1999
1079  DoNavResetNow (duration);
1080  return;
1081  }
1082  // XXX Note that we should also handle CF_END specially here
1083  // but we don't for now because we do not generate them.
1084  else if (hdr.GetAddr1 () != m_self)
1085  {
1086  // see section 9.2.5.4 802.11-1999
1087  bool navUpdated = DoNavStartNow (duration);
1088  if (hdr.IsRts () && navUpdated)
1089  {
1098  WifiMacHeader cts;
1099  cts.SetType (WIFI_MAC_CTL_CTS);
1100  Time navCounterResetCtsMissedDelay =
1101  m_phy->CalculateTxDuration (cts.GetSerializedSize (), txMode, preamble) +
1102  Time (2 * GetSifs ()) + Time (2 * GetSlotTime ());
1103  m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay,
1105  Simulator::Now ());
1106  }
1107  }
1108 }
1109 
1110 void
1112 {
1113  if (m_phy->GetLastRxStartTime () > rtsEndRxTime)
1114  {
1115  DoNavResetNow (Seconds (0.0));
1116  }
1117 }
1118 
1119 void
1121 {
1122  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1123  {
1124  (*i)->NavReset (duration);
1125  }
1127  m_lastNavStart = duration;
1128 }
1129 bool
1131 {
1132  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1133  {
1134  (*i)->NavStart (duration);
1135  }
1136  Time newNavEnd = Simulator::Now () + duration;
1137  Time oldNavEnd = m_lastNavStart + m_lastNavDuration;
1138  if (newNavEnd > oldNavEnd)
1139  {
1141  m_lastNavDuration = duration;
1142  return true;
1143  }
1144  return false;
1145 }
1146 void
1148 {
1149  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1150  {
1151  (*i)->AckTimeoutStart (duration);
1152  }
1153 }
1154 void
1156 {
1157  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1158  {
1159  (*i)->AckTimeoutReset ();
1160  }
1161 }
1162 void
1164 {
1165  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1166  {
1167  (*i)->CtsTimeoutStart (duration);
1168  }
1169 }
1170 void
1172 {
1173  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1174  {
1175  (*i)->CtsTimeoutReset ();
1176  }
1177 }
1178 
1179 void
1181  WifiMode txMode)
1182 {
1183  NS_LOG_FUNCTION (this << packet << hdr << txMode);
1184  NS_LOG_DEBUG ("send " << hdr->GetTypeString () <<
1185  ", to=" << hdr->GetAddr1 () <<
1186  ", size=" << packet->GetSize () <<
1187  ", mode=" << txMode <<
1188  ", duration=" << hdr->GetDuration () <<
1189  ", seq=0x" << std::hex << m_currentHdr.GetSequenceControl () << std::dec);
1190  m_phy->SendPacket (packet, txMode, WIFI_PREAMBLE_LONG, 0);
1191 }
1192 
1193 void
1195 {
1196  NS_LOG_FUNCTION (this);
1197  NS_LOG_DEBUG ("cts timeout");
1198  // XXX: should check that there was no rx start before now.
1199  // we should restart a new cts timeout now until the expected
1200  // end of rx if there was a rx start before now.
1202  m_currentPacket = 0;
1204  m_listener = 0;
1205  listener->MissedCts ();
1206 }
1207 void
1209 {
1210  NS_LOG_FUNCTION (this);
1211  NS_LOG_DEBUG ("normal ack timeout");
1212  // XXX: should check that there was no rx start before now.
1213  // we should restart a new ack timeout now until the expected
1214  // end of rx if there was a rx start before now.
1217  m_listener = 0;
1218  listener->MissedAck ();
1219 }
1220 void
1222 {
1223  NS_LOG_FUNCTION (this);
1226  m_listener = 0;
1227  if (m_phy->IsStateIdle ())
1228  {
1229  NS_LOG_DEBUG ("fast Ack idle missed");
1230  listener->MissedAck ();
1231  }
1232  else
1233  {
1234  NS_LOG_DEBUG ("fast Ack ok");
1235  }
1236 }
1237 void
1239 {
1240  NS_LOG_FUNCTION (this);
1241  NS_LOG_DEBUG ("block ack timeout");
1242 
1245  m_listener = 0;
1246  listener->MissedBlockAck ();
1247 }
1248 void
1250 {
1251  NS_LOG_FUNCTION (this);
1254  m_listener = 0;
1255  if (m_phy->IsStateIdle ())
1256  {
1257  NS_LOG_DEBUG ("super fast Ack failed");
1258  listener->MissedAck ();
1259  }
1260  else
1261  {
1262  NS_LOG_DEBUG ("super fast Ack ok");
1263  listener->GotAck (0.0, WifiMode ());
1264  }
1265 }
1266 
1267 void
1269 {
1270  NS_LOG_FUNCTION (this);
1271  /* send an RTS for this packet. */
1272  WifiMacHeader rts;
1273  rts.SetType (WIFI_MAC_CTL_RTS);
1274  rts.SetDsNotFrom ();
1275  rts.SetDsNotTo ();
1276  rts.SetNoRetry ();
1277  rts.SetNoMoreFragments ();
1278  rts.SetAddr1 (m_currentHdr.GetAddr1 ());
1279  rts.SetAddr2 (m_self);
1281  Time duration = Seconds (0);
1282  if (m_txParams.HasDurationId ())
1283  {
1284  duration += m_txParams.GetDurationId ();
1285  }
1286  else
1287  {
1289  duration += GetSifs ();
1290  duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxMode);
1291  duration += GetSifs ();
1293  dataTxMode, WIFI_PREAMBLE_LONG);
1294  duration += GetSifs ();
1295  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
1296  }
1297  rts.SetDuration (duration);
1298 
1299  Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxMode, WIFI_PREAMBLE_LONG);
1300  Time timerDelay = txDuration + GetCtsTimeout ();
1301 
1303  NotifyCtsTimeoutStartNow (timerDelay);
1305 
1306  Ptr<Packet> packet = Create<Packet> ();
1307  packet->AddHeader (rts);
1308  WifiMacTrailer fcs;
1309  packet->AddTrailer (fcs);
1310 
1311  ForwardDown (packet, &rts, rtsTxMode);
1312 }
1313 
1314 void
1316 {
1320  {
1321  Time timerDelay = txDuration + GetAckTimeout ();
1323  NotifyAckTimeoutStartNow (timerDelay);
1325  }
1326  else if (m_txParams.MustWaitFastAck ())
1327  {
1328  Time timerDelay = txDuration + GetPifs ();
1330  NotifyAckTimeoutStartNow (timerDelay);
1332  }
1333  else if (m_txParams.MustWaitSuperFastAck ())
1334  {
1335  Time timerDelay = txDuration + GetPifs ();
1337  NotifyAckTimeoutStartNow (timerDelay);
1340  }
1341  else if (m_txParams.MustWaitBasicBlockAck ())
1342  {
1343  Time timerDelay = txDuration + GetBasicBlockAckTimeout ();
1346  }
1348  {
1349  Time timerDelay = txDuration + GetCompressedBlockAckTimeout ();
1352  }
1353  else if (m_txParams.HasNextPacket ())
1354  {
1355  Time delay = txDuration + GetSifs ();
1358  }
1359  else
1360  {
1361  // since we do not expect any timer to be triggered.
1362  Simulator::Schedule(txDuration, &MacLow::EndTxNoAck, this);
1363  }
1364 }
1365 
1366 void
1368 {
1369  NS_LOG_FUNCTION (this);
1370  /* send this packet directly. No RTS is needed. */
1371  StartDataTxTimers ();
1372 
1374  Time duration = Seconds (0.0);
1375  if (m_txParams.HasDurationId ())
1376  {
1377  duration += m_txParams.GetDurationId ();
1378  }
1379  else
1380  {
1382  {
1383  duration += GetSifs ();
1384  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxMode, BASIC_BLOCK_ACK);
1385  }
1387  {
1388  duration += GetSifs ();
1389  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxMode, COMPRESSED_BLOCK_ACK);
1390  }
1391  else if (m_txParams.MustWaitAck ())
1392  {
1393  duration += GetSifs ();
1394  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
1395  }
1396  if (m_txParams.HasNextPacket ())
1397  {
1398  duration += GetSifs ();
1400  dataTxMode, WIFI_PREAMBLE_LONG);
1401  if (m_txParams.MustWaitAck ())
1402  {
1403  duration += GetSifs ();
1404  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
1405  }
1406  }
1407  }
1408  m_currentHdr.SetDuration (duration);
1409 
1411  WifiMacTrailer fcs;
1412  m_currentPacket->AddTrailer (fcs);
1413 
1414  ForwardDown (m_currentPacket, &m_currentHdr, dataTxMode);
1415  m_currentPacket = 0;
1416 }
1417 
1418 bool
1419 MacLow::IsNavZero (void) const
1420 {
1422  {
1423  return true;
1424  }
1425  else
1426  {
1427  return false;
1428  }
1429 }
1430 
1431 void
1432 MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode rtsTxMode, double rtsSnr)
1433 {
1434  NS_LOG_FUNCTION (this << source << duration << rtsTxMode << rtsSnr);
1435  /* send a CTS when you receive a RTS
1436  * right after SIFS.
1437  */
1438  WifiMode ctsTxMode = GetCtsTxModeForRts (source, rtsTxMode);
1439  WifiMacHeader cts;
1440  cts.SetType (WIFI_MAC_CTL_CTS);
1441  cts.SetDsNotFrom ();
1442  cts.SetDsNotTo ();
1443  cts.SetNoMoreFragments ();
1444  cts.SetNoRetry ();
1445  cts.SetAddr1 (source);
1446  duration -= GetCtsDuration (source, rtsTxMode);
1447  duration -= GetSifs ();
1448  NS_ASSERT (duration >= MicroSeconds (0));
1449  cts.SetDuration (duration);
1450 
1451  Ptr<Packet> packet = Create<Packet> ();
1452  packet->AddHeader (cts);
1453  WifiMacTrailer fcs;
1454  packet->AddTrailer (fcs);
1455 
1456  SnrTag tag;
1457  tag.Set (rtsSnr);
1458  packet->AddPacketTag (tag);
1459 
1460  ForwardDown (packet, &cts, ctsTxMode);
1461 }
1462 
1463 void
1465 {
1466  NS_LOG_FUNCTION (this);
1467  /* send the third step in a
1468  * RTS/CTS/DATA/ACK hanshake
1469  */
1470  NS_ASSERT (m_currentPacket != 0);
1471  StartDataTxTimers ();
1472 
1474  Time newDuration = Seconds (0);
1475  newDuration += GetSifs ();
1476  newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
1478  dataTxMode, WIFI_PREAMBLE_LONG);
1479  duration -= txDuration;
1480  duration -= GetSifs ();
1481 
1482  duration = std::max (duration, newDuration);
1483  NS_ASSERT (duration >= MicroSeconds (0));
1484  m_currentHdr.SetDuration (duration);
1485 
1487  WifiMacTrailer fcs;
1488  m_currentPacket->AddTrailer (fcs);
1489 
1490  ForwardDown (m_currentPacket, &m_currentHdr, dataTxMode);
1491  m_currentPacket = 0;
1492 }
1493 
1494 void
1496 {
1497  m_listener->StartNext ();
1498 }
1499 
1500 void
1502 {
1504  m_listener = 0;
1505  listener->EndTxNoAck ();
1506 }
1507 
1508 void
1510 {
1511  NS_LOG_FUNCTION (this);
1513  m_listener = 0;
1514  listener->MissedAck ();
1515  NS_LOG_DEBUG ("fast Ack busy but missed");
1516 }
1517 
1518 void
1519 MacLow::SendAckAfterData (Mac48Address source, Time duration, WifiMode dataTxMode, double dataSnr)
1520 {
1521  NS_LOG_FUNCTION (this);
1522  /* send an ACK when you receive
1523  * a packet after SIFS.
1524  */
1525  WifiMode ackTxMode = GetAckTxModeForData (source, dataTxMode);
1526  WifiMacHeader ack;
1527  ack.SetType (WIFI_MAC_CTL_ACK);
1528  ack.SetDsNotFrom ();
1529  ack.SetDsNotTo ();
1530  ack.SetNoRetry ();
1531  ack.SetNoMoreFragments ();
1532  ack.SetAddr1 (source);
1533  duration -= GetAckDuration (source, dataTxMode);
1534  duration -= GetSifs ();
1535  NS_ASSERT (duration >= MicroSeconds (0));
1536  ack.SetDuration (duration);
1537 
1538  Ptr<Packet> packet = Create<Packet> ();
1539  packet->AddHeader (ack);
1540  WifiMacTrailer fcs;
1541  packet->AddTrailer (fcs);
1542 
1543  SnrTag tag;
1544  tag.Set (dataSnr);
1545  packet->AddPacketTag (tag);
1546 
1547  ForwardDown (packet, &ack, ackTxMode);
1548 }
1549 
1550 bool
1552 {
1553  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1554  if (it != m_bAckAgreements.end ())
1555  {
1556  WifiMacTrailer fcs;
1557  packet->RemoveTrailer (fcs);
1558  BufferedPacket bufferedPacket (packet, hdr);
1559 
1560  uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
1561  uint16_t mappedSeqControl = QosUtilsMapSeqControlToUniqueInteger (hdr.GetSequenceControl (), endSequence);
1562 
1563  BufferedPacketI i = (*it).second.second.begin ();
1564  for (; i != (*it).second.second.end ()
1565  && QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceControl (), endSequence) < mappedSeqControl; i++)
1566  {
1567  ;
1568  }
1569  (*it).second.second.insert (i, bufferedPacket);
1570 
1571  //Update block ack cache
1572  BlockAckCachesI j = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1573  NS_ASSERT (j != m_bAckCaches.end ());
1574  (*j).second.UpdateWithMpdu (&hdr);
1575 
1576  return true;
1577  }
1578  return false;
1579 }
1580 
1581 void
1583  uint16_t startingSeq)
1584 {
1585  uint8_t tid = respHdr->GetTid ();
1586  BlockAckAgreement agreement (originator, tid);
1587  if (respHdr->IsImmediateBlockAck ())
1588  {
1589  agreement.SetImmediateBlockAck ();
1590  }
1591  else
1592  {
1593  agreement.SetDelayedBlockAck ();
1594  }
1595  agreement.SetAmsduSupport (respHdr->IsAmsduSupported ());
1596  agreement.SetBufferSize (respHdr->GetBufferSize () + 1);
1597  agreement.SetTimeout (respHdr->GetTimeout ());
1598  agreement.SetStartingSequence (startingSeq);
1599 
1600  std::list<BufferedPacket> buffer (0);
1601  AgreementKey key (originator, respHdr->GetTid ());
1602  AgreementValue value (agreement, buffer);
1603  m_bAckAgreements.insert (std::make_pair (key, value));
1604 
1605  BlockAckCache cache;
1606  cache.Init (startingSeq, respHdr->GetBufferSize () + 1);
1607  m_bAckCaches.insert (std::make_pair (key, cache));
1608 
1609  if (respHdr->GetTimeout () != 0)
1610  {
1611  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, respHdr->GetTid ()));
1612  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
1613 
1614  AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
1615 
1616  it->second.first.m_inactivityEvent = Simulator::Schedule (timeout,
1618  m_edcaListeners[ac],
1619  originator, tid);
1620  }
1621 }
1622 
1623 void
1625 {
1626  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1627  if (it != m_bAckAgreements.end ())
1628  {
1629  RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (), originator, tid);
1630  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
1631  m_bAckAgreements.erase (it);
1632 
1633  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
1634  NS_ASSERT (i != m_bAckCaches.end ());
1635  m_bAckCaches.erase (i);
1636  }
1637 }
1638 
1639 void
1641 {
1642  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1643  if (it != m_bAckAgreements.end ())
1644  {
1645  uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
1646  uint16_t mappedStart = QosUtilsMapSeqControlToUniqueInteger (seq, endSequence);
1647  uint16_t guard = (*it).second.second.begin ()->second.GetSequenceControl () & 0xfff0;
1648  BufferedPacketI last = (*it).second.second.begin ();
1649 
1650  BufferedPacketI i = (*it).second.second.begin ();
1651  for (; i != (*it).second.second.end ()
1652  && QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceNumber (), endSequence) < mappedStart;)
1653  {
1654  if (guard == (*i).second.GetSequenceControl ())
1655  {
1656  if (!(*i).second.IsMoreFragments ())
1657  {
1658  while (last != i)
1659  {
1660  m_rxCallback ((*last).first, &(*last).second);
1661  last++;
1662  }
1663  m_rxCallback ((*last).first, &(*last).second);
1664  last++;
1665  /* go to next packet */
1666  while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
1667  {
1668  i++;
1669  }
1670  if (i != (*it).second.second.end ())
1671  {
1672  guard = (*i).second.GetSequenceControl () & 0xfff0;
1673  last = i;
1674  }
1675  }
1676  else
1677  {
1678  guard++;
1679  }
1680  }
1681  else
1682  {
1683  /* go to next packet */
1684  while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
1685  {
1686  i++;
1687  }
1688  if (i != (*it).second.second.end ())
1689  {
1690  guard = (*i).second.GetSequenceControl () & 0xfff0;
1691  last = i;
1692  }
1693  }
1694  }
1695  (*it).second.second.erase ((*it).second.second.begin (), i);
1696  }
1697 }
1698 
1699 void
1701 {
1702  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1703  if (it != m_bAckAgreements.end ())
1704  {
1705  uint16_t startingSeqCtrl = ((*it).second.first.GetStartingSequence () << 4) & 0xfff0;
1706  uint16_t guard = startingSeqCtrl;
1707 
1708  BufferedPacketI lastComplete = (*it).second.second.begin ();
1709  BufferedPacketI i = (*it).second.second.begin ();
1710  for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
1711  {
1712  if (!(*i).second.IsMoreFragments ())
1713  {
1714  while (lastComplete != i)
1715  {
1716  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
1717  lastComplete++;
1718  }
1719  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
1720  lastComplete++;
1721  }
1722  guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
1723  }
1724  (*it).second.first.SetStartingSequence ((guard >> 4) & 0x0fff);
1725  /* All packets already forwarded to WifiMac must be removed from buffer:
1726  [begin (), lastComplete) */
1727  (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
1728  }
1729 }
1730 
1731 void
1732 MacLow::SendBlockAckResponse (const CtrlBAckResponseHeader* blockAck, Mac48Address originator, bool immediate,
1733  Time duration, WifiMode blockAckReqTxMode)
1734 {
1735  Ptr<Packet> packet = Create<Packet> ();
1736  packet->AddHeader (*blockAck);
1737 
1738  WifiMacHeader hdr;
1740  hdr.SetAddr1 (originator);
1741  hdr.SetAddr2 (GetAddress ());
1742  hdr.SetDsNotFrom ();
1743  hdr.SetDsNotTo ();
1744  hdr.SetNoRetry ();
1745  hdr.SetNoMoreFragments ();
1746 
1747  m_currentPacket = packet;
1748  m_currentHdr = hdr;
1749  if (immediate)
1750  {
1752  duration -= GetSifs ();
1753  if (blockAck->IsBasic ())
1754  {
1755  duration -= GetBlockAckDuration (originator, blockAckReqTxMode, BASIC_BLOCK_ACK);
1756  }
1757  else if (blockAck->IsCompressed ())
1758  {
1759  duration -= GetBlockAckDuration (originator, blockAckReqTxMode, COMPRESSED_BLOCK_ACK);
1760  }
1761  else if (blockAck->IsMultiTid ())
1762  {
1763  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
1764  }
1765  }
1766  else
1767  {
1768  m_txParams.EnableAck ();
1769  duration += GetSifs ();
1770  duration += GetAckDuration (originator, blockAckReqTxMode);
1771  }
1773 
1774  StartDataTxTimers ();
1775 
1776  NS_ASSERT (duration >= MicroSeconds (0));
1777  hdr.SetDuration (duration);
1778  //here should be present a control about immediate or delayed block ack
1779  //for now we assume immediate
1780  packet->AddHeader (hdr);
1781  WifiMacTrailer fcs;
1782  packet->AddTrailer (fcs);
1783  ForwardDown (packet, &hdr, blockAckReqTxMode);
1784  m_currentPacket = 0;
1785 }
1786 
1787 void
1789  Time duration, WifiMode blockAckReqTxMode)
1790 {
1791  NS_LOG_FUNCTION (this);
1792  CtrlBAckResponseHeader blockAck;
1793  uint8_t tid;
1794  bool immediate = false;
1795  if (!reqHdr.IsMultiTid ())
1796  {
1797  tid = reqHdr.GetTidInfo ();
1798  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1799  if (it != m_bAckAgreements.end ())
1800  {
1801  blockAck.SetStartingSequence (reqHdr.GetStartingSequence ());
1802  blockAck.SetTidInfo (tid);
1803  immediate = (*it).second.first.IsImmediateBlockAck ();
1804  if (reqHdr.IsBasic ())
1805  {
1806  blockAck.SetType (BASIC_BLOCK_ACK);
1807  }
1808  else if (reqHdr.IsCompressed ())
1809  {
1810  blockAck.SetType (COMPRESSED_BLOCK_ACK);
1811  }
1812  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
1813  NS_ASSERT (i != m_bAckCaches.end ());
1814  (*i).second.FillBlockAckBitmap (&blockAck);
1815 
1816  /* All packets with smaller sequence than starting sequence control must be passed up to Wifimac
1817  * See 9.10.3 in IEEE8022.11e standard.
1818  */
1820  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
1821  }
1822  else
1823  {
1824  NS_LOG_DEBUG ("there's not a valid block ack agreement with " << originator);
1825  }
1826  }
1827  else
1828  {
1829  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
1830  }
1831 
1832  SendBlockAckResponse (&blockAck, originator, immediate, duration, blockAckReqTxMode);
1833 }
1834 
1835 void
1837 {
1838  if (agreement.GetTimeout () != 0)
1839  {
1840  NS_ASSERT (agreement.m_inactivityEvent.IsRunning ());
1841  agreement.m_inactivityEvent.Cancel ();
1842  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
1843 
1844  AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
1845  //std::map<AcIndex, MacLowTransmissionListener*>::iterator it = m_edcaListeners.find (ac);
1846  //NS_ASSERT (it != m_edcaListeners.end ());
1847 
1848  agreement.m_inactivityEvent = Simulator::Schedule (timeout,
1850  m_edcaListeners[ac],
1851  agreement.GetPeer (),
1852  agreement.GetTid ());
1853  }
1854 }
1855 
1856 void
1858 {
1859  m_edcaListeners.insert (std::make_pair (ac, listener));
1860 }
1861 
1862 } // namespace ns3