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 {
100  m_overrideDurationId = Seconds (0);
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 {
195  NS_ASSERT (m_overrideDurationId != Seconds (0));
196  return m_overrideDurationId;
197 }
198 bool
200 {
201  return (m_nextSize != 0);
202 }
203 uint32_t
205 {
207  return m_nextSize;
208 }
209 
210 std::ostream &operator << (std::ostream &os, const MacLowTransmissionParameters &params)
211 {
212  os << "["
213  << "send rts=" << params.m_sendRts << ", "
214  << "next size=" << params.m_nextSize << ", "
215  << "dur=" << params.m_overrideDurationId << ", "
216  << "ack=";
217  switch (params.m_waitAck)
218  {
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);
301  m_lastNavDuration = Seconds (0);
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);
335  m_phy = 0;
336  m_stationManager = 0;
337  delete m_phyMacLowListener;
339 }
340 
341 void
343 {
344  NS_LOG_FUNCTION (this);
345  bool oneRunning = false;
347  {
349  oneRunning = true;
350  }
352  {
354  oneRunning = true;
355  }
357  {
359  oneRunning = true;
360  }
362  {
364  oneRunning = true;
365  }
367  {
369  oneRunning = true;
370  }
372  {
374  oneRunning = true;
375  }
376  if (m_sendCtsEvent.IsRunning ())
377  {
379  oneRunning = true;
380  }
381  if (m_sendAckEvent.IsRunning ())
382  {
384  oneRunning = true;
385  }
386  if (m_sendDataEvent.IsRunning ())
387  {
389  oneRunning = true;
390  }
391  if (m_waitSifsEvent.IsRunning ())
392  {
394  oneRunning = true;
395  }
396  if (m_waitRifsEvent.IsRunning ())
397  {
399  oneRunning = true;
400  }
402  {
404  oneRunning = true;
405  }
406  if (oneRunning && m_listener != 0)
407  {
408  m_listener->Cancel ();
409  m_listener = 0;
410  }
411 }
412 
413 void
415 {
416  m_phy = phy;
420 }
421 void
423 {
424  m_stationManager = manager;
425 }
426 
427 void
429 {
430  m_self = ad;
431 }
432 void
434 {
435  m_ackTimeout = ackTimeout;
436 }
437 void
439 {
440  m_basicBlockAckTimeout = blockAckTimeout;
441 }
442 void
444 {
445  m_compressedBlockAckTimeout = blockAckTimeout;
446 }
447 void
449 {
450  m_ctsToSelfSupported = enable;
451 }
452 bool
454 {
455  return m_ctsToSelfSupported;
456 }
457 void
459 {
460  m_ctsTimeout = ctsTimeout;
461 }
462 void
464 {
465  m_sifs = sifs;
466 }
467 void
469 {
470  m_slotTime = slotTime;
471 }
472 void
474 {
475  m_pifs = pifs;
476 }
477 void
479 {
480  m_rifs = rifs;
481 }
482 void
484 {
485  m_bssid = bssid;
486 }
487 void
489 {
490  m_promisc = true;
491 }
493 MacLow::GetAddress (void) const
494 {
495  return m_self;
496 }
497 Time
499 {
500  return m_ackTimeout;
501 }
502 Time
504 {
505  return m_basicBlockAckTimeout;
506 }
507 Time
509 {
511 }
512 Time
514 {
515  return m_ctsTimeout;
516 }
517 Time
518 MacLow::GetSifs (void) const
519 {
520  return m_sifs;
521 }
522 Time
523 MacLow::GetRifs (void) const
524 {
525  return m_rifs;
526 }
527 Time
529 {
530  return m_slotTime;
531 }
532 Time
533 MacLow::GetPifs (void) const
534 {
535  return m_pifs;
536 }
538 MacLow::GetBssid (void) const
539 {
540  return m_bssid;
541 }
542 
543 void
545 {
546  m_rxCallback = callback;
547 }
548 void
550 {
551  m_dcfListeners.push_back (listener);
552 }
553 
554 
555 void
557  const WifiMacHeader* hdr,
559  MacLowTransmissionListener *listener)
560 {
561  NS_LOG_FUNCTION (this << packet << hdr << params << listener);
562  /* m_currentPacket is not NULL because someone started
563  * a transmission and was interrupted before one of:
564  * - ctsTimeout
565  * - sendDataAfterCTS
566  * expired. This means that one of these timers is still
567  * running. They are all cancelled below anyway by the
568  * call to CancelAllEvents (because of at least one
569  * of these two timer) which will trigger a call to the
570  * previous listener's cancel method.
571  *
572  * This typically happens because the high-priority
573  * QapScheduler has taken access to the channel from
574  * one of the Edca of the QAP.
575  */
576  m_currentPacket = packet->Copy ();
577  m_currentHdr = *hdr;
578  CancelAllEvents ();
579  m_listener = listener;
580  m_txParams = params;
581 
582  //NS_ASSERT (m_phy->IsStateIdle ());
583 
584  NS_LOG_DEBUG ("startTx size=" << GetSize (m_currentPacket, &m_currentHdr) <<
585  ", to=" << m_currentHdr.GetAddr1 () << ", listener=" << m_listener);
586 
587  if (m_txParams.MustSendRts ())
588  {
589  SendRtsForPacket ();
590  }
591  else
592  {
594  {
595  SendCtsToSelf();
596  }
597  else
598  {
599  SendDataPacket ();
600  }
601  }
602 
603  /* When this method completes, we have taken ownership of the medium. */
604  NS_ASSERT (m_phy->IsStateTx ());
605 }
606 bool
608 {
610  return m_stationManager->NeedCtsToSelf (dataTxVector);
611 }
612 void
614 {
615  NS_LOG_FUNCTION (this << packet << rxSnr);
616  NS_LOG_DEBUG ("rx failed ");
618  {
622  }
623  return;
624 }
625 
626 void
628 {
629  NS_LOG_DEBUG ("switching channel. Cancelling MAC pending events");
631  CancelAllEvents ();
633  {
635  }
637  m_lastNavDuration = Seconds (0);
638  m_currentPacket = 0;
639  m_listener = 0;
640 }
641 
642 void
643 MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamble preamble)
644 {
645  NS_LOG_FUNCTION (this << packet << rxSnr << txMode << preamble);
646  /* A packet is received from the PHY.
647  * When we have handled this packet,
648  * we handle any packet present in the
649  * packet queue.
650  */
651  WifiMacHeader hdr;
652  packet->RemoveHeader (hdr);
653 
654  bool isPrevNavZero = IsNavZero ();
655  NS_LOG_DEBUG ("duration/id=" << hdr.GetDuration ());
656  NotifyNav (packet,hdr, txMode, preamble);
657  if (hdr.IsRts ())
658  {
659  /* see section 9.2.5.7 802.11-1999
660  * A STA that is addressed by an RTS frame shall transmit a CTS frame after a SIFS
661  * period if the NAV at the STA receiving the RTS frame indicates that the medium is
662  * idle. If the NAV at the STA receiving the RTS indicates the medium is not idle,
663  * that STA shall not respond to the RTS frame.
664  */
665  if (isPrevNavZero
666  && hdr.GetAddr1 () == m_self)
667  {
668  NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
670  m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
671  rxSnr, txMode);
674  hdr.GetAddr2 (),
675  hdr.GetDuration (),
676  txMode,
677  rxSnr);
678  }
679  else
680  {
681  NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
682  }
683  }
684  else if (hdr.IsCts ()
685  && hdr.GetAddr1 () == m_self
687  && m_currentPacket != 0)
688  {
689  NS_LOG_DEBUG ("receive cts from=" << m_currentHdr.GetAddr1 ());
690  SnrTag tag;
691  packet->RemovePacketTag (tag);
693  rxSnr, txMode);
695  rxSnr, txMode, tag.Get ());
696 
699  m_listener->GotCts (rxSnr, txMode);
703  hdr.GetAddr1 (),
704  hdr.GetDuration (),
705  txMode);
706  }
707  else if (hdr.IsAck ()
708  && hdr.GetAddr1 () == m_self
712  && m_txParams.MustWaitAck ())
713  {
714  NS_LOG_DEBUG ("receive ack from=" << m_currentHdr.GetAddr1 ());
715  SnrTag tag;
716  packet->RemovePacketTag (tag);
718  rxSnr, txMode);
720  rxSnr, txMode, tag.Get ());
721  bool gotAck = false;
724  {
727  gotAck = true;
728  }
731  {
734  gotAck = true;
735  }
736  if (gotAck)
737  {
738  m_listener->GotAck (rxSnr, txMode);
739  }
740  if (m_txParams.HasNextPacket ())
741  {
744  }
745  }
746  else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self
749  {
750  NS_LOG_DEBUG ("got block ack from " << hdr.GetAddr2 ());
751  CtrlBAckResponseHeader blockAck;
752  packet->RemoveHeader (blockAck);
754  m_listener->GotBlockAck (&blockAck, hdr.GetAddr2 ());
755  }
756  else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
757  {
758  CtrlBAckRequestHeader blockAckReq;
759  packet->RemoveHeader (blockAckReq);
760  if (!blockAckReq.IsMultiTid ())
761  {
762  uint8_t tid = blockAckReq.GetTidInfo ();
763  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), tid));
764  if (it != m_bAckAgreements.end ())
765  {
766  //Update block ack cache
767  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), tid));
768  NS_ASSERT (i != m_bAckCaches.end ());
769  (*i).second.UpdateWithBlockAckReq (blockAckReq.GetStartingSequence ());
770 
772  /* See section 11.5.3 in IEEE802.11 for mean of this timer */
773  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
774  if ((*it).second.first.IsImmediateBlockAck ())
775  {
776  NS_LOG_DEBUG ("rx blockAckRequest/sendImmediateBlockAck from=" << hdr.GetAddr2 ());
779  blockAckReq,
780  hdr.GetAddr2 (),
781  hdr.GetDuration (),
782  txMode);
783  }
784  else
785  {
786  NS_FATAL_ERROR ("Delayed block ack not supported.");
787  }
788  }
789  else
790  {
791  NS_LOG_DEBUG ("There's not a valid agreement for this block ack request.");
792  }
793  }
794  else
795  {
796  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
797  }
798  }
799  else if (hdr.IsCtl ())
800  {
801  NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ());
802  }
803  else if (hdr.GetAddr1 () == m_self)
804  {
805  m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
806  rxSnr, txMode);
807 
808  if (hdr.IsQosData () && StoreMpduIfNeeded (packet, hdr))
809  {
810  /* From section 9.10.4 in IEEE802.11:
811  Upon the receipt of a QoS data frame from the originator for which
812  the Block Ack agreement exists, the recipient shall buffer the MSDU
813  regardless of the value of the Ack Policy subfield within the
814  QoS Control field of the QoS data frame. */
815  if (hdr.IsQosAck ())
816  {
817  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
818  RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (),
819  hdr.GetAddr2 (), hdr.GetQosTid ());
824  hdr.GetAddr2 (),
825  hdr.GetDuration (),
826  txMode,
827  rxSnr);
828  }
829  else if (hdr.IsQosBlockAck ())
830  {
831  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
832  /* See section 11.5.3 in IEEE802.11 for mean of this timer */
833  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
834  }
835  return;
836  }
837  else if (hdr.IsQosData () && hdr.IsQosBlockAck ())
838  {
839  /* This happens if a packet with ack policy Block Ack is received and a block ack
840  agreement for that packet doesn't exist.
841 
842  From section 11.5.3 in IEEE802.11e:
843  When a recipient does not have an active Block ack for a TID, but receives
844  data MPDUs with the Ack Policy subfield set to Block Ack, it shall discard
845  them and shall send a DELBA frame using the normal access
846  mechanisms. */
847  AcIndex ac = QosUtilsMapTidToAc (hdr.GetQosTid ());
848  m_edcaListeners[ac]->BlockAckInactivityTimeout (hdr.GetAddr2 (), hdr.GetQosTid ());
849  return;
850  }
851  else if (hdr.IsQosData () && hdr.IsQosNoAck ())
852  {
853  NS_LOG_DEBUG ("rx unicast/noAck from=" << hdr.GetAddr2 ());
854  }
855  else if (hdr.IsData () || hdr.IsMgt ())
856  {
857  NS_LOG_DEBUG ("rx unicast/sendAck from=" << hdr.GetAddr2 ());
861  hdr.GetAddr2 (),
862  hdr.GetDuration (),
863  txMode,
864  rxSnr);
865  }
866  goto rxPacket;
867  }
868  else if (hdr.GetAddr1 ().IsGroup ())
869  {
870  if (hdr.IsData () || hdr.IsMgt ())
871  {
872  NS_LOG_DEBUG ("rx group from=" << hdr.GetAddr2 ());
873  goto rxPacket;
874  }
875  else
876  {
877  // DROP
878  }
879  }
880  else if (m_promisc)
881  {
882  NS_ASSERT (hdr.GetAddr1 () != m_self);
883  if (hdr.IsData ())
884  {
885  goto rxPacket;
886  }
887  }
888  else
889  {
890  //NS_LOG_DEBUG_VERBOSE ("rx not-for-me from %d", GetSource (packet));
891  }
892  return;
893 rxPacket:
894  WifiMacTrailer fcs;
895  packet->RemoveTrailer (fcs);
896  m_rxCallback (packet, &hdr);
897  return;
898 }
899 
900 uint32_t
901 MacLow::GetAckSize (void) const
902 {
903  WifiMacHeader ack;
905  return ack.GetSize () + 4;
906 }
907 uint32_t
909 {
910  WifiMacHeader hdr;
912  CtrlBAckResponseHeader blockAck;
913  if (type == BASIC_BLOCK_ACK)
914  {
915  blockAck.SetType (BASIC_BLOCK_ACK);
916  }
917  else if (type == COMPRESSED_BLOCK_ACK)
918  {
919  blockAck.SetType (COMPRESSED_BLOCK_ACK);
920  }
921  else if (type == MULTI_TID_BLOCK_ACK)
922  {
923  //Not implemented
924  NS_ASSERT (false);
925  }
926  return hdr.GetSize () + blockAck.GetSerializedSize () + 4;
927 }
928 uint32_t
929 MacLow::GetRtsSize (void) const
930 {
931  WifiMacHeader rts;
933  return rts.GetSize () + 4;
934 }
935 Time
937 {
938  WifiTxVector ackTxVector = GetAckTxVectorForData (to, dataTxVector.GetMode());
939  return GetAckDuration (ackTxVector);
940 }
941 Time
943 {
944  WifiPreamble preamble;
945  if (ackTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
946  preamble= WIFI_PREAMBLE_HT_MF;
947  else
948  preamble=WIFI_PREAMBLE_LONG;
949  return m_phy->CalculateTxDuration (GetAckSize (), ackTxVector, preamble);
950 }
951 Time
952 MacLow::GetBlockAckDuration (Mac48Address to, WifiTxVector blockAckReqTxVector, enum BlockAckType type) const
953 {
954  /*
955  * For immediate BlockAck we should transmit the frame with the same WifiMode
956  * as the BlockAckReq.
957  *
958  * from section 9.6 in IEEE802.11e:
959  * The BlockAck control frame shall be sent at the same rate and modulation class as
960  * the BlockAckReq frame if it is sent in response to a BlockAckReq frame.
961  */
962  WifiPreamble preamble;
963  if (blockAckReqTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
964  preamble= WIFI_PREAMBLE_HT_MF;
965  else
966  preamble=WIFI_PREAMBLE_LONG;
967  return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxVector, preamble);
968 }
969 Time
971 {
972  WifiTxVector ctsTxVector = GetCtsTxVectorForRts (to, rtsTxVector.GetMode());
973  return GetCtsDuration (ctsTxVector);
974 }
975 
976 Time
978 {
979  WifiPreamble preamble;
980  if (ctsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
981  preamble= WIFI_PREAMBLE_HT_MF;
982  else
983  preamble=WIFI_PREAMBLE_LONG;
984  return m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble);
985 }
986 uint32_t
987 MacLow::GetCtsSize (void) const
988 {
989  WifiMacHeader cts;
991  return cts.GetSize () + 4;
992 }
993 uint32_t
995 {
996  WifiMacTrailer fcs;
997  return packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
998 }
999 
1002 {
1003  return m_stationManager->GetCtsToSelfTxVector (hdr, packet);
1004 }
1005 
1008 {
1009  Mac48Address to = hdr->GetAddr1 ();
1010  return m_stationManager->GetRtsTxVector (to, hdr, packet);
1011 }
1014 {
1015  Mac48Address to = hdr->GetAddr1 ();
1016  WifiMacTrailer fcs;
1017  uint32_t size = packet->GetSize ()+ hdr->GetSize () + fcs.GetSerializedSize ();
1018  //size is not used in anything!! will not worry about aggregation
1019  return m_stationManager->GetDataTxVector (to, hdr, packet, size);
1020 }
1023 {
1024  return m_stationManager->GetCtsTxVector (to, rtsTxMode);
1025 }
1028 {
1029  return m_stationManager->GetAckTxVector (to, dataTxMode);
1030 }
1033 {
1034  return m_stationManager->GetBlockAckTxVector (to, dataTxMode);
1035 }
1036 
1039 {
1040  return GetCtsTxVector (to, rtsTxMode);
1041 }
1044 {
1045  return GetAckTxVector (to, dataTxMode);
1046 }
1047 
1048 
1049 Time
1051  const WifiMacHeader* hdr,
1052  const MacLowTransmissionParameters& params) const
1053 {
1054  WifiPreamble preamble;
1055  Time txTime = Seconds (0);
1056  WifiTxVector rtsTxVector = GetRtsTxVector (packet, hdr);
1057  WifiTxVector dataTxVector = GetDataTxVector (packet, hdr);
1058  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
1060  preamble= WIFI_PREAMBLE_HT_GF;
1061  else if (rtsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1062  preamble= WIFI_PREAMBLE_HT_MF;
1063  else
1064  preamble=WIFI_PREAMBLE_LONG;
1065  if (params.MustSendRts ())
1066  {
1067  txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble);
1068  txTime += GetCtsDuration (hdr->GetAddr1 (), rtsTxVector);
1069  txTime += Time (GetSifs () * 2);
1070  }
1071  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
1073  preamble= WIFI_PREAMBLE_HT_GF;
1074  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1075  preamble= WIFI_PREAMBLE_HT_MF;
1076  else
1077  preamble=WIFI_PREAMBLE_LONG;
1078  uint32_t dataSize = GetSize (packet, hdr);
1079  txTime += m_phy->CalculateTxDuration (dataSize, dataTxVector, preamble);
1080  if (params.MustWaitAck ())
1081  {
1082  txTime += GetSifs ();
1083  txTime += GetAckDuration (hdr->GetAddr1 (), dataTxVector);
1084  }
1085  return txTime;
1086 }
1087 
1088 Time
1090  const WifiMacHeader* hdr,
1091  const MacLowTransmissionParameters& params) const
1092 {
1093  Time txTime = CalculateOverallTxTime (packet, hdr, params);
1094  if (params.HasNextPacket ())
1095  {
1096  WifiTxVector dataTxVector = GetDataTxVector (packet, hdr);
1097  WifiPreamble preamble;
1098  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
1100  preamble= WIFI_PREAMBLE_HT_GF;
1101  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1102  preamble= WIFI_PREAMBLE_HT_MF;
1103  else
1104  preamble=WIFI_PREAMBLE_LONG;
1105  txTime += GetSifs ();
1106  txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataTxVector, preamble);
1107  }
1108  return txTime;
1109 }
1110 
1111 void
1113 {
1115  Time duration = hdr.GetDuration ();
1116 
1117  if (hdr.IsCfpoll ()
1118  && hdr.GetAddr2 () == m_bssid)
1119  {
1120  // see section 9.3.2.2 802.11-1999
1121  DoNavResetNow (duration);
1122  return;
1123  }
1126  else if (hdr.GetAddr1 () != m_self)
1127  {
1128  // see section 9.2.5.4 802.11-1999
1129  bool navUpdated = DoNavStartNow (duration);
1130  if (hdr.IsRts () && navUpdated)
1131  {
1140  WifiMacHeader cts;
1141  cts.SetType (WIFI_MAC_CTL_CTS);
1142  WifiTxVector txVector=GetRtsTxVector (packet, &hdr);
1143  Time navCounterResetCtsMissedDelay =
1144  m_phy->CalculateTxDuration (cts.GetSerializedSize (), txVector, preamble) +
1145  Time (2 * GetSifs ()) + Time (2 * GetSlotTime ());
1146  m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay,
1148  Simulator::Now ());
1149  }
1150  }
1151 }
1152 
1153 void
1155 {
1156  if (m_phy->GetLastRxStartTime () > rtsEndRxTime)
1157  {
1158  DoNavResetNow (Seconds (0.0));
1159  }
1160 }
1161 
1162 void
1164 {
1165  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1166  {
1167  (*i)->NavReset (duration);
1168  }
1170  m_lastNavStart = duration;
1171 }
1172 bool
1174 {
1175  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1176  {
1177  (*i)->NavStart (duration);
1178  }
1179  Time newNavEnd = Simulator::Now () + duration;
1180  Time oldNavEnd = m_lastNavStart + m_lastNavDuration;
1181  if (newNavEnd > oldNavEnd)
1182  {
1184  m_lastNavDuration = duration;
1185  return true;
1186  }
1187  return false;
1188 }
1189 void
1191 {
1192  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1193  {
1194  (*i)->AckTimeoutStart (duration);
1195  }
1196 }
1197 void
1199 {
1200  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1201  {
1202  (*i)->AckTimeoutReset ();
1203  }
1204 }
1205 void
1207 {
1208  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1209  {
1210  (*i)->CtsTimeoutStart (duration);
1211  }
1212 }
1213 void
1215 {
1216  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1217  {
1218  (*i)->CtsTimeoutReset ();
1219  }
1220 }
1221 
1222 void
1224  WifiTxVector txVector, WifiPreamble preamble)
1225 {
1226  NS_LOG_FUNCTION (this << packet << hdr << txVector);
1227  NS_LOG_DEBUG ("send " << hdr->GetTypeString () <<
1228  ", to=" << hdr->GetAddr1 () <<
1229  ", size=" << packet->GetSize () <<
1230  ", mode=" << txVector.GetMode() <<
1231  ", duration=" << hdr->GetDuration () <<
1232  ", seq=0x" << std::hex << m_currentHdr.GetSequenceControl () << std::dec);
1233  m_phy->SendPacket (packet, txVector.GetMode(), preamble, txVector);
1234 }
1235 
1236 void
1238 {
1239  NS_LOG_FUNCTION (this);
1240  NS_LOG_DEBUG ("cts timeout");
1245  m_currentPacket = 0;
1247  m_listener = 0;
1248  listener->MissedCts ();
1249 }
1250 void
1252 {
1253  NS_LOG_FUNCTION (this);
1254  NS_LOG_DEBUG ("normal ack timeout");
1260  m_listener = 0;
1261  listener->MissedAck ();
1262 }
1263 void
1265 {
1266  NS_LOG_FUNCTION (this);
1269  m_listener = 0;
1270  if (m_phy->IsStateIdle ())
1271  {
1272  NS_LOG_DEBUG ("fast Ack idle missed");
1273  listener->MissedAck ();
1274  }
1275  else
1276  {
1277  NS_LOG_DEBUG ("fast Ack ok");
1278  }
1279 }
1280 void
1282 {
1283  NS_LOG_FUNCTION (this);
1284  NS_LOG_DEBUG ("block ack timeout");
1285 
1288  m_listener = 0;
1289  listener->MissedBlockAck ();
1290 }
1291 void
1293 {
1294  NS_LOG_FUNCTION (this);
1297  m_listener = 0;
1298  if (m_phy->IsStateIdle ())
1299  {
1300  NS_LOG_DEBUG ("super fast Ack failed");
1301  listener->MissedAck ();
1302  }
1303  else
1304  {
1305  NS_LOG_DEBUG ("super fast Ack ok");
1306  listener->GotAck (0.0, WifiMode ());
1307  }
1308 }
1309 
1310 void
1312 {
1313  NS_LOG_FUNCTION (this);
1314  /* send an RTS for this packet. */
1315  WifiMacHeader rts;
1316  rts.SetType (WIFI_MAC_CTL_RTS);
1317  rts.SetDsNotFrom ();
1318  rts.SetDsNotTo ();
1319  rts.SetNoRetry ();
1320  rts.SetNoMoreFragments ();
1321  rts.SetAddr1 (m_currentHdr.GetAddr1 ());
1322  rts.SetAddr2 (m_self);
1324  Time duration = Seconds (0);
1325 
1326  WifiPreamble preamble;
1327  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
1329  preamble= WIFI_PREAMBLE_HT_GF;
1330  else if (rtsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1331  preamble= WIFI_PREAMBLE_HT_MF;
1332  else
1333  preamble=WIFI_PREAMBLE_LONG;
1334 
1335  if (m_txParams.HasDurationId ())
1336  {
1337  duration += m_txParams.GetDurationId ();
1338  }
1339  else
1340  {
1342  duration += GetSifs ();
1343  duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxVector);
1344  duration += GetSifs ();
1346  dataTxVector, preamble);
1347  duration += GetSifs ();
1348  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1349  }
1350  rts.SetDuration (duration);
1351 
1352  Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble);
1353  Time timerDelay = txDuration + GetCtsTimeout ();
1354 
1356  NotifyCtsTimeoutStartNow (timerDelay);
1358 
1359  Ptr<Packet> packet = Create<Packet> ();
1360  packet->AddHeader (rts);
1361  WifiMacTrailer fcs;
1362  packet->AddTrailer (fcs);
1363 
1364  ForwardDown (packet, &rts, rtsTxVector,preamble);
1365 }
1366 
1367 void
1369 {
1370  WifiPreamble preamble;
1371 
1372  //Since it is data then it can have format = GF
1374  preamble= WIFI_PREAMBLE_HT_GF;
1375  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1376  preamble= WIFI_PREAMBLE_HT_MF;
1377  else
1378  preamble=WIFI_PREAMBLE_LONG;
1379 
1380  Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxVector, preamble);
1382  {
1383  Time timerDelay = txDuration + GetAckTimeout ();
1385  NotifyAckTimeoutStartNow (timerDelay);
1387  }
1388  else if (m_txParams.MustWaitFastAck ())
1389  {
1390  Time timerDelay = txDuration + GetPifs ();
1392  NotifyAckTimeoutStartNow (timerDelay);
1394  }
1395  else if (m_txParams.MustWaitSuperFastAck ())
1396  {
1397  Time timerDelay = txDuration + GetPifs ();
1399  NotifyAckTimeoutStartNow (timerDelay);
1402  }
1403  else if (m_txParams.MustWaitBasicBlockAck ())
1404  {
1405  Time timerDelay = txDuration + GetBasicBlockAckTimeout ();
1408  }
1410  {
1411  Time timerDelay = txDuration + GetCompressedBlockAckTimeout ();
1414  }
1415  else if (m_txParams.HasNextPacket ())
1416  {
1418  {
1419  Time delay = txDuration + GetRifs ();
1422  }
1423  else
1424  {
1425  Time delay = txDuration + GetSifs ();
1428  }
1429  }
1430  else
1431  {
1432  // since we do not expect any timer to be triggered.
1433  Simulator::Schedule(txDuration, &MacLow::EndTxNoAck, this);
1434  }
1435 }
1436 
1437 void
1439 {
1440  NS_LOG_FUNCTION (this);
1441  /* send this packet directly. No RTS is needed. */
1443  WifiPreamble preamble;
1444 
1446  //In the future has to make sure that receiver has greenfield enabled
1447  preamble= WIFI_PREAMBLE_HT_GF;
1448  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1449  preamble= WIFI_PREAMBLE_HT_MF;
1450  else
1451  preamble=WIFI_PREAMBLE_LONG;
1452 
1453  StartDataTxTimers (dataTxVector);
1454 
1455  Time duration = Seconds (0.0);
1456  if (m_txParams.HasDurationId ())
1457  {
1458  duration += m_txParams.GetDurationId ();
1459  }
1460  else
1461  {
1463  {
1464  duration += GetSifs ();
1465  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, BASIC_BLOCK_ACK);
1466  }
1468  {
1469  duration += GetSifs ();
1470  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, COMPRESSED_BLOCK_ACK);
1471  }
1472  else if (m_txParams.MustWaitAck ())
1473  {
1474  duration += GetSifs ();
1475  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1476  }
1477  if (m_txParams.HasNextPacket ())
1478  {
1479  duration += GetSifs ();
1481  dataTxVector, preamble);
1482  if (m_txParams.MustWaitAck ())
1483  {
1484  duration += GetSifs ();
1485  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1486  }
1487  }
1488  }
1489  m_currentHdr.SetDuration (duration);
1490 
1492  WifiMacTrailer fcs;
1493  m_currentPacket->AddTrailer (fcs);
1494 
1495  ForwardDown (m_currentPacket, &m_currentHdr, dataTxVector,preamble);
1496  m_currentPacket = 0;
1497 }
1498 
1499 bool
1500 MacLow::IsNavZero (void) const
1501 {
1503  {
1504  return true;
1505  }
1506  else
1507  {
1508  return false;
1509  }
1510 }
1511 void
1513 {
1514  WifiMacHeader cts;
1515  cts.SetType (WIFI_MAC_CTL_CTS);
1516  cts.SetDsNotFrom ();
1517  cts.SetDsNotTo ();
1518  cts.SetNoMoreFragments ();
1519  cts.SetNoRetry ();
1520  cts.SetAddr1 (m_self);
1521 
1523 
1524  WifiPreamble preamble;
1525  if (ctsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1526  preamble= WIFI_PREAMBLE_HT_MF;
1527  else
1528  preamble=WIFI_PREAMBLE_LONG;
1529 
1530  Time duration = Seconds (0);
1531 
1532  if (m_txParams.HasDurationId ())
1533  {
1534  duration += m_txParams.GetDurationId ();
1535  }
1536  else
1537  {
1539  duration += GetSifs ();
1541  dataTxVector, preamble);
1543  {
1544 
1545  duration += GetSifs ();
1546  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, BASIC_BLOCK_ACK);
1547  }
1549  {
1550  duration += GetSifs ();
1551  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, COMPRESSED_BLOCK_ACK);
1552  }
1553  else if (m_txParams.MustWaitAck ())
1554  {
1555  duration += GetSifs ();
1556  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1557  }
1558  if (m_txParams.HasNextPacket ())
1559  {
1560  duration += GetSifs ();
1562  dataTxVector, preamble);
1564  {
1565  duration += GetSifs ();
1566  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, COMPRESSED_BLOCK_ACK);
1567  }
1568  else if (m_txParams.MustWaitAck ())
1569  {
1570  duration += GetSifs ();
1571  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1572  }
1573  }
1574  }
1575 
1576  cts.SetDuration (duration);
1577 
1578  Ptr<Packet> packet = Create<Packet> ();
1579  packet->AddHeader (cts);
1580  WifiMacTrailer fcs;
1581  packet->AddTrailer (fcs);
1582 
1583  ForwardDown (packet, &cts, ctsTxVector,preamble);
1584 
1585  Time txDuration = m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble);
1586  txDuration += GetSifs ();
1588 
1589  m_sendDataEvent = Simulator::Schedule (txDuration,
1590  &MacLow::SendDataAfterCts, this,
1591  cts.GetAddr1 (),
1592  duration,
1593  ctsTxVector.GetMode());
1594 }
1595 void
1596 MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode rtsTxMode, double rtsSnr)
1597 {
1598  NS_LOG_FUNCTION (this << source << duration << rtsTxMode << rtsSnr);
1599  /* send a CTS when you receive a RTS
1600  * right after SIFS.
1601  */
1602  WifiTxVector ctsTxVector = GetCtsTxVector (source, rtsTxMode);
1603  WifiMacHeader cts;
1604  cts.SetType (WIFI_MAC_CTL_CTS);
1605  cts.SetDsNotFrom ();
1606  cts.SetDsNotTo ();
1607  cts.SetNoMoreFragments ();
1608  cts.SetNoRetry ();
1609  cts.SetAddr1 (source);
1610  duration -= GetCtsDuration (source, ctsTxVector);
1611  duration -= GetSifs ();
1612  NS_ASSERT (duration >= MicroSeconds (0));
1613  cts.SetDuration (duration);
1614 
1615  Ptr<Packet> packet = Create<Packet> ();
1616  packet->AddHeader (cts);
1617  WifiMacTrailer fcs;
1618  packet->AddTrailer (fcs);
1619 
1620  SnrTag tag;
1621  tag.Set (rtsSnr);
1622  packet->AddPacketTag (tag);
1623 
1624  WifiPreamble preamble;
1625  if (ctsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1626  preamble= WIFI_PREAMBLE_HT_MF;
1627  else
1628  preamble=WIFI_PREAMBLE_LONG;
1629  ForwardDown (packet, &cts, ctsTxVector,preamble);
1630 }
1631 
1632 void
1634 {
1635  NS_LOG_FUNCTION (this);
1636  /* send the third step in a
1637  * RTS/CTS/DATA/ACK hanshake
1638  */
1639  NS_ASSERT (m_currentPacket != 0);
1641 
1642  WifiPreamble preamble;
1644  //In the future has to make sure that receiver has greenfield enabled
1645  preamble= WIFI_PREAMBLE_HT_GF;
1646  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1647  preamble= WIFI_PREAMBLE_HT_MF;
1648  else
1649  preamble=WIFI_PREAMBLE_LONG;
1650 
1651  StartDataTxTimers (dataTxVector);
1652  Time newDuration = Seconds (0);
1653  newDuration += GetSifs ();
1654  newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1656  dataTxVector, preamble);
1657  duration -= txDuration;
1658  duration -= GetSifs ();
1659 
1660  duration = std::max (duration, newDuration);
1661  NS_ASSERT (duration >= MicroSeconds (0));
1662  m_currentHdr.SetDuration (duration);
1663 
1665  WifiMacTrailer fcs;
1666  m_currentPacket->AddTrailer (fcs);
1667 
1668  ForwardDown (m_currentPacket, &m_currentHdr, dataTxVector,preamble);
1669  m_currentPacket = 0;
1670 }
1671 
1672 void
1674 {
1675  m_listener->StartNext ();
1676 }
1677 
1678 void
1680 {
1682  m_listener = 0;
1683  listener->EndTxNoAck ();
1684 }
1685 
1686 void
1688 {
1689  NS_LOG_FUNCTION (this);
1691  m_listener = 0;
1692  listener->MissedAck ();
1693  NS_LOG_DEBUG ("fast Ack busy but missed");
1694 }
1695 
1696 void
1697 MacLow::SendAckAfterData (Mac48Address source, Time duration, WifiMode dataTxMode, double dataSnr)
1698 {
1699  NS_LOG_FUNCTION (this);
1700  /* send an ACK when you receive
1701  * a packet after SIFS.
1702  */
1703  WifiTxVector ackTxVector = GetAckTxVector (source, dataTxMode);
1704  WifiMacHeader ack;
1705  ack.SetType (WIFI_MAC_CTL_ACK);
1706  ack.SetDsNotFrom ();
1707  ack.SetDsNotTo ();
1708  ack.SetNoRetry ();
1709  ack.SetNoMoreFragments ();
1710  ack.SetAddr1 (source);
1711  duration -= GetAckDuration (ackTxVector);
1712  duration -= GetSifs ();
1713  NS_ASSERT (duration >= MicroSeconds (0));
1714  ack.SetDuration (duration);
1715 
1716  Ptr<Packet> packet = Create<Packet> ();
1717  packet->AddHeader (ack);
1718  WifiMacTrailer fcs;
1719  packet->AddTrailer (fcs);
1720 
1721  SnrTag tag;
1722  tag.Set (dataSnr);
1723  packet->AddPacketTag (tag);
1724 
1725  //since ACK is a control response it can't have Fomat =GF
1726  WifiPreamble preamble;
1727  if (ackTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1728  preamble= WIFI_PREAMBLE_HT_MF;
1729  else
1730  preamble=WIFI_PREAMBLE_LONG;
1731  ForwardDown (packet, &ack, ackTxVector, preamble);
1732 }
1733 
1734 bool
1736 {
1737  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1738  if (it != m_bAckAgreements.end ())
1739  {
1740  WifiMacTrailer fcs;
1741  packet->RemoveTrailer (fcs);
1742  BufferedPacket bufferedPacket (packet, hdr);
1743 
1744  uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
1745  uint16_t mappedSeqControl = QosUtilsMapSeqControlToUniqueInteger (hdr.GetSequenceControl (), endSequence);
1746 
1747  BufferedPacketI i = (*it).second.second.begin ();
1748  for (; i != (*it).second.second.end ()
1749  && QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceControl (), endSequence) < mappedSeqControl; i++)
1750  {
1751  ;
1752  }
1753  (*it).second.second.insert (i, bufferedPacket);
1754 
1755  //Update block ack cache
1756  BlockAckCachesI j = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1757  NS_ASSERT (j != m_bAckCaches.end ());
1758  (*j).second.UpdateWithMpdu (&hdr);
1759 
1760  return true;
1761  }
1762  return false;
1763 }
1764 
1765 void
1767  uint16_t startingSeq)
1768 {
1769  uint8_t tid = respHdr->GetTid ();
1770  BlockAckAgreement agreement (originator, tid);
1771  if (respHdr->IsImmediateBlockAck ())
1772  {
1773  agreement.SetImmediateBlockAck ();
1774  }
1775  else
1776  {
1777  agreement.SetDelayedBlockAck ();
1778  }
1779  agreement.SetAmsduSupport (respHdr->IsAmsduSupported ());
1780  agreement.SetBufferSize (respHdr->GetBufferSize () + 1);
1781  agreement.SetTimeout (respHdr->GetTimeout ());
1782  agreement.SetStartingSequence (startingSeq);
1783 
1784  std::list<BufferedPacket> buffer (0);
1785  AgreementKey key (originator, respHdr->GetTid ());
1786  AgreementValue value (agreement, buffer);
1787  m_bAckAgreements.insert (std::make_pair (key, value));
1788 
1789  BlockAckCache cache;
1790  cache.Init (startingSeq, respHdr->GetBufferSize () + 1);
1791  m_bAckCaches.insert (std::make_pair (key, cache));
1792 
1793  if (respHdr->GetTimeout () != 0)
1794  {
1795  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, respHdr->GetTid ()));
1796  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
1797 
1798  AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
1799 
1800  it->second.first.m_inactivityEvent = Simulator::Schedule (timeout,
1802  m_edcaListeners[ac],
1803  originator, tid);
1804  }
1805 }
1806 
1807 void
1809 {
1810  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1811  if (it != m_bAckAgreements.end ())
1812  {
1813  RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (), originator, tid);
1814  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
1815  m_bAckAgreements.erase (it);
1816 
1817  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
1818  NS_ASSERT (i != m_bAckCaches.end ());
1819  m_bAckCaches.erase (i);
1820  }
1821 }
1822 
1823 void
1825 {
1826  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1827  if (it != m_bAckAgreements.end ())
1828  {
1829  uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
1830  uint16_t mappedStart = QosUtilsMapSeqControlToUniqueInteger (seq, endSequence);
1831  uint16_t guard = (*it).second.second.begin ()->second.GetSequenceControl () & 0xfff0;
1832  BufferedPacketI last = (*it).second.second.begin ();
1833 
1834  BufferedPacketI i = (*it).second.second.begin ();
1835  for (; i != (*it).second.second.end ()
1836  && QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceNumber (), endSequence) < mappedStart;)
1837  {
1838  if (guard == (*i).second.GetSequenceControl ())
1839  {
1840  if (!(*i).second.IsMoreFragments ())
1841  {
1842  while (last != i)
1843  {
1844  m_rxCallback ((*last).first, &(*last).second);
1845  last++;
1846  }
1847  m_rxCallback ((*last).first, &(*last).second);
1848  last++;
1849  /* go to next packet */
1850  while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
1851  {
1852  i++;
1853  }
1854  if (i != (*it).second.second.end ())
1855  {
1856  guard = (*i).second.GetSequenceControl () & 0xfff0;
1857  last = i;
1858  }
1859  }
1860  else
1861  {
1862  guard++;
1863  }
1864  }
1865  else
1866  {
1867  /* go to next packet */
1868  while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
1869  {
1870  i++;
1871  }
1872  if (i != (*it).second.second.end ())
1873  {
1874  guard = (*i).second.GetSequenceControl () & 0xfff0;
1875  last = i;
1876  }
1877  }
1878  }
1879  (*it).second.second.erase ((*it).second.second.begin (), i);
1880  }
1881 }
1882 
1883 void
1885 {
1886  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1887  if (it != m_bAckAgreements.end ())
1888  {
1889  uint16_t startingSeqCtrl = ((*it).second.first.GetStartingSequence () << 4) & 0xfff0;
1890  uint16_t guard = startingSeqCtrl;
1891 
1892  BufferedPacketI lastComplete = (*it).second.second.begin ();
1893  BufferedPacketI i = (*it).second.second.begin ();
1894  for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
1895  {
1896  if (!(*i).second.IsMoreFragments ())
1897  {
1898  while (lastComplete != i)
1899  {
1900  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
1901  lastComplete++;
1902  }
1903  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
1904  lastComplete++;
1905  }
1906  guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
1907  }
1908  (*it).second.first.SetStartingSequence ((guard >> 4) & 0x0fff);
1909  /* All packets already forwarded to WifiMac must be removed from buffer:
1910  [begin (), lastComplete) */
1911  (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
1912  }
1913 }
1914 
1915 void
1916 MacLow::SendBlockAckResponse (const CtrlBAckResponseHeader* blockAck, Mac48Address originator, bool immediate,
1917  Time duration, WifiMode blockAckReqTxMode)
1918 {
1919  Ptr<Packet> packet = Create<Packet> ();
1920  packet->AddHeader (*blockAck);
1921 
1922  WifiMacHeader hdr;
1924  hdr.SetAddr1 (originator);
1925  hdr.SetAddr2 (GetAddress ());
1926  hdr.SetDsNotFrom ();
1927  hdr.SetDsNotTo ();
1928  hdr.SetNoRetry ();
1929  hdr.SetNoMoreFragments ();
1930 
1931  WifiTxVector blockAckTxVector = GetBlockAckTxVector (originator, blockAckReqTxMode);
1932  WifiTxVector blockAckReqTxVector;
1933  blockAckReqTxVector.SetMode(blockAckReqTxMode);
1934  blockAckReqTxVector.SetNss(1);
1935  blockAckReqTxVector.SetStbc(false);
1936 
1937  m_currentPacket = packet;
1938  m_currentHdr = hdr;
1939  if (immediate)
1940  {
1942  duration -= GetSifs ();
1943  if (blockAck->IsBasic ())
1944  {
1945  duration -= GetBlockAckDuration (originator, blockAckReqTxVector, BASIC_BLOCK_ACK);
1946  }
1947  else if (blockAck->IsCompressed ())
1948  {
1949  duration -= GetBlockAckDuration (originator, blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1950  }
1951  else if (blockAck->IsMultiTid ())
1952  {
1953  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
1954  }
1955  }
1956  else
1957  {
1958  m_txParams.EnableAck ();
1959  duration += GetSifs ();
1960  duration += GetAckDuration (originator, blockAckReqTxVector);
1961  }
1963 
1964  if (!immediate)
1965  {
1966  StartDataTxTimers (blockAckTxVector);
1967  }
1968 
1969  NS_ASSERT (duration >= MicroSeconds (0));
1970  hdr.SetDuration (duration);
1971  //here should be present a control about immediate or delayed block ack
1972  //for now we assume immediate
1973  packet->AddHeader (hdr);
1974  WifiMacTrailer fcs;
1975  packet->AddTrailer (fcs);
1976  WifiPreamble preamble;
1977  if (blockAckTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1978  preamble= WIFI_PREAMBLE_HT_MF;
1979  else
1980  preamble=WIFI_PREAMBLE_LONG;
1981  ForwardDown (packet, &hdr, blockAckTxVector,preamble);
1982  m_currentPacket = 0;
1983 }
1984 
1985 void
1987  Time duration, WifiMode blockAckReqTxMode)
1988 {
1989  NS_LOG_FUNCTION (this);
1990  CtrlBAckResponseHeader blockAck;
1991  uint8_t tid;
1992  bool immediate = false;
1993  if (!reqHdr.IsMultiTid ())
1994  {
1995  tid = reqHdr.GetTidInfo ();
1996  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1997  if (it != m_bAckAgreements.end ())
1998  {
1999  blockAck.SetStartingSequence (reqHdr.GetStartingSequence ());
2000  blockAck.SetTidInfo (tid);
2001  immediate = (*it).second.first.IsImmediateBlockAck ();
2002  if (reqHdr.IsBasic ())
2003  {
2004  blockAck.SetType (BASIC_BLOCK_ACK);
2005  }
2006  else if (reqHdr.IsCompressed ())
2007  {
2008  blockAck.SetType (COMPRESSED_BLOCK_ACK);
2009  }
2010  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
2011  NS_ASSERT (i != m_bAckCaches.end ());
2012  (*i).second.FillBlockAckBitmap (&blockAck);
2013 
2014  /* All packets with smaller sequence than starting sequence control must be passed up to Wifimac
2015  * See 9.10.3 in IEEE8022.11e standard.
2016  */
2018  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
2019  }
2020  else
2021  {
2022  NS_LOG_DEBUG ("there's not a valid block ack agreement with " << originator);
2023  }
2024  }
2025  else
2026  {
2027  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
2028  }
2029 
2030  SendBlockAckResponse (&blockAck, originator, immediate, duration, blockAckReqTxMode);
2031 }
2032 
2033 void
2035 {
2036  if (agreement.GetTimeout () != 0)
2037  {
2038  NS_ASSERT (agreement.m_inactivityEvent.IsRunning ());
2039  agreement.m_inactivityEvent.Cancel ();
2040  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
2041 
2042  AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
2043  //std::map<AcIndex, MacLowTransmissionListener*>::iterator it = m_edcaListeners.find (ac);
2044  //NS_ASSERT (it != m_edcaListeners.end ());
2045 
2046  agreement.m_inactivityEvent = Simulator::Schedule (timeout,
2048  m_edcaListeners[ac],
2049  agreement.GetPeer (),
2050  agreement.GetTid ());
2051  }
2052 }
2053 
2054 void
2056 {
2057  m_edcaListeners.insert (std::make_pair (ac, listener));
2058 }
2059 
2060 } // namespace ns3