A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
mac-low.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 INRIA
4  * Copyright (c) 2009 MIRKO BANCHI
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20  * Author: Mirko Banchi <mk.banchi@gmail.com>
21  */
22 
23 #include "ns3/assert.h"
24 #include "ns3/packet.h"
25 #include "ns3/simulator.h"
26 #include "ns3/tag.h"
27 #include "ns3/log.h"
28 #include "ns3/node.h"
29 #include "ns3/double.h"
30 
31 #include "mac-low.h"
32 #include "wifi-phy.h"
33 #include "wifi-mac-trailer.h"
34 #include "qos-utils.h"
35 #include "edca-txop-n.h"
36 #include "snr-tag.h"
37 
38 NS_LOG_COMPONENT_DEFINE ("MacLow");
39 
40 #undef NS_LOG_APPEND_CONTEXT
41 #define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] "
42 
43 
44 namespace ns3 {
45 
47 {
48 }
50 {
51 }
52 void
54  Mac48Address source)
55 {
56 }
57 void
59 {
60 }
62 {
63 }
65 {
66 }
67 
69 {
70 }
72 {
73 }
74 
76  : m_nextSize (0),
77  m_waitAck (ACK_NONE),
78  m_sendRts (false),
79  m_overrideDurationId (Seconds (0))
80 {
81 }
82 void
84 {
85  m_nextSize = size;
86 }
87 void
89 {
90  m_nextSize = 0;
91 }
92 void
94 {
95  m_overrideDurationId = durationId;
96 }
97 void
99 {
101 }
102 void
104 {
106 }
107 void
109 {
111 }
112 void
114 {
116 }
117 void
119 {
121 }
122 void
124 {
126 }
127 void
129 {
131 }
132 void
134 {
136 }
137 void
139 {
140  m_sendRts = true;
141 }
142 void
144 {
145  m_sendRts = false;
146 }
147 bool
149 {
150  return (m_waitAck != ACK_NONE);
151 }
152 bool
154 {
155  return (m_waitAck == ACK_NORMAL);
156 }
157 bool
159 {
160  return (m_waitAck == ACK_FAST);
161 }
162 bool
164 {
165  return (m_waitAck == ACK_SUPER_FAST);
166 }
167 bool
169 {
170  return (m_waitAck == BLOCK_ACK_BASIC) ? true : false;
171 }
172 bool
174 {
175  return (m_waitAck == BLOCK_ACK_COMPRESSED) ? true : false;
176 }
177 bool
179 {
180  return (m_waitAck == BLOCK_ACK_MULTI_TID) ? true : false;
181 }
182 bool
184 {
185  return m_sendRts;
186 }
187 bool
189 {
190  return (m_overrideDurationId != Seconds (0));
191 }
192 Time
194 {
196  return m_overrideDurationId;
197 }
198 bool
200 {
201  return (m_nextSize != 0);
202 }
203 uint32_t
205 {
207  return m_nextSize;
208 }
209 
210 std::ostream &operator << (std::ostream &os, const MacLowTransmissionParameters &params)
211 {
212  os << "["
213  << "send rts=" << params.m_sendRts << ", "
214  << "next size=" << params.m_nextSize << ", "
215  << "dur=" << params.m_overrideDurationId << ", "
216  << "ack=";
217  switch (params.m_waitAck)
218  {
220  os << "none";
221  break;
223  os << "normal";
224  break;
226  os << "fast";
227  break;
229  os << "super-fast";
230  break;
232  os << "basic-block-ack";
233  break;
235  os << "compressed-block-ack";
236  break;
238  os << "multi-tid-block-ack";
239  break;
240  }
241  os << "]";
242  return os;
243 }
244 
245 
250 {
251 public:
258  : m_macLow (macLow)
259  {
260  }
262  {
263  }
264  virtual void NotifyRxStart (Time duration)
265  {
266  }
267  virtual void NotifyRxEndOk (void)
268  {
269  }
270  virtual void NotifyRxEndError (void)
271  {
272  }
273  virtual void NotifyTxStart (Time duration, double txPowerDbm)
274  {
275  }
276  virtual void NotifyMaybeCcaBusyStart (Time duration)
277  {
278  }
279  virtual void NotifySwitchingStart (Time duration)
280  {
281  m_macLow->NotifySwitchingStartNow (duration);
282  }
283  virtual void NotifySleep (void)
284  {
286  }
287  virtual void NotifyWakeup (void)
288  {
289  }
290 private:
292 };
293 
294 
296  : m_normalAckTimeoutEvent (),
297  m_fastAckTimeoutEvent (),
298  m_superFastAckTimeoutEvent (),
299  m_fastAckFailedTimeoutEvent (),
300  m_blockAckTimeoutEvent (),
301  m_ctsTimeoutEvent (),
302  m_sendCtsEvent (),
303  m_sendAckEvent (),
304  m_sendDataEvent (),
305  m_waitSifsEvent (),
306  m_endTxNoAckEvent (),
307  m_currentPacket (0),
308  m_listener (0),
309  m_phyMacLowListener (0),
310  m_ctsToSelfSupported (false)
311 {
312  NS_LOG_FUNCTION (this);
314  m_lastNavStart = Seconds (0);
315  m_promisc = false;
316 }
317 
319 {
320  NS_LOG_FUNCTION (this);
321 }
322 
323 void
325 {
328 }
329 
330 
331 void
333 {
334  NS_LOG_FUNCTION (this);
347  m_phy = 0;
348  m_stationManager = 0;
349  if (m_phyMacLowListener != 0)
350  {
351  delete m_phyMacLowListener;
353  }
354 }
355 
356 void
358 {
359  NS_LOG_FUNCTION (this);
360  bool oneRunning = false;
362  {
364  oneRunning = true;
365  }
367  {
369  oneRunning = true;
370  }
372  {
374  oneRunning = true;
375  }
377  {
379  oneRunning = true;
380  }
382  {
384  oneRunning = true;
385  }
387  {
389  oneRunning = true;
390  }
391  if (m_sendCtsEvent.IsRunning ())
392  {
394  oneRunning = true;
395  }
396  if (m_sendAckEvent.IsRunning ())
397  {
399  oneRunning = true;
400  }
401  if (m_sendDataEvent.IsRunning ())
402  {
404  oneRunning = true;
405  }
406  if (m_waitSifsEvent.IsRunning ())
407  {
409  oneRunning = true;
410  }
411  if (m_waitRifsEvent.IsRunning ())
412  {
414  oneRunning = true;
415  }
417  {
419  oneRunning = true;
420  }
421  if (oneRunning && m_listener != 0)
422  {
423  m_listener->Cancel ();
424  m_listener = 0;
425  }
426 }
427 
428 void
430 {
431  m_phy = phy;
435 }
436 void
438 {
439  m_stationManager = manager;
440 }
441 
442 void
444 {
445  m_self = ad;
446 }
447 void
449 {
450  m_ackTimeout = ackTimeout;
451 }
452 void
454 {
455  m_basicBlockAckTimeout = blockAckTimeout;
456 }
457 void
459 {
460  m_compressedBlockAckTimeout = blockAckTimeout;
461 }
462 void
464 {
465  m_ctsToSelfSupported = enable;
466 }
467 bool
469 {
470  return m_ctsToSelfSupported;
471 }
472 void
474 {
475  m_ctsTimeout = ctsTimeout;
476 }
477 void
479 {
480  m_sifs = sifs;
481 }
482 void
484 {
485  m_slotTime = slotTime;
486 }
487 void
489 {
490  m_pifs = pifs;
491 }
492 void
494 {
495  m_rifs = rifs;
496 }
497 void
499 {
500  m_bssid = bssid;
501 }
502 void
504 {
505  m_promisc = true;
506 }
508 MacLow::GetAddress (void) const
509 {
510  return m_self;
511 }
512 Time
514 {
515  return m_ackTimeout;
516 }
517 Time
519 {
520  return m_basicBlockAckTimeout;
521 }
522 Time
524 {
526 }
527 Time
529 {
530  return m_ctsTimeout;
531 }
532 Time
533 MacLow::GetSifs (void) const
534 {
535  return m_sifs;
536 }
537 Time
538 MacLow::GetRifs (void) const
539 {
540  return m_rifs;
541 }
542 Time
544 {
545  return m_slotTime;
546 }
547 Time
548 MacLow::GetPifs (void) const
549 {
550  return m_pifs;
551 }
553 MacLow::GetBssid (void) const
554 {
555  return m_bssid;
556 }
557 bool
558 MacLow::IsPromisc (void) const
559 {
560  return m_promisc;
561 }
562 
563 void
565 {
566  m_rxCallback = callback;
567 }
568 void
570 {
571  m_dcfListeners.push_back (listener);
572 }
573 
574 
575 void
577  const WifiMacHeader* hdr,
579  MacLowTransmissionListener *listener)
580 {
581  NS_LOG_FUNCTION (this << packet << hdr << params << listener);
582  /* m_currentPacket is not NULL because someone started
583  * a transmission and was interrupted before one of:
584  * - ctsTimeout
585  * - sendDataAfterCTS
586  * expired. This means that one of these timers is still
587  * running. They are all cancelled below anyway by the
588  * call to CancelAllEvents (because of at least one
589  * of these two timer) which will trigger a call to the
590  * previous listener's cancel method.
591  *
592  * This typically happens because the high-priority
593  * QapScheduler has taken access to the channel from
594  * one of the Edca of the QAP.
595  */
596  m_currentPacket = packet->Copy ();
597  m_currentHdr = *hdr;
598  CancelAllEvents ();
599  m_listener = listener;
600  m_txParams = params;
601 
602  //NS_ASSERT (m_phy->IsStateIdle ());
603 
604  NS_LOG_DEBUG ("startTx size=" << GetSize (m_currentPacket, &m_currentHdr) <<
605  ", to=" << m_currentHdr.GetAddr1 () << ", listener=" << m_listener);
606 
607  if (m_txParams.MustSendRts ())
608  {
609  SendRtsForPacket ();
610  }
611  else
612  {
614  {
615  SendCtsToSelf();
616  }
617  else
618  {
619  SendDataPacket ();
620  }
621  }
622 
623  /* When this method completes, we have taken ownership of the medium. */
624  NS_ASSERT (m_phy->IsStateTx ());
625 }
626 bool
628 {
630  return m_stationManager->NeedCtsToSelf (dataTxVector);
631 }
632 void
634 {
635  NS_LOG_FUNCTION (this << packet << rxSnr);
636  NS_LOG_DEBUG ("rx failed ");
638  {
642  }
643  return;
644 }
645 
646 void
648 {
649  NS_LOG_DEBUG ("switching channel. Cancelling MAC pending events");
650  m_stationManager->Reset ();
651  CancelAllEvents ();
653  {
655  }
658  m_currentPacket = 0;
659  m_listener = 0;
660 }
661 
662 void
664 {
665  NS_LOG_DEBUG ("Device in sleep mode. Cancelling MAC pending events");
666  m_stationManager->Reset ();
667  CancelAllEvents ();
669  {
671  }
674  m_currentPacket = 0;
675  m_listener = 0;
676 }
677 
678 void
679 MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamble preamble)
680 {
681  NS_LOG_FUNCTION (this << packet << rxSnr << txMode << preamble);
682  /* A packet is received from the PHY.
683  * When we have handled this packet,
684  * we handle any packet present in the
685  * packet queue.
686  */
687  WifiMacHeader hdr;
688  packet->RemoveHeader (hdr);
689 
690  bool isPrevNavZero = IsNavZero ();
691  NS_LOG_DEBUG ("duration/id=" << hdr.GetDuration ());
692  NotifyNav (packet,hdr, txMode, preamble);
693  if (hdr.IsRts ())
694  {
695  /* see section 9.2.5.7 802.11-1999
696  * A STA that is addressed by an RTS frame shall transmit a CTS frame after a SIFS
697  * period if the NAV at the STA receiving the RTS frame indicates that the medium is
698  * idle. If the NAV at the STA receiving the RTS indicates the medium is not idle,
699  * that STA shall not respond to the RTS frame.
700  */
701  if (isPrevNavZero
702  && hdr.GetAddr1 () == m_self)
703  {
704  NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
706  m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
707  rxSnr, txMode);
710  hdr.GetAddr2 (),
711  hdr.GetDuration (),
712  txMode,
713  rxSnr);
714  }
715  else
716  {
717  NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
718  }
719  }
720  else if (hdr.IsCts ()
721  && hdr.GetAddr1 () == m_self
723  && m_currentPacket != 0)
724  {
725  NS_LOG_DEBUG ("receive cts from=" << m_currentHdr.GetAddr1 ());
726  SnrTag tag;
727  packet->RemovePacketTag (tag);
729  rxSnr, txMode);
731  rxSnr, txMode, tag.Get ());
732 
735  m_listener->GotCts (rxSnr, txMode);
739  hdr.GetAddr1 (),
740  hdr.GetDuration (),
741  txMode);
742  }
743  else if (hdr.IsAck ()
744  && hdr.GetAddr1 () == m_self
748  && m_txParams.MustWaitAck ())
749  {
750  NS_LOG_DEBUG ("receive ack from=" << m_currentHdr.GetAddr1 ());
751  SnrTag tag;
752  packet->RemovePacketTag (tag);
754  rxSnr, txMode);
756  rxSnr, txMode, tag.Get ());
757  bool gotAck = false;
760  {
763  gotAck = true;
764  }
767  {
770  gotAck = true;
771  }
772  if (gotAck)
773  {
774  m_listener->GotAck (rxSnr, txMode);
775  }
776  if (m_txParams.HasNextPacket ())
777  {
780  }
781  }
782  else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self
785  {
786  NS_LOG_DEBUG ("got block ack from " << hdr.GetAddr2 ());
787  CtrlBAckResponseHeader blockAck;
788  packet->RemoveHeader (blockAck);
790  m_listener->GotBlockAck (&blockAck, hdr.GetAddr2 ());
791  }
792  else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
793  {
794  CtrlBAckRequestHeader blockAckReq;
795  packet->RemoveHeader (blockAckReq);
796  if (!blockAckReq.IsMultiTid ())
797  {
798  uint8_t tid = blockAckReq.GetTidInfo ();
799  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), tid));
800  if (it != m_bAckAgreements.end ())
801  {
802  //Update block ack cache
803  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), tid));
804  NS_ASSERT (i != m_bAckCaches.end ());
805  (*i).second.UpdateWithBlockAckReq (blockAckReq.GetStartingSequence ());
806 
808  /* See section 11.5.3 in IEEE802.11 for mean of this timer */
809  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
810  if ((*it).second.first.IsImmediateBlockAck ())
811  {
812  NS_LOG_DEBUG ("rx blockAckRequest/sendImmediateBlockAck from=" << hdr.GetAddr2 ());
815  blockAckReq,
816  hdr.GetAddr2 (),
817  hdr.GetDuration (),
818  txMode);
819  }
820  else
821  {
822  NS_FATAL_ERROR ("Delayed block ack not supported.");
823  }
824  }
825  else
826  {
827  NS_LOG_DEBUG ("There's not a valid agreement for this block ack request.");
828  }
829  }
830  else
831  {
832  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
833  }
834  }
835  else if (hdr.IsCtl ())
836  {
837  NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ());
838  }
839  else if (hdr.GetAddr1 () == m_self)
840  {
841  m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
842  rxSnr, txMode);
843 
844  if (hdr.IsQosData () && StoreMpduIfNeeded (packet, hdr))
845  {
846  /* From section 9.10.4 in IEEE802.11:
847  Upon the receipt of a QoS data frame from the originator for which
848  the Block Ack agreement exists, the recipient shall buffer the MSDU
849  regardless of the value of the Ack Policy subfield within the
850  QoS Control field of the QoS data frame. */
851  if (hdr.IsQosAck ())
852  {
853  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
854  RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (),
855  hdr.GetAddr2 (), hdr.GetQosTid ());
860  hdr.GetAddr2 (),
861  hdr.GetDuration (),
862  txMode,
863  rxSnr);
864  }
865  else if (hdr.IsQosBlockAck ())
866  {
867  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
868  /* See section 11.5.3 in IEEE802.11 for mean of this timer */
869  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
870  }
871  return;
872  }
873  else if (hdr.IsQosData () && hdr.IsQosBlockAck ())
874  {
875  /* This happens if a packet with ack policy Block Ack is received and a block ack
876  agreement for that packet doesn't exist.
877 
878  From section 11.5.3 in IEEE802.11e:
879  When a recipient does not have an active Block ack for a TID, but receives
880  data MPDUs with the Ack Policy subfield set to Block Ack, it shall discard
881  them and shall send a DELBA frame using the normal access
882  mechanisms. */
883  AcIndex ac = QosUtilsMapTidToAc (hdr.GetQosTid ());
884  m_edcaListeners[ac]->BlockAckInactivityTimeout (hdr.GetAddr2 (), hdr.GetQosTid ());
885  return;
886  }
887  else if (hdr.IsQosData () && hdr.IsQosNoAck ())
888  {
889  NS_LOG_DEBUG ("rx unicast/noAck from=" << hdr.GetAddr2 ());
890  }
891  else if (hdr.IsData () || hdr.IsMgt ())
892  {
893  NS_LOG_DEBUG ("rx unicast/sendAck from=" << hdr.GetAddr2 ());
897  hdr.GetAddr2 (),
898  hdr.GetDuration (),
899  txMode,
900  rxSnr);
901  }
902  goto rxPacket;
903  }
904  else if (hdr.GetAddr1 ().IsGroup ())
905  {
906  if (hdr.IsData () || hdr.IsMgt ())
907  {
908  NS_LOG_DEBUG ("rx group from=" << hdr.GetAddr2 ());
909  goto rxPacket;
910  }
911  else
912  {
913  // DROP
914  }
915  }
916  else if (m_promisc)
917  {
918  NS_ASSERT (hdr.GetAddr1 () != m_self);
919  if (hdr.IsData ())
920  {
921  goto rxPacket;
922  }
923  }
924  else
925  {
926  //NS_LOG_DEBUG_VERBOSE ("rx not-for-me from %d", GetSource (packet));
927  }
928  return;
929 rxPacket:
930  WifiMacTrailer fcs;
931  packet->RemoveTrailer (fcs);
932  m_rxCallback (packet, &hdr);
933  return;
934 }
935 
936 uint32_t
937 MacLow::GetAckSize (void) const
938 {
939  WifiMacHeader ack;
941  return ack.GetSize () + 4;
942 }
943 uint32_t
945 {
946  WifiMacHeader hdr;
948  CtrlBAckResponseHeader blockAck;
949  if (type == BASIC_BLOCK_ACK)
950  {
951  blockAck.SetType (BASIC_BLOCK_ACK);
952  }
953  else if (type == COMPRESSED_BLOCK_ACK)
954  {
955  blockAck.SetType (COMPRESSED_BLOCK_ACK);
956  }
957  else if (type == MULTI_TID_BLOCK_ACK)
958  {
959  //Not implemented
960  NS_ASSERT (false);
961  }
962  return hdr.GetSize () + blockAck.GetSerializedSize () + 4;
963 }
964 uint32_t
965 MacLow::GetRtsSize (void) const
966 {
967  WifiMacHeader rts;
969  return rts.GetSize () + 4;
970 }
971 Time
973 {
974  WifiTxVector ackTxVector = GetAckTxVectorForData (to, dataTxVector.GetMode());
975  return GetAckDuration (ackTxVector);
976 }
977 Time
979 {
980  WifiPreamble preamble;
981  if (ackTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
982  preamble= WIFI_PREAMBLE_HT_MF;
983  else
984  preamble=WIFI_PREAMBLE_LONG;
985  return m_phy->CalculateTxDuration (GetAckSize (), ackTxVector, preamble);
986 }
987 Time
988 MacLow::GetBlockAckDuration (Mac48Address to, WifiTxVector blockAckReqTxVector, enum BlockAckType type) const
989 {
990  /*
991  * For immediate BlockAck we should transmit the frame with the same WifiMode
992  * as the BlockAckReq.
993  *
994  * from section 9.6 in IEEE802.11e:
995  * The BlockAck control frame shall be sent at the same rate and modulation class as
996  * the BlockAckReq frame if it is sent in response to a BlockAckReq frame.
997  */
998  WifiPreamble preamble;
999  if (blockAckReqTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1000  preamble= WIFI_PREAMBLE_HT_MF;
1001  else
1002  preamble=WIFI_PREAMBLE_LONG;
1003  return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxVector, preamble);
1004 }
1005 Time
1007 {
1008  WifiTxVector ctsTxVector = GetCtsTxVectorForRts (to, rtsTxVector.GetMode());
1009  return GetCtsDuration (ctsTxVector);
1010 }
1011 
1012 Time
1014 {
1015  WifiPreamble preamble;
1016  if (ctsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1017  preamble= WIFI_PREAMBLE_HT_MF;
1018  else
1019  preamble=WIFI_PREAMBLE_LONG;
1020  return m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble);
1021 }
1022 uint32_t
1024 {
1025  WifiMacHeader cts;
1026  cts.SetType (WIFI_MAC_CTL_CTS);
1027  return cts.GetSize () + 4;
1028 }
1029 uint32_t
1031 {
1032  WifiMacTrailer fcs;
1033  return packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
1034 }
1035 
1038 {
1039  return m_stationManager->GetCtsToSelfTxVector (hdr, packet);
1040 }
1041 
1044 {
1045  Mac48Address to = hdr->GetAddr1 ();
1046  return m_stationManager->GetRtsTxVector (to, hdr, packet);
1047 }
1050 {
1051  Mac48Address to = hdr->GetAddr1 ();
1052  WifiMacTrailer fcs;
1053  uint32_t size = packet->GetSize ()+ hdr->GetSize () + fcs.GetSerializedSize ();
1054  //size is not used in anything!! will not worry about aggregation
1055  return m_stationManager->GetDataTxVector (to, hdr, packet, size);
1056 }
1059 {
1060  return m_stationManager->GetCtsTxVector (to, rtsTxMode);
1061 }
1064 {
1065  return m_stationManager->GetAckTxVector (to, dataTxMode);
1066 }
1069 {
1070  return m_stationManager->GetBlockAckTxVector (to, dataTxMode);
1071 }
1072 
1075 {
1076  return GetCtsTxVector (to, rtsTxMode);
1077 }
1080 {
1081  return GetAckTxVector (to, dataTxMode);
1082 }
1083 
1084 
1085 Time
1087  const WifiMacHeader* hdr,
1088  const MacLowTransmissionParameters& params) const
1089 {
1090  WifiPreamble preamble;
1091  Time txTime = Seconds (0);
1092  if (params.MustSendRts ())
1093  {
1094  WifiTxVector rtsTxVector = GetRtsTxVector (packet, hdr);
1095  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
1096  if (m_phy->GetGreenfield () && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1097  {
1098  preamble = WIFI_PREAMBLE_HT_GF;
1099  }
1100  else if (rtsTxVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HT)
1101  {
1102  preamble = WIFI_PREAMBLE_HT_MF;
1103  }
1104  else
1105  {
1106  preamble = WIFI_PREAMBLE_LONG;
1107  }
1108  txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble);
1109  txTime += GetCtsDuration (hdr->GetAddr1 (), rtsTxVector);
1110  txTime += Time (GetSifs () * 2);
1111  }
1112  WifiTxVector dataTxVector = GetDataTxVector (packet, hdr);
1113  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
1114  if ( m_phy->GetGreenfield()&& m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1115  preamble= WIFI_PREAMBLE_HT_GF;
1116  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1117  preamble= WIFI_PREAMBLE_HT_MF;
1118  else
1119  preamble=WIFI_PREAMBLE_LONG;
1120  uint32_t dataSize = GetSize (packet, hdr);
1121  txTime += m_phy->CalculateTxDuration (dataSize, dataTxVector, preamble);
1122  if (params.MustWaitAck ())
1123  {
1124  txTime += GetSifs ();
1125  txTime += GetAckDuration (hdr->GetAddr1 (), dataTxVector);
1126  }
1127  return txTime;
1128 }
1129 
1130 Time
1132  const WifiMacHeader* hdr,
1133  const MacLowTransmissionParameters& params) const
1134 {
1135  Time txTime = CalculateOverallTxTime (packet, hdr, params);
1136  if (params.HasNextPacket ())
1137  {
1138  WifiTxVector dataTxVector = GetDataTxVector (packet, hdr);
1139  WifiPreamble preamble;
1140  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
1141  if ( m_phy->GetGreenfield()&& m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1142  preamble= WIFI_PREAMBLE_HT_GF;
1143  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1144  preamble= WIFI_PREAMBLE_HT_MF;
1145  else
1146  preamble=WIFI_PREAMBLE_LONG;
1147  txTime += GetSifs ();
1148  txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataTxVector, preamble);
1149  }
1150  return txTime;
1151 }
1152 
1153 void
1155 {
1157  Time duration = hdr.GetDuration ();
1158 
1159  if (hdr.IsCfpoll ()
1160  && hdr.GetAddr2 () == m_bssid)
1161  {
1162  // see section 9.3.2.2 802.11-1999
1163  DoNavResetNow (duration);
1164  return;
1165  }
1168  else if (hdr.GetAddr1 () != m_self)
1169  {
1170  // see section 9.2.5.4 802.11-1999
1171  bool navUpdated = DoNavStartNow (duration);
1172  if (hdr.IsRts () && navUpdated)
1173  {
1182  WifiMacHeader cts;
1183  cts.SetType (WIFI_MAC_CTL_CTS);
1184  WifiTxVector txVector=GetRtsTxVector (packet, &hdr);
1185  Time navCounterResetCtsMissedDelay =
1186  m_phy->CalculateTxDuration (cts.GetSerializedSize (), txVector, preamble) +
1187  Time (2 * GetSifs ()) + Time (2 * GetSlotTime ());
1188  m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay,
1190  Simulator::Now ());
1191  }
1192  }
1193 }
1194 
1195 void
1197 {
1198  if (m_phy->GetLastRxStartTime () < rtsEndRxTime)
1199  {
1200  DoNavResetNow (Seconds (0.0));
1201  }
1202 }
1203 
1204 void
1206 {
1207  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1208  {
1209  (*i)->NavReset (duration);
1210  }
1212  m_lastNavStart = duration;
1213 }
1214 bool
1216 {
1217  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1218  {
1219  (*i)->NavStart (duration);
1220  }
1221  Time newNavEnd = Simulator::Now () + duration;
1222  Time oldNavEnd = m_lastNavStart + m_lastNavDuration;
1223  if (newNavEnd > oldNavEnd)
1224  {
1226  m_lastNavDuration = duration;
1227  return true;
1228  }
1229  return false;
1230 }
1231 void
1233 {
1234  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1235  {
1236  (*i)->AckTimeoutStart (duration);
1237  }
1238 }
1239 void
1241 {
1242  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1243  {
1244  (*i)->AckTimeoutReset ();
1245  }
1246 }
1247 void
1249 {
1250  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1251  {
1252  (*i)->CtsTimeoutStart (duration);
1253  }
1254 }
1255 void
1257 {
1258  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1259  {
1260  (*i)->CtsTimeoutReset ();
1261  }
1262 }
1263 
1264 void
1266  WifiTxVector txVector, WifiPreamble preamble)
1267 {
1268  NS_LOG_FUNCTION (this << packet << hdr << txVector);
1269  NS_LOG_DEBUG ("send " << hdr->GetTypeString () <<
1270  ", to=" << hdr->GetAddr1 () <<
1271  ", size=" << packet->GetSize () <<
1272  ", mode=" << txVector.GetMode() <<
1273  ", duration=" << hdr->GetDuration () <<
1274  ", seq=0x" << std::hex << m_currentHdr.GetSequenceControl () << std::dec);
1275  m_phy->SendPacket (packet, txVector, preamble);
1276 }
1277 
1278 void
1280 {
1281  NS_LOG_FUNCTION (this);
1282  NS_LOG_DEBUG ("cts timeout");
1286  m_stationManager->ReportRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1287  m_currentPacket = 0;
1289  m_listener = 0;
1290  listener->MissedCts ();
1291 }
1292 void
1294 {
1295  NS_LOG_FUNCTION (this);
1296  NS_LOG_DEBUG ("normal ack timeout");
1300  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1302  m_listener = 0;
1303  listener->MissedAck ();
1304 }
1305 void
1307 {
1308  NS_LOG_FUNCTION (this);
1309  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1311  m_listener = 0;
1312  if (m_phy->IsStateIdle ())
1313  {
1314  NS_LOG_DEBUG ("fast Ack idle missed");
1315  listener->MissedAck ();
1316  }
1317  else
1318  {
1319  NS_LOG_DEBUG ("fast Ack ok");
1320  }
1321 }
1322 void
1324 {
1325  NS_LOG_FUNCTION (this);
1326  NS_LOG_DEBUG ("block ack timeout");
1327 
1328  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1330  m_listener = 0;
1331  listener->MissedBlockAck ();
1332 }
1333 void
1335 {
1336  NS_LOG_FUNCTION (this);
1337  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1339  m_listener = 0;
1340  if (m_phy->IsStateIdle ())
1341  {
1342  NS_LOG_DEBUG ("super fast Ack failed");
1343  listener->MissedAck ();
1344  }
1345  else
1346  {
1347  NS_LOG_DEBUG ("super fast Ack ok");
1348  listener->GotAck (0.0, WifiMode ());
1349  }
1350 }
1351 
1352 void
1354 {
1355  NS_LOG_FUNCTION (this);
1356  /* send an RTS for this packet. */
1357  WifiMacHeader rts;
1358  rts.SetType (WIFI_MAC_CTL_RTS);
1359  rts.SetDsNotFrom ();
1360  rts.SetDsNotTo ();
1361  rts.SetNoRetry ();
1362  rts.SetNoMoreFragments ();
1363  rts.SetAddr1 (m_currentHdr.GetAddr1 ());
1364  rts.SetAddr2 (m_self);
1366  Time duration = Seconds (0);
1367 
1368  WifiPreamble preamble;
1369  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
1370  if ( m_phy->GetGreenfield()&& m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1371  preamble= WIFI_PREAMBLE_HT_GF;
1372  else if (rtsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1373  preamble= WIFI_PREAMBLE_HT_MF;
1374  else
1375  preamble=WIFI_PREAMBLE_LONG;
1376 
1377  if (m_txParams.HasDurationId ())
1378  {
1379  duration += m_txParams.GetDurationId ();
1380  }
1381  else
1382  {
1384  duration += GetSifs ();
1385  duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxVector);
1386  duration += GetSifs ();
1388  dataTxVector, preamble);
1389  duration += GetSifs ();
1390  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1391  }
1392  rts.SetDuration (duration);
1393 
1394  Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble);
1395  Time timerDelay = txDuration + GetCtsTimeout ();
1396 
1398  NotifyCtsTimeoutStartNow (timerDelay);
1400 
1401  Ptr<Packet> packet = Create<Packet> ();
1402  packet->AddHeader (rts);
1403  WifiMacTrailer fcs;
1404  packet->AddTrailer (fcs);
1405 
1406  ForwardDown (packet, &rts, rtsTxVector,preamble);
1407 }
1408 
1409 void
1411 {
1412  WifiPreamble preamble;
1413 
1414  //Since it is data then it can have format = GF
1415  if (m_phy->GetGreenfield() && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1416  preamble= WIFI_PREAMBLE_HT_GF;
1417  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1418  preamble= WIFI_PREAMBLE_HT_MF;
1419  else
1420  preamble=WIFI_PREAMBLE_LONG;
1421 
1422  Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxVector, preamble);
1424  {
1425  Time timerDelay = txDuration + GetAckTimeout ();
1427  NotifyAckTimeoutStartNow (timerDelay);
1429  }
1430  else if (m_txParams.MustWaitFastAck ())
1431  {
1432  Time timerDelay = txDuration + GetPifs ();
1434  NotifyAckTimeoutStartNow (timerDelay);
1436  }
1437  else if (m_txParams.MustWaitSuperFastAck ())
1438  {
1439  Time timerDelay = txDuration + GetPifs ();
1441  NotifyAckTimeoutStartNow (timerDelay);
1444  }
1445  else if (m_txParams.MustWaitBasicBlockAck ())
1446  {
1447  Time timerDelay = txDuration + GetBasicBlockAckTimeout ();
1450  }
1452  {
1453  Time timerDelay = txDuration + GetCompressedBlockAckTimeout ();
1456  }
1457  else if (m_txParams.HasNextPacket ())
1458  {
1459  if (m_stationManager->HasHtSupported())
1460  {
1461  Time delay = txDuration + GetRifs ();
1464  }
1465  else
1466  {
1467  Time delay = txDuration + GetSifs ();
1470  }
1471  }
1472  else
1473  {
1474  // since we do not expect any timer to be triggered.
1475  Simulator::Schedule(txDuration, &MacLow::EndTxNoAck, this);
1476  }
1477 }
1478 
1479 void
1481 {
1482  NS_LOG_FUNCTION (this);
1483  /* send this packet directly. No RTS is needed. */
1485  WifiPreamble preamble;
1486 
1487  if (m_phy->GetGreenfield() && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1488  //In the future has to make sure that receiver has greenfield enabled
1489  preamble= WIFI_PREAMBLE_HT_GF;
1490  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1491  preamble= WIFI_PREAMBLE_HT_MF;
1492  else
1493  preamble=WIFI_PREAMBLE_LONG;
1494 
1495  StartDataTxTimers (dataTxVector);
1496 
1497  Time duration = Seconds (0.0);
1498  if (m_txParams.HasDurationId ())
1499  {
1500  duration += m_txParams.GetDurationId ();
1501  }
1502  else
1503  {
1505  {
1506  duration += GetSifs ();
1507  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, BASIC_BLOCK_ACK);
1508  }
1510  {
1511  duration += GetSifs ();
1512  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, COMPRESSED_BLOCK_ACK);
1513  }
1514  else if (m_txParams.MustWaitAck ())
1515  {
1516  duration += GetSifs ();
1517  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1518  }
1519  if (m_txParams.HasNextPacket ())
1520  {
1521  duration += GetSifs ();
1523  dataTxVector, preamble);
1524  if (m_txParams.MustWaitAck ())
1525  {
1526  duration += GetSifs ();
1527  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1528  }
1529  }
1530  }
1531  m_currentHdr.SetDuration (duration);
1532 
1534  WifiMacTrailer fcs;
1535  m_currentPacket->AddTrailer (fcs);
1536 
1537  ForwardDown (m_currentPacket, &m_currentHdr, dataTxVector,preamble);
1538  m_currentPacket = 0;
1539 }
1540 
1541 bool
1542 MacLow::IsNavZero (void) const
1543 {
1545  {
1546  return true;
1547  }
1548  else
1549  {
1550  return false;
1551  }
1552 }
1553 void
1555 {
1556  WifiMacHeader cts;
1557  cts.SetType (WIFI_MAC_CTL_CTS);
1558  cts.SetDsNotFrom ();
1559  cts.SetDsNotTo ();
1560  cts.SetNoMoreFragments ();
1561  cts.SetNoRetry ();
1562  cts.SetAddr1 (m_self);
1563 
1565 
1566  WifiPreamble preamble;
1567  if (ctsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1568  preamble= WIFI_PREAMBLE_HT_MF;
1569  else
1570  preamble=WIFI_PREAMBLE_LONG;
1571 
1572  Time duration = Seconds (0);
1573 
1574  if (m_txParams.HasDurationId ())
1575  {
1576  duration += m_txParams.GetDurationId ();
1577  }
1578  else
1579  {
1581  duration += GetSifs ();
1583  dataTxVector, preamble);
1585  {
1586 
1587  duration += GetSifs ();
1588  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, BASIC_BLOCK_ACK);
1589  }
1591  {
1592  duration += GetSifs ();
1593  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, COMPRESSED_BLOCK_ACK);
1594  }
1595  else if (m_txParams.MustWaitAck ())
1596  {
1597  duration += GetSifs ();
1598  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1599  }
1600  if (m_txParams.HasNextPacket ())
1601  {
1602  duration += GetSifs ();
1604  dataTxVector, preamble);
1606  {
1607  duration += GetSifs ();
1608  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, COMPRESSED_BLOCK_ACK);
1609  }
1610  else if (m_txParams.MustWaitAck ())
1611  {
1612  duration += GetSifs ();
1613  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1614  }
1615  }
1616  }
1617 
1618  cts.SetDuration (duration);
1619 
1620  Ptr<Packet> packet = Create<Packet> ();
1621  packet->AddHeader (cts);
1622  WifiMacTrailer fcs;
1623  packet->AddTrailer (fcs);
1624 
1625  ForwardDown (packet, &cts, ctsTxVector,preamble);
1626 
1627  Time txDuration = m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble);
1628  txDuration += GetSifs ();
1630 
1631  m_sendDataEvent = Simulator::Schedule (txDuration,
1632  &MacLow::SendDataAfterCts, this,
1633  cts.GetAddr1 (),
1634  duration,
1635  ctsTxVector.GetMode());
1636 }
1637 void
1638 MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode rtsTxMode, double rtsSnr)
1639 {
1640  NS_LOG_FUNCTION (this << source << duration << rtsTxMode << rtsSnr);
1641  /* send a CTS when you receive a RTS
1642  * right after SIFS.
1643  */
1644  WifiTxVector ctsTxVector = GetCtsTxVector (source, rtsTxMode);
1645  WifiMacHeader cts;
1646  cts.SetType (WIFI_MAC_CTL_CTS);
1647  cts.SetDsNotFrom ();
1648  cts.SetDsNotTo ();
1649  cts.SetNoMoreFragments ();
1650  cts.SetNoRetry ();
1651  cts.SetAddr1 (source);
1652  duration -= GetCtsDuration (source, ctsTxVector);
1653  duration -= GetSifs ();
1654  NS_ASSERT (duration >= MicroSeconds (0));
1655  cts.SetDuration (duration);
1656 
1657  Ptr<Packet> packet = Create<Packet> ();
1658  packet->AddHeader (cts);
1659  WifiMacTrailer fcs;
1660  packet->AddTrailer (fcs);
1661 
1662  SnrTag tag;
1663  tag.Set (rtsSnr);
1664  packet->AddPacketTag (tag);
1665 
1666  WifiPreamble preamble;
1667  if (ctsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1668  preamble= WIFI_PREAMBLE_HT_MF;
1669  else
1670  preamble=WIFI_PREAMBLE_LONG;
1671  ForwardDown (packet, &cts, ctsTxVector,preamble);
1672 }
1673 
1674 void
1676 {
1677  NS_LOG_FUNCTION (this);
1678  /* send the third step in a
1679  * RTS/CTS/DATA/ACK hanshake
1680  */
1681  NS_ASSERT (m_currentPacket != 0);
1683 
1684  WifiPreamble preamble;
1685  if (m_phy->GetGreenfield() && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1686  //In the future has to make sure that receiver has greenfield enabled
1687  preamble= WIFI_PREAMBLE_HT_GF;
1688  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1689  preamble= WIFI_PREAMBLE_HT_MF;
1690  else
1691  preamble=WIFI_PREAMBLE_LONG;
1692 
1693  StartDataTxTimers (dataTxVector);
1694  Time newDuration = Seconds (0);
1695  newDuration += GetSifs ();
1696  newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1698  dataTxVector, preamble);
1699  duration -= txDuration;
1700  duration -= GetSifs ();
1701 
1702  duration = std::max (duration, newDuration);
1703  NS_ASSERT (duration >= MicroSeconds (0));
1704  m_currentHdr.SetDuration (duration);
1705 
1707  WifiMacTrailer fcs;
1708  m_currentPacket->AddTrailer (fcs);
1709 
1710  ForwardDown (m_currentPacket, &m_currentHdr, dataTxVector,preamble);
1711  m_currentPacket = 0;
1712 }
1713 
1714 void
1716 {
1717  m_listener->StartNext ();
1718 }
1719 
1720 void
1722 {
1724  m_listener = 0;
1725  listener->EndTxNoAck ();
1726 }
1727 
1728 void
1730 {
1731  NS_LOG_FUNCTION (this);
1733  m_listener = 0;
1734  listener->MissedAck ();
1735  NS_LOG_DEBUG ("fast Ack busy but missed");
1736 }
1737 
1738 void
1739 MacLow::SendAckAfterData (Mac48Address source, Time duration, WifiMode dataTxMode, double dataSnr)
1740 {
1741  NS_LOG_FUNCTION (this);
1742  /* send an ACK when you receive
1743  * a packet after SIFS.
1744  */
1745  WifiTxVector ackTxVector = GetAckTxVector (source, dataTxMode);
1746  WifiMacHeader ack;
1747  ack.SetType (WIFI_MAC_CTL_ACK);
1748  ack.SetDsNotFrom ();
1749  ack.SetDsNotTo ();
1750  ack.SetNoRetry ();
1751  ack.SetNoMoreFragments ();
1752  ack.SetAddr1 (source);
1753  duration -= GetAckDuration (ackTxVector);
1754  duration -= GetSifs ();
1755  NS_ASSERT (duration >= MicroSeconds (0));
1756  ack.SetDuration (duration);
1757 
1758  Ptr<Packet> packet = Create<Packet> ();
1759  packet->AddHeader (ack);
1760  WifiMacTrailer fcs;
1761  packet->AddTrailer (fcs);
1762 
1763  SnrTag tag;
1764  tag.Set (dataSnr);
1765  packet->AddPacketTag (tag);
1766 
1767  //since ACK is a control response it can't have Fomat =GF
1768  WifiPreamble preamble;
1769  if (ackTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1770  preamble= WIFI_PREAMBLE_HT_MF;
1771  else
1772  preamble=WIFI_PREAMBLE_LONG;
1773  ForwardDown (packet, &ack, ackTxVector, preamble);
1774 }
1775 
1776 bool
1778 {
1779  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1780  if (it != m_bAckAgreements.end ())
1781  {
1782  WifiMacTrailer fcs;
1783  packet->RemoveTrailer (fcs);
1784  BufferedPacket bufferedPacket (packet, hdr);
1785 
1786  uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
1787  uint16_t mappedSeqControl = QosUtilsMapSeqControlToUniqueInteger (hdr.GetSequenceControl (), endSequence);
1788 
1789  BufferedPacketI i = (*it).second.second.begin ();
1790  for (; i != (*it).second.second.end ()
1791  && QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceControl (), endSequence) < mappedSeqControl; i++)
1792  {
1793  ;
1794  }
1795  (*it).second.second.insert (i, bufferedPacket);
1796 
1797  //Update block ack cache
1798  BlockAckCachesI j = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1799  NS_ASSERT (j != m_bAckCaches.end ());
1800  (*j).second.UpdateWithMpdu (&hdr);
1801 
1802  return true;
1803  }
1804  return false;
1805 }
1806 
1807 void
1809  uint16_t startingSeq)
1810 {
1811  uint8_t tid = respHdr->GetTid ();
1812  BlockAckAgreement agreement (originator, tid);
1813  if (respHdr->IsImmediateBlockAck ())
1814  {
1815  agreement.SetImmediateBlockAck ();
1816  }
1817  else
1818  {
1819  agreement.SetDelayedBlockAck ();
1820  }
1821  agreement.SetAmsduSupport (respHdr->IsAmsduSupported ());
1822  agreement.SetBufferSize (respHdr->GetBufferSize () + 1);
1823  agreement.SetTimeout (respHdr->GetTimeout ());
1824  agreement.SetStartingSequence (startingSeq);
1825 
1826  std::list<BufferedPacket> buffer (0);
1827  AgreementKey key (originator, respHdr->GetTid ());
1828  AgreementValue value (agreement, buffer);
1829  m_bAckAgreements.insert (std::make_pair (key, value));
1830 
1831  BlockAckCache cache;
1832  cache.Init (startingSeq, respHdr->GetBufferSize () + 1);
1833  m_bAckCaches.insert (std::make_pair (key, cache));
1834 
1835  if (respHdr->GetTimeout () != 0)
1836  {
1837  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, respHdr->GetTid ()));
1838  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
1839 
1840  AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
1841 
1842  it->second.first.m_inactivityEvent = Simulator::Schedule (timeout,
1844  m_edcaListeners[ac],
1845  originator, tid);
1846  }
1847 }
1848 
1849 void
1851 {
1852  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1853  if (it != m_bAckAgreements.end ())
1854  {
1855  RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (), originator, tid);
1856  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
1857  m_bAckAgreements.erase (it);
1858 
1859  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
1860  NS_ASSERT (i != m_bAckCaches.end ());
1861  m_bAckCaches.erase (i);
1862  }
1863 }
1864 
1865 void
1867 {
1868  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1869  if (it != m_bAckAgreements.end ())
1870  {
1871  uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
1872  uint16_t mappedStart = QosUtilsMapSeqControlToUniqueInteger (seq, endSequence);
1873  uint16_t guard = (*it).second.second.begin ()->second.GetSequenceControl () & 0xfff0;
1874  BufferedPacketI last = (*it).second.second.begin ();
1875 
1876  BufferedPacketI i = (*it).second.second.begin ();
1877  for (; i != (*it).second.second.end ()
1878  && QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceNumber (), endSequence) < mappedStart;)
1879  {
1880  if (guard == (*i).second.GetSequenceControl ())
1881  {
1882  if (!(*i).second.IsMoreFragments ())
1883  {
1884  while (last != i)
1885  {
1886  m_rxCallback ((*last).first, &(*last).second);
1887  last++;
1888  }
1889  m_rxCallback ((*last).first, &(*last).second);
1890  last++;
1891  /* go to next packet */
1892  while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
1893  {
1894  i++;
1895  }
1896  if (i != (*it).second.second.end ())
1897  {
1898  guard = (*i).second.GetSequenceControl () & 0xfff0;
1899  last = i;
1900  }
1901  }
1902  else
1903  {
1904  guard++;
1905  }
1906  }
1907  else
1908  {
1909  /* go to next packet */
1910  while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
1911  {
1912  i++;
1913  }
1914  if (i != (*it).second.second.end ())
1915  {
1916  guard = (*i).second.GetSequenceControl () & 0xfff0;
1917  last = i;
1918  }
1919  }
1920  }
1921  (*it).second.second.erase ((*it).second.second.begin (), i);
1922  }
1923 }
1924 
1925 void
1927 {
1928  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1929  if (it != m_bAckAgreements.end ())
1930  {
1931  uint16_t startingSeqCtrl = ((*it).second.first.GetStartingSequence () << 4) & 0xfff0;
1932  uint16_t guard = startingSeqCtrl;
1933 
1934  BufferedPacketI lastComplete = (*it).second.second.begin ();
1935  BufferedPacketI i = (*it).second.second.begin ();
1936  for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
1937  {
1938  if (!(*i).second.IsMoreFragments ())
1939  {
1940  while (lastComplete != i)
1941  {
1942  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
1943  lastComplete++;
1944  }
1945  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
1946  lastComplete++;
1947  }
1948  guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
1949  }
1950  (*it).second.first.SetStartingSequence ((guard >> 4) & 0x0fff);
1951  /* All packets already forwarded to WifiMac must be removed from buffer:
1952  [begin (), lastComplete) */
1953  (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
1954  }
1955 }
1956 
1957 void
1958 MacLow::SendBlockAckResponse (const CtrlBAckResponseHeader* blockAck, Mac48Address originator, bool immediate,
1959  Time duration, WifiMode blockAckReqTxMode)
1960 {
1961  Ptr<Packet> packet = Create<Packet> ();
1962  packet->AddHeader (*blockAck);
1963 
1964  WifiMacHeader hdr;
1966  hdr.SetAddr1 (originator);
1967  hdr.SetAddr2 (GetAddress ());
1968  hdr.SetDsNotFrom ();
1969  hdr.SetDsNotTo ();
1970  hdr.SetNoRetry ();
1971  hdr.SetNoMoreFragments ();
1972 
1973  WifiTxVector blockAckTxVector = GetBlockAckTxVector (originator, blockAckReqTxMode);
1974  WifiTxVector blockAckReqTxVector;
1975  blockAckReqTxVector.SetMode(blockAckReqTxMode);
1976  blockAckReqTxVector.SetNss(1);
1977  blockAckReqTxVector.SetStbc(false);
1978 
1979  m_currentPacket = packet;
1980  m_currentHdr = hdr;
1981  if (immediate)
1982  {
1984  duration -= GetSifs ();
1985  if (blockAck->IsBasic ())
1986  {
1987  duration -= GetBlockAckDuration (originator, blockAckReqTxVector, BASIC_BLOCK_ACK);
1988  }
1989  else if (blockAck->IsCompressed ())
1990  {
1991  duration -= GetBlockAckDuration (originator, blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1992  }
1993  else if (blockAck->IsMultiTid ())
1994  {
1995  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
1996  }
1997  }
1998  else
1999  {
2000  m_txParams.EnableAck ();
2001  duration += GetSifs ();
2002  duration += GetAckDuration (originator, blockAckReqTxVector);
2003  }
2005 
2006  if (!immediate)
2007  {
2008  StartDataTxTimers (blockAckTxVector);
2009  }
2010 
2011  NS_ASSERT (duration >= MicroSeconds (0));
2012  hdr.SetDuration (duration);
2013  //here should be present a control about immediate or delayed block ack
2014  //for now we assume immediate
2015  packet->AddHeader (hdr);
2016  WifiMacTrailer fcs;
2017  packet->AddTrailer (fcs);
2018  WifiPreamble preamble;
2019  if (blockAckTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
2020  preamble= WIFI_PREAMBLE_HT_MF;
2021  else
2022  preamble=WIFI_PREAMBLE_LONG;
2023  ForwardDown (packet, &hdr, blockAckTxVector,preamble);
2024  m_currentPacket = 0;
2025 }
2026 
2027 void
2029  Time duration, WifiMode blockAckReqTxMode)
2030 {
2031  NS_LOG_FUNCTION (this);
2032  CtrlBAckResponseHeader blockAck;
2033  uint8_t tid;
2034  bool immediate = false;
2035  if (!reqHdr.IsMultiTid ())
2036  {
2037  tid = reqHdr.GetTidInfo ();
2038  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
2039  if (it != m_bAckAgreements.end ())
2040  {
2041  blockAck.SetStartingSequence (reqHdr.GetStartingSequence ());
2042  blockAck.SetTidInfo (tid);
2043  immediate = (*it).second.first.IsImmediateBlockAck ();
2044  if (reqHdr.IsBasic ())
2045  {
2046  blockAck.SetType (BASIC_BLOCK_ACK);
2047  }
2048  else if (reqHdr.IsCompressed ())
2049  {
2050  blockAck.SetType (COMPRESSED_BLOCK_ACK);
2051  }
2052  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
2053  NS_ASSERT (i != m_bAckCaches.end ());
2054  (*i).second.FillBlockAckBitmap (&blockAck);
2055 
2056  /* All packets with smaller sequence than starting sequence control must be passed up to Wifimac
2057  * See 9.10.3 in IEEE8022.11e standard.
2058  */
2060  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
2061  }
2062  else
2063  {
2064  NS_LOG_DEBUG ("there's not a valid block ack agreement with " << originator);
2065  }
2066  }
2067  else
2068  {
2069  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
2070  }
2071 
2072  SendBlockAckResponse (&blockAck, originator, immediate, duration, blockAckReqTxMode);
2073 }
2074 
2075 void
2077 {
2078  if (agreement.GetTimeout () != 0)
2079  {
2080  NS_ASSERT (agreement.m_inactivityEvent.IsRunning ());
2081  agreement.m_inactivityEvent.Cancel ();
2082  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
2083 
2084  AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
2085  //std::map<AcIndex, MacLowTransmissionListener*>::iterator it = m_edcaListeners.find (ac);
2086  //NS_ASSERT (it != m_edcaListeners.end ());
2087 
2088  agreement.m_inactivityEvent = Simulator::Schedule (timeout,
2090  m_edcaListeners[ac],
2091  agreement.GetPeer (),
2092  agreement.GetTid ());
2093  }
2094 }
2095 
2096 void
2098 {
2099  m_edcaListeners.insert (std::make_pair (ac, listener));
2100 }
2101 
2102 } // namespace ns3
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
void Set(double snr)
Set the SNR to the given value.
Definition: snr-tag.cc:83
bool MustSendRts(void) const
Definition: mac-low.cc:183
Time GetPifs(void) const
Return PCF Interframe Space (PIFS) of this MacLow.
Definition: mac-low.cc:548
uint32_t GetAckSize(void) const
Return the total ACK size (including FCS trailer).
Definition: mac-low.cc:937
virtual ~MacLowDcfListener()
Definition: mac-low.cc:64
void SetPifs(Time pifs)
Set PCF Interframe Space (PIFS) of this MacLow.
Definition: mac-low.cc:488
Time m_ctsTimeout
CTS timeout duration.
Definition: mac-low.h:1112
uint16_t GetBufferSize(void) const
Return the buffer size.
Definition: mgt-headers.cc:947
uint8_t GetTid(void) const
Return the Traffic ID (TID).
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:95
EventId m_navCounterResetCtsMissed
Event to reset NAV when CTS is not received.
Definition: mac-low.h:1100
uint32_t GetSize(void) const
Return the size of the WifiMacHeader in octets.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void ResetBlockAckInactivityTimerIfNeeded(BlockAckAgreement &agreement)
Every time that a block ack request or a packet with ack policy equals to block ack are received...
Definition: mac-low.cc:2076
EventId m_blockAckTimeoutEvent
Block ACK timeout event.
Definition: mac-low.h:1093
Time GetBlockAckDuration(Mac48Address to, WifiTxVector blockAckReqTxVector, enum BlockAckType type) const
Definition: mac-low.cc:988
Callback template class.
Definition: callback.h:972
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
virtual ~MacLowTransmissionListener()
Definition: mac-low.cc:49
uint16_t GetTimeout(void) const
Return the timeout.
Time GetAckDuration(WifiTxVector ackTxVector) const
Return the time required to transmit the ACK (including preamble and FCS).
Definition: mac-low.cc:978
virtual void GotAck(double snr, WifiMode txMode)=0
bool IsBasic(void) const
Check if the current ACK policy is basic (i.e.
void SetDuration(Time duration)
Set the Duration/ID field with the given duration (Time object).
void SetPromisc(void)
Enable promiscuous mode.
Definition: mac-low.cc:503
EventId m_waitSifsEvent
Wait for SIFS event.
Definition: mac-low.h:1098
void SendDataAfterCts(Mac48Address source, Time duration, WifiMode txMode)
Send DATA after receiving CTS.
Definition: mac-low.cc:1675
void DoNavResetNow(Time duration)
Reset NAV with the given duration.
Definition: mac-low.cc:1205
bool IsPromisc(void) const
Check if MacLow is operating in promiscuous mode.
Definition: mac-low.cc:558
void EnableBasicBlockAck(void)
Wait BASICBLOCKACKTimeout for a Basic Block Ack Response frame.
Definition: mac-low.cc:108
Mac48Address GetPeer(void) const
Return the peer address.
EventId m_fastAckTimeoutEvent
Fast ACK timeout event.
Definition: mac-low.h:1090
Time m_pifs
PCF Interframe Space (PIFS) duration.
Definition: mac-low.h:1115
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:841
bool DoNavStartNow(Time duration)
Start NAV with the given duration.
Definition: mac-low.cc:1215
void FastAckFailedTimeout(void)
Event handler when fast ACK timeout occurs (busy).
Definition: mac-low.cc:1729
Mac48Address GetBssid(void) const
Return the Basic Service Set Identification.
Definition: mac-low.cc:553
void SetSifs(Time sifs)
Set Short Interframe Space (SIFS) of this MacLow.
Definition: mac-low.cc:478
virtual void MissedAck(void)=0
ns3::MacLow did not receive an expected ACK within AckTimeout.
std::pair< Mac48Address, uint8_t > AgreementKey
Definition: mac-low.h:1131
enum WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:115
WifiTxVector GetCtsToSelfTxVector(Ptr< const Packet > packet, const WifiMacHeader *hdr) const
Return a TXVECTOR for the CTS-to-self frame.
Definition: mac-low.cc:1037
void SetNoMoreFragments(void)
Un-set the More Fragment bit in the Frame Control Field.
bool IsImmediateBlockAck(void) const
Return whether the Block ACK policy is immediate Block ACK.
Definition: mgt-headers.cc:935
void SetupPhyMacLowListener(Ptr< WifiPhy > phy)
Set up WifiPhy listener for this MacLow.
Definition: mac-low.cc:324
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
void Init(uint16_t winStart, uint16_t winSize)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
bool IsMultiTid(void) const
Check if the current ACK policy has multiple TID.
virtual void NotifyRxEndError(void)
We have received the last bit of a packet for which NotifyRxStart was invoked first and...
Definition: mac-low.cc:270
virtual void BlockAckInactivityTimeout(Mac48Address originator, uint8_t tid)=0
Typically is called in order to notify EdcaTxopN that a block ack inactivity timeout occurs for the b...
void SetStbc(bool stbc)
Sets if STBC is being used.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:744
void NotifySleepNow(void)
This method is typically invoked by the PhyMacLowListener to notify the MAC layer that the device has...
Definition: mac-low.cc:663
bool IsCompressed(void) const
Check if the current ACK policy is compressed ACK and not multiple TID.
bool HasDurationId(void) const
Definition: mac-low.cc:188
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:95
DcfListeners m_dcfListeners
List of MacLowDcfListener (pass events to Dcf)
Definition: mac-low.h:1087
bool IsBlockAck(void) const
Return true if the header is a Block ACK header.
bool IsRunning(void) const
This method is syntactic sugar for the ns3::Simulator::isExpired method.
Definition: event-id.cc:59
void SetRxCallback(Callback< void, Ptr< Packet >, const WifiMacHeader * > callback)
Definition: mac-low.cc:564
Time GetCompressedBlockAckTimeout() const
Return Compressed Block ACK timeout of this MacLow.
Definition: mac-low.cc:523
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:825
Mac48Address m_bssid
BSSID address (Mac48Address)
Definition: mac-low.h:1108
bool IsCtl(void) const
Return true if the Type is Control.
ns3::Time timeout
BlockAckType
Enumeration for different block ACK policies.
Definition: ctrl-headers.h:30
EventId m_sendCtsEvent
Event to send CTS.
Definition: mac-low.h:1095
MacLowRxCallback m_rxCallback
Callback to pass packet up.
Definition: mac-low.h:1078
Time GetCtsTimeout(void) const
Return CTS timeout of this MacLow.
Definition: mac-low.cc:528
void SetStartingSequence(uint16_t seq)
Set the starting sequence number from the given raw sequence control field.
EventId m_superFastAckTimeoutEvent
Super fast ACK timeout event.
Definition: mac-low.h:1091
EventId m_sendAckEvent
Event to send ACK.
Definition: mac-low.h:1096
listen to events coming from ns3::MacLow.
Definition: mac-low.h:56
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:91
Time GetCtsDuration(WifiTxVector ctsTxVector) const
Return the time required to transmit the CTS (including preamble and FCS).
Definition: mac-low.cc:1013
bool MustWaitFastAck(void) const
Definition: mac-low.cc:158
virtual void RegisterListener(WifiPhyListener *listener)=0
void SetTidInfo(uint8_t tid)
Set Traffic ID (TID).
control how a packet is transmitted.
Definition: mac-low.h:218
void WaitSifsAfterEndTx(void)
Event handler that is usually scheduled to fired at the appropriate time after completing transmissio...
Definition: mac-low.cc:1715
std::vector< MacLowDcfListener * >::const_iterator DcfListenersCI
typedef for an iterator for a list of MacLowDcfListener.
Definition: mac-low.h:1082
bool IsCfpoll(void) const
Return true if the Type/Subtype is one of the possible CF-Poll headers.
void SetCtsToSelfSupported(bool enable)
Enable or disable CTS-to-self capability.
Definition: mac-low.cc:463
void NormalAckTimeout(void)
Event handler when normal ACK timeout occurs.
Definition: mac-low.cc:1293
void SetBasicBlockAckTimeout(Time blockAckTimeout)
Set Basic Block ACK timeout of this MacLow.
Definition: mac-low.cc:453
bool IsAmsduSupported(void) const
Return whether A-MSDU capability is supported.
Definition: mgt-headers.cc:953
BlockAckCaches m_bAckCaches
Definition: mac-low.h:1141
virtual bool IsStateIdle(void)=0
Time GetDuration(void) const
Return the duration from the Duration/ID field (Time object).
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
Definition: wifi-preamble.h:29
uint8_t GetQosTid(void) const
Return the Traffic ID of a QoS header.
void DestroyBlockAckAgreement(Mac48Address originator, uint8_t tid)
Definition: mac-low.cc:1850
Time m_lastNavDuration
The duration of the latest NAV.
Definition: mac-low.h:1119
virtual uint32_t GetSerializedSize(void) const
std::pair< Ptr< Packet >, WifiMacHeader > BufferedPacket
Definition: mac-low.h:1128
void SendCtsToSelf(void)
Send CTS for a CTS-to-self mechanism.
Definition: mac-low.cc:1554
bool m_ctsToSelfSupported
Definition: mac-low.h:1145
virtual void SetReceiveErrorCallback(RxErrorCallback callback)=0
void SendAckAfterData(Mac48Address source, Time duration, WifiMode dataTxMode, double dataSnr)
Send ACK after receiving DATA.
Definition: mac-low.cc:1739
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
void CreateBlockAckAgreement(const MgtAddBaResponseHeader *respHdr, Mac48Address originator, uint16_t startingSeq)
Definition: mac-low.cc:1808
virtual void NotifyTxStart(Time duration, double txPowerDbm)
Definition: mac-low.cc:273
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
uint32_t GetBlockAckSize(enum BlockAckType type) const
Return the total Block ACK size (including FCS trailer).
Definition: mac-low.cc:944
Listener for PHY events.
Definition: mac-low.cc:249
virtual void NotifyWakeup(void)
Notify listeners that we woke up.
Definition: mac-low.cc:287
receive notifications about phy events.
Definition: wifi-phy.h:44
void CtsTimeout(void)
Event handler when CTS timeout occurs.
Definition: mac-low.cc:1279
virtual void StartNext(void)=0
Invoked when ns3::MacLow wants to start a new transmission as configured by MacLowTransmissionParamet...
uint16_t GetSequenceControl(void) const
Return the raw Sequence Control field.
void EndTxNoAck(void)
A transmission that does not require an ACK has completed.
Definition: mac-low.cc:1721
std::map< AgreementKey, BlockAckCache >::iterator BlockAckCachesI
Definition: mac-low.h:1138
virtual void EndTxNoAck(void)=0
Invoked upon the end of the transmission of a frame that does not require an ACK (e.g., broadcast and multicast frames).
WifiTxVector GetAckTxVector(Mac48Address to, WifiMode dataTxMode) const
Return a TXVECTOR for the ACK frame given the destination and the mode of the DATA used by the sender...
Definition: mac-low.cc:1063
void SetAckTimeout(Time ackTimeout)
Set ACK timeout of this MacLow.
Definition: mac-low.cc:448
virtual void GotCts(double snr, WifiMode txMode)=0
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
Definition: qos-utils.cc:27
void SendBlockAckResponse(const CtrlBAckResponseHeader *blockAck, Mac48Address originator, bool immediate, Time duration, WifiMode blockAckReqTxMode)
This method creates block ack frame with header equals to blockAck and start its transmission.
Definition: mac-low.cc:1958
Time GetRifs(void) const
Return Reduced Interframe Space (RIFS) of this MacLow.
Definition: mac-low.cc:538
HT PHY (Clause 20)
Definition: wifi-mode.h:56
virtual void NotifyRxStart(Time duration)
Definition: mac-low.cc:264
virtual void NotifySleep(void)
Notify listeners that we went to sleep.
Definition: mac-low.cc:283
void NavCounterResetCtsMissed(Time rtsEndRxTime)
Reset NAV after CTS was missed when the NAV was setted with RTS.
Definition: mac-low.cc:1196
Ptr< WifiRemoteStationManager > m_stationManager
Pointer to WifiRemoteStationManager (rate control)
Definition: mac-low.h:1077
bool MustWaitMultiTidBlockAck(void) const
Definition: mac-low.cc:178
bool IsQosBlockAck(void) const
Return if the QoS ACK policy is Block ACK.
Headers for Block ack response.
Definition: ctrl-headers.h:183
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1283
Mac48Address GetAddress(void) const
Return the MAC address of this MacLow.
Definition: mac-low.cc:508
uint32_t GetNextPacketSize(void) const
Definition: mac-low.cc:204
Agreements m_bAckAgreements
Definition: mac-low.h:1140
bool HasNextPacket(void) const
Definition: mac-low.cc:199
WifiTxVector GetAckTxVectorForData(Mac48Address to, WifiMode dataTxMode) const
Return a TXVECTOR for the Block ACK frame given the destination and the mode of the DATA used by the ...
Definition: mac-low.cc:1079
bool IsMgt(void) const
Return true if the Type is Management.
void RegisterDcfListener(MacLowDcfListener *listener)
Definition: mac-low.cc:569
virtual uint32_t GetSerializedSize(void) const
void NotifySwitchingStartNow(Time duration)
Definition: mac-low.cc:647
Time m_slotTime
Slot duration.
Definition: mac-low.h:1114
bool m_promisc
Flag if the device is operating in promiscuous mode.
Definition: mac-low.h:1121
void SetNss(uint8_t nss)
Sets the number of Nss refer to IEEE802.11n Table 20-28 for explanation and range.
void CancelAllEvents(void)
Cancel all scheduled events.
Definition: mac-low.cc:357
void StartTransmission(Ptr< const Packet > packet, const WifiMacHeader *hdr, MacLowTransmissionParameters parameters, MacLowTransmissionListener *listener)
Definition: mac-low.cc:576
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:43
std::list< BufferedPacket >::iterator BufferedPacketI
Definition: mac-low.h:1129
void SetStartingSequence(uint16_t seq)
Set starting sequence number.
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
void BlockAckTimeout(void)
Event handler when block ACK timeout occurs.
Definition: mac-low.cc:1323
void NotifyCtsTimeoutStartNow(Time duration)
Notify DcfManager (via DcfListener) that CTS timer should be started for the given duration...
Definition: mac-low.cc:1248
uint16_t GetStartingSequence(void) const
Return the starting sequence number.
void SendBlockAckAfterBlockAckRequest(const CtrlBAckRequestHeader reqHdr, Mac48Address originator, Time duration, WifiMode blockAckReqTxMode)
Invoked after that a block ack request has been received.
Definition: mac-low.cc:2028
void SetNoRetry(void)
Un-set the Retry bit in the Frame Control field.
void EnableCompressedBlockAck(void)
Wait COMPRESSEDBLOCKACKTimeout for a Compressed Block Ack Response frame.
Definition: mac-low.cc:113
void SuperFastAckTimeout(void)
Event handler when super fast ACK timeout occurs.
Definition: mac-low.cc:1334
void SetBssid(Mac48Address ad)
Set the Basic Service Set Identification.
Definition: mac-low.cc:498
listen for block ack events.
Definition: mac-low.h:190
uint32_t GetRtsSize(void) const
Return the total RTS size (including FCS trailer).
Definition: mac-low.cc:965
bool IsGroup(void) const
void EnableAck(void)
Wait ACKTimeout for an ACK.
Definition: mac-low.cc:128
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
enum ns3::MacLowTransmissionParameters::@90 m_waitAck
Time CalculateTransmissionTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters &parameters) const
Definition: mac-low.cc:1131
EventId m_normalAckTimeoutEvent
Normal ACK timeout event.
Definition: mac-low.h:1089
void SetType(enum BlockAckType type)
Set the block ACK type.
void StartDataTxTimers(WifiTxVector dataTxVector)
Start a DATA timer by scheduling appropriate ACK timeout.
Definition: mac-low.cc:1410
void AddTrailer(const Trailer &trailer)
Add trailer to this packet.
Definition: packet.cc:284
bool IsBasic(void) const
Check if the current ACK policy is basic (i.e.
void NotifyCtsTimeoutResetNow()
Notify DcfManager (via DcfListener) that CTS timer should be resetted.
Definition: mac-low.cc:1256
bool MustWaitBasicBlockAck(void) const
Definition: mac-low.cc:168
bool MustWaitCompressedBlockAck(void) const
Definition: mac-low.cc:173
uint32_t RemoveTrailer(Trailer &trailer)
Remove a deserialized trailer from the internal buffer.
Definition: packet.cc:300
bool NeedCtsToSelf(void)
Check if CTS-to-self mechanism should be used for the current packet.
Definition: mac-low.cc:627
an EUI-48 address
Definition: mac48-address.h:41
virtual ~MacLowBlockAckEventListener()
Definition: mac-low.cc:71
virtual void Cancel(void)=0
Invoked if this transmission was canceled one way or another.
Time m_ackTimeout
ACK timeout duration.
Definition: mac-low.h:1109
listen to NAV eventsThis class is typically connected to an instance of ns3::Dcf and calls to its met...
Definition: mac-low.h:147
void FastAckTimeout(void)
Event handler when fast ACK timeout occurs (idle).
Definition: mac-low.cc:1306
void DisableRts(void)
Do not send rts and wait for cts before sending data.
Definition: mac-low.cc:143
void EnableMultiTidBlockAck(void)
NOT IMPLEMENTED FOR NOW.
Definition: mac-low.cc:118
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
EventId m_ctsTimeoutEvent
CTS timeout event.
Definition: mac-low.h:1094
void RxCompleteBufferedPacketsWithSmallerSequence(uint16_t seq, Mac48Address originator, uint8_t tid)
Definition: mac-low.cc:1866
void SetPhy(Ptr< WifiPhy > phy)
Set up WifiPhy associated with this MacLow.
Definition: mac-low.cc:429
virtual bool IsStateTx(void)=0
Time m_basicBlockAckTimeout
Basic block ACK timeout duration.
Definition: mac-low.h:1110
Time GetDurationId(void) const
Definition: mac-low.cc:193
uint16_t GetTimeout(void) const
Return the timeout.
Definition: mgt-headers.cc:941
uint8_t GetTid(void) const
Return the Traffic ID (TID).
Definition: mgt-headers.cc:929
virtual void MissedBlockAck(void)
ns3::MacLow did not receive an expected BLOCK_ACK within BlockAckTimeout.
Definition: mac-low.cc:58
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
Time m_sifs
Short Interframe Space (SIFS) duration.
Definition: mac-low.h:1113
const char * GetTypeString(void) const
Return a string corresponds to the header type.
void ReceiveError(Ptr< const Packet > packet, double rxSnr)
Definition: mac-low.cc:633
Time GetSlotTime(void) const
Return slot duration of this MacLow.
Definition: mac-low.cc:543
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void SetDelayedBlockAck(void)
Set Block ACK policy to delayed ACK.
Time m_lastNavStart
The time when the latest NAV started.
Definition: mac-low.h:1118
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support.
virtual void NotifyMaybeCcaBusyStart(Time duration)
Definition: mac-low.cc:276
WifiTxVector GetRtsTxVector(Ptr< const Packet > packet, const WifiMacHeader *hdr) const
Return a TXVECTOR for the RTS frame given the destination.
Definition: mac-low.cc:1043
virtual WifiTxVector GetDataTxVector(Ptr< const Packet > packet, const WifiMacHeader *hdr) const
Return a TXVECTOR for the DATA frame given the destination.
Definition: mac-low.cc:1049
handle RTS/CTS/DATA/ACK transactions.
Definition: mac-low.h:411
virtual void MissedCts(void)=0
ns3::MacLow did not receive an expected CTS within CtsTimeout.
EventId m_sendDataEvent
Event to send DATA.
Definition: mac-low.h:1097
static Time CalculateTxDuration(uint32_t size, WifiTxVector txvector, enum WifiPreamble preamble)
Definition: wifi-phy.cc:439
MacLowTransmissionParameters m_txParams
Transmission parameters of the current packet.
Definition: mac-low.h:1105
void SetRifs(Time rifs)
Set Reduced Interframe Space (RIFS) of this MacLow.
Definition: mac-low.cc:493
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: mac-low.cc:332
void NotifyAckTimeoutResetNow()
Notify DcfManager (via DcfListener) that ACK timer should be resetted.
Definition: mac-low.cc:1240
bool MustWaitSuperFastAck(void) const
Definition: mac-low.cc:163
Time CalculateOverallTxTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters &params) const
Definition: mac-low.cc:1086
QueueListeners m_edcaListeners
Definition: mac-low.h:1144
WifiTxVector GetBlockAckTxVector(Mac48Address to, WifiMode dataTxMode) const
Return a TXVECTOR for the Block ACK frame given the destination and the mode of the DATA used by the ...
Definition: mac-low.cc:1068
bool IsData(void) const
Return true if the Type is DATA.
Mac48Address m_self
Address of this MacLow (Mac48Address)
Definition: mac-low.h:1107
Maintains information for a block ack agreement.
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS DATA...
EventId m_fastAckFailedTimeoutEvent
Fast ACK failed timeout event.
Definition: mac-low.h:1092
uint32_t QosUtilsMapSeqControlToUniqueInteger(uint16_t seqControl, uint16_t endSequence)
Next function is useful to correctly sort buffered packets under block ack.
Definition: qos-utils.cc:75
bool IsNavZero(void) const
Check if NAV is zero.
Definition: mac-low.cc:1542
void EnableRts(void)
Send a RTS, and wait CTSTimeout for a CTS.
Definition: mac-low.cc:138
void NotifyAckTimeoutStartNow(Time duration)
Notify DcfManager (via DcfListener) that ACK timer should be started for the given duration...
Definition: mac-low.cc:1232
bool IsBlockAckReq(void) const
Return true if the header is a Block ACK Request header.
void SetSlotTime(Time slotTime)
Set slot duration of this MacLow.
Definition: mac-low.cc:483
Ptr< Packet > m_currentPacket
Current packet transmitted/to be transmitted.
Definition: mac-low.h:1103
Time GetSifs(void) const
Return Short Interframe Space (SIFS) of this MacLow.
Definition: mac-low.cc:533
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:848
Implement the header for management frames of type add block ack response.
Definition: mgt-headers.h:582
void SendCtsAfterRts(Mac48Address source, Time duration, WifiMode txMode, double rtsSnr)
Send CTS after receiving RTS.
Definition: mac-low.cc:1638
ns3::MacLow * m_macLow
Definition: mac-low.cc:291
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:213
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:845
std::map< AgreementKey, AgreementValue >::iterator AgreementsI
Definition: mac-low.h:1135
EventId m_endTxNoAckEvent
Event for finishing transmission that does not require ACK.
Definition: mac-low.h:1099
virtual void SendPacket(Ptr< const Packet > packet, WifiTxVector txvector, enum WifiPreamble preamble)=0
virtual void GotBlockAck(const CtrlBAckResponseHeader *blockAck, Mac48Address source)
Definition: mac-low.cc:53
void EnableOverrideDurationId(Time durationId)
Definition: mac-low.cc:93
virtual void SetReceiveOkCallback(RxOkCallback callback)=0
bool GetCtsToSelfSupported() const
Return whether CTS-to-self capability is supported.
Definition: mac-low.cc:468
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::cancel method.
Definition: event-id.cc:47
void SetCtsTimeout(Time ctsTimeout)
Set CTS timeout of this MacLow.
Definition: mac-low.cc:473
void EnableNextData(uint32_t size)
Definition: mac-low.cc:83
void SetImmediateBlockAck(void)
Set Block ACK policy to immediate ACK.
void DisableOverrideDurationId(void)
Do not force the duration/id field of the packet: its value is automatically calculated by the MacLow...
Definition: mac-low.cc:98
Time GetAckTimeout(void) const
Return ACK timeout of this MacLow.
Definition: mac-low.cc:513
EventId m_waitRifsEvent
Wait for RIFS event.
Definition: mac-low.h:1101
void DisableNextData(void)
Do not attempt to send data burst after current transmission.
Definition: mac-low.cc:88
void SendDataPacket(void)
Send DATA packet, which can be DATA-ACK or RTS-CTS-DATA-ACK transaction.
Definition: mac-low.cc:1480
void SetTimeout(uint16_t timeout)
Set timeout.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:861
uint32_t GetCtsSize(void) const
Return the total CTS size (including FCS trailer).
Definition: mac-low.cc:1023
WifiMacHeader m_currentHdr
Header of the current packet.
Definition: mac-low.h:1104
void SetType(enum WifiMacType type)
Set Type/Subtype values with the correct values depending on the given type.
void SetAddress(Mac48Address ad)
Set MAC address of this MacLow.
Definition: mac-low.cc:443
bool IsCts(void) const
Return true if the header is a CTS header.
bool IsCompressed(void) const
Check if the current ACK policy is compressed ACK and not multiple TID.
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
void ForwardDown(Ptr< const Packet > packet, const WifiMacHeader *hdr, WifiTxVector txVector, WifiPreamble preamble)
Forward the packet down to WifiPhy for transmission.
Definition: mac-low.cc:1265
void ReceiveOk(Ptr< Packet > packet, double rxSnr, WifiMode txMode, WifiPreamble preamble)
Definition: mac-low.cc:679
PhyMacLowListener(ns3::MacLow *macLow)
Create a PhyMacLowListener for the given MacLow.
Definition: mac-low.cc:257
Time m_compressedBlockAckTimeout
Compressed block ACK timeout duration.
Definition: mac-low.h:1111
WifiMode GetMode(void) const
bool MustWaitAck(void) const
Definition: mac-low.cc:148
bool IsRts(void) const
Return true if the header is a RTS header.
Headers for Block ack request.
Definition: ctrl-headers.h:49
bool IsAck(void) const
Return true if the header is an ACK header.
void RegisterBlockAckListenerForAc(enum AcIndex ac, MacLowBlockAckEventListener *listener)
Definition: mac-low.cc:2097
virtual ~PhyMacLowListener()
Definition: mac-low.cc:261
void DisableAck(void)
Do not wait for Ack after data transmission.
Definition: mac-low.cc:133
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::isExpired method.
Definition: event-id.cc:53
std::pair< BlockAckAgreement, std::list< BufferedPacket > > AgreementValue
Definition: mac-low.h:1132
virtual void NotifySwitchingStart(Time duration)
Definition: mac-low.cc:279
virtual Time GetLastRxStartTime(void) const =0
Return the start time of the last received packet.
WifiTxVector GetCtsTxVectorForRts(Mac48Address to, WifiMode rtsTxMode) const
Return a TXVECTOR for the CTS frame given the destination and the mode of the RTS used by the sender...
Definition: mac-low.cc:1074
void SetBufferSize(uint16_t bufferSize)
Set buffer size.
Time GetBasicBlockAckTimeout() const
Return Basic Block ACK timeout of this MacLow.
Definition: mac-low.cc:518
void NotifyNav(Ptr< const Packet > packet, const WifiMacHeader &hdr, WifiMode txMode, WifiPreamble preamble)
Definition: mac-low.cc:1154
bool IsMultiTid(void) const
Check if the current ACK policy has multiple TID.
Time m_rifs
Reduced Interframe Space (RIFS) duration.
Definition: mac-low.h:1116
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:35
WifiTxVector GetCtsTxVector(Mac48Address to, WifiMode rtsTxMode) const
Return a TXVECTOR for the CTS frame given the destination and the mode of the RTS used by the sender...
Definition: mac-low.cc:1058
Doxygen introspection did not find any typical Config paths.
Definition: snr-tag.h:34
bool StoreMpduIfNeeded(Ptr< Packet > packet, WifiMacHeader hdr)
Definition: mac-low.cc:1777
bool MustWaitNormalAck(void) const
Definition: mac-low.cc:153
virtual bool GetGreenfield(void) const =0
virtual ~MacLow()
Definition: mac-low.cc:318
Ptr< WifiPhy > m_phy
Pointer to WifiPhy (actually send/receives frames)
Definition: mac-low.h:1076
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
Implements the IEEE 802.11 MAC header.
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
bool IsQosNoAck(void) const
Return if the QoS ACK policy is No ACK.
void SetCompressedBlockAckTimeout(Time blockAckTimeout)
Set Compressed Block ACK timeout of this MacLow.
Definition: mac-low.cc:458
Implements the IEEE 802.11 MAC trailer.
virtual void NotifyRxEndOk(void)
We have received the last bit of a packet for which NotifyRxStart was invoked first and...
Definition: mac-low.cc:267
void SetWifiRemoteStationManager(Ptr< WifiRemoteStationManager > manager)
Set up WifiRemoteStationManager associated with this MacLow.
Definition: mac-low.cc:437
bool IsQosAck(void) const
Return if the QoS ACK policy is Normal ACK.
class PhyMacLowListener * m_phyMacLowListener
Listerner needed to monitor when a channel switching occurs.
Definition: mac-low.h:1123
virtual uint32_t GetSerializedSize(void) const
uint32_t GetSize(Ptr< const Packet > packet, const WifiMacHeader *hdr) const
Return the total size of the packet after WifiMacHeader and FCS trailer have been added...
Definition: mac-low.cc:1030
MacLowTransmissionListener * m_listener
Transmission listener for the current packet.
Definition: mac-low.h:1106
void SetDsNotFrom(void)
Un-set the From DS bit in the Frame Control field.
void SendRtsForPacket(void)
Send RTS to begin RTS-CTS-DATA-ACK transaction.
Definition: mac-low.cc:1353
void RxCompleteBufferedPacketsUntilFirstLost(Mac48Address originator, uint8_t tid)
Definition: mac-low.cc:1926