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 
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)
274  {
275  }
276  virtual void NotifyMaybeCcaBusyStart (Time duration)
277  {
278  }
279  virtual void NotifySwitchingStart (Time duration)
280  {
281  m_macLow->NotifySwitchingStartNow (duration);
282  }
283 private:
285 };
286 
287 
289  : m_normalAckTimeoutEvent (),
290  m_fastAckTimeoutEvent (),
291  m_superFastAckTimeoutEvent (),
292  m_fastAckFailedTimeoutEvent (),
293  m_blockAckTimeoutEvent (),
294  m_ctsTimeoutEvent (),
295  m_sendCtsEvent (),
296  m_sendAckEvent (),
297  m_sendDataEvent (),
298  m_waitSifsEvent (),
299  m_endTxNoAckEvent (),
300  m_currentPacket (0),
301  m_listener (0),
302  m_phyMacLowListener (0),
303  m_ctsToSelfSupported (false)
304 {
305  NS_LOG_FUNCTION (this);
306  m_lastNavDuration = Seconds (0);
307  m_lastNavStart = Seconds (0);
308  m_promisc = false;
309 }
310 
312 {
313  NS_LOG_FUNCTION (this);
314 }
315 
316 void
318 {
321 }
322 
323 
324 void
326 {
327  NS_LOG_FUNCTION (this);
340  m_phy = 0;
341  m_stationManager = 0;
342  if (m_phyMacLowListener != 0)
343  {
344  delete m_phyMacLowListener;
346  }
347 }
348 
349 void
351 {
352  NS_LOG_FUNCTION (this);
353  bool oneRunning = false;
355  {
357  oneRunning = true;
358  }
360  {
362  oneRunning = true;
363  }
365  {
367  oneRunning = true;
368  }
370  {
372  oneRunning = true;
373  }
375  {
377  oneRunning = true;
378  }
380  {
382  oneRunning = true;
383  }
384  if (m_sendCtsEvent.IsRunning ())
385  {
387  oneRunning = true;
388  }
389  if (m_sendAckEvent.IsRunning ())
390  {
392  oneRunning = true;
393  }
394  if (m_sendDataEvent.IsRunning ())
395  {
397  oneRunning = true;
398  }
399  if (m_waitSifsEvent.IsRunning ())
400  {
402  oneRunning = true;
403  }
404  if (m_waitRifsEvent.IsRunning ())
405  {
407  oneRunning = true;
408  }
410  {
412  oneRunning = true;
413  }
414  if (oneRunning && m_listener != 0)
415  {
416  m_listener->Cancel ();
417  m_listener = 0;
418  }
419 }
420 
421 void
423 {
424  m_phy = phy;
428 }
429 void
431 {
432  m_stationManager = manager;
433 }
434 
435 void
437 {
438  m_self = ad;
439 }
440 void
442 {
443  m_ackTimeout = ackTimeout;
444 }
445 void
447 {
448  m_basicBlockAckTimeout = blockAckTimeout;
449 }
450 void
452 {
453  m_compressedBlockAckTimeout = blockAckTimeout;
454 }
455 void
457 {
458  m_ctsToSelfSupported = enable;
459 }
460 bool
462 {
463  return m_ctsToSelfSupported;
464 }
465 void
467 {
468  m_ctsTimeout = ctsTimeout;
469 }
470 void
472 {
473  m_sifs = sifs;
474 }
475 void
477 {
478  m_slotTime = slotTime;
479 }
480 void
482 {
483  m_pifs = pifs;
484 }
485 void
487 {
488  m_rifs = rifs;
489 }
490 void
492 {
493  m_bssid = bssid;
494 }
495 void
497 {
498  m_promisc = true;
499 }
501 MacLow::GetAddress (void) const
502 {
503  return m_self;
504 }
505 Time
507 {
508  return m_ackTimeout;
509 }
510 Time
512 {
513  return m_basicBlockAckTimeout;
514 }
515 Time
517 {
519 }
520 Time
522 {
523  return m_ctsTimeout;
524 }
525 Time
526 MacLow::GetSifs (void) const
527 {
528  return m_sifs;
529 }
530 Time
531 MacLow::GetRifs (void) const
532 {
533  return m_rifs;
534 }
535 Time
537 {
538  return m_slotTime;
539 }
540 Time
541 MacLow::GetPifs (void) const
542 {
543  return m_pifs;
544 }
546 MacLow::GetBssid (void) const
547 {
548  return m_bssid;
549 }
550 bool
551 MacLow::IsPromisc (void) const
552 {
553  return m_promisc;
554 }
555 
556 void
558 {
559  m_rxCallback = callback;
560 }
561 void
563 {
564  m_dcfListeners.push_back (listener);
565 }
566 
567 
568 void
570  const WifiMacHeader* hdr,
572  MacLowTransmissionListener *listener)
573 {
574  NS_LOG_FUNCTION (this << packet << hdr << params << listener);
575  /* m_currentPacket is not NULL because someone started
576  * a transmission and was interrupted before one of:
577  * - ctsTimeout
578  * - sendDataAfterCTS
579  * expired. This means that one of these timers is still
580  * running. They are all cancelled below anyway by the
581  * call to CancelAllEvents (because of at least one
582  * of these two timer) which will trigger a call to the
583  * previous listener's cancel method.
584  *
585  * This typically happens because the high-priority
586  * QapScheduler has taken access to the channel from
587  * one of the Edca of the QAP.
588  */
589  m_currentPacket = packet->Copy ();
590  m_currentHdr = *hdr;
591  CancelAllEvents ();
592  m_listener = listener;
593  m_txParams = params;
594 
595  //NS_ASSERT (m_phy->IsStateIdle ());
596 
597  NS_LOG_DEBUG ("startTx size=" << GetSize (m_currentPacket, &m_currentHdr) <<
598  ", to=" << m_currentHdr.GetAddr1 () << ", listener=" << m_listener);
599 
600  if (m_txParams.MustSendRts ())
601  {
602  SendRtsForPacket ();
603  }
604  else
605  {
607  {
608  SendCtsToSelf();
609  }
610  else
611  {
612  SendDataPacket ();
613  }
614  }
615 
616  /* When this method completes, we have taken ownership of the medium. */
617  NS_ASSERT (m_phy->IsStateTx ());
618 }
619 bool
621 {
623  return m_stationManager->NeedCtsToSelf (dataTxVector);
624 }
625 void
627 {
628  NS_LOG_FUNCTION (this << packet << rxSnr);
629  NS_LOG_DEBUG ("rx failed ");
631  {
635  }
636  return;
637 }
638 
639 void
641 {
642  NS_LOG_DEBUG ("switching channel. Cancelling MAC pending events");
643  m_stationManager->Reset ();
644  CancelAllEvents ();
646  {
648  }
650  m_lastNavDuration = Seconds (0);
651  m_currentPacket = 0;
652  m_listener = 0;
653 }
654 
655 void
656 MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamble preamble)
657 {
658  NS_LOG_FUNCTION (this << packet << rxSnr << txMode << preamble);
659  /* A packet is received from the PHY.
660  * When we have handled this packet,
661  * we handle any packet present in the
662  * packet queue.
663  */
664  WifiMacHeader hdr;
665  packet->RemoveHeader (hdr);
666 
667  bool isPrevNavZero = IsNavZero ();
668  NS_LOG_DEBUG ("duration/id=" << hdr.GetDuration ());
669  NotifyNav (packet,hdr, txMode, preamble);
670  if (hdr.IsRts ())
671  {
672  /* see section 9.2.5.7 802.11-1999
673  * A STA that is addressed by an RTS frame shall transmit a CTS frame after a SIFS
674  * period if the NAV at the STA receiving the RTS frame indicates that the medium is
675  * idle. If the NAV at the STA receiving the RTS indicates the medium is not idle,
676  * that STA shall not respond to the RTS frame.
677  */
678  if (isPrevNavZero
679  && hdr.GetAddr1 () == m_self)
680  {
681  NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
683  m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
684  rxSnr, txMode);
687  hdr.GetAddr2 (),
688  hdr.GetDuration (),
689  txMode,
690  rxSnr);
691  }
692  else
693  {
694  NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
695  }
696  }
697  else if (hdr.IsCts ()
698  && hdr.GetAddr1 () == m_self
700  && m_currentPacket != 0)
701  {
702  NS_LOG_DEBUG ("receive cts from=" << m_currentHdr.GetAddr1 ());
703  SnrTag tag;
704  packet->RemovePacketTag (tag);
706  rxSnr, txMode);
708  rxSnr, txMode, tag.Get ());
709 
712  m_listener->GotCts (rxSnr, txMode);
716  hdr.GetAddr1 (),
717  hdr.GetDuration (),
718  txMode);
719  }
720  else if (hdr.IsAck ()
721  && hdr.GetAddr1 () == m_self
725  && m_txParams.MustWaitAck ())
726  {
727  NS_LOG_DEBUG ("receive ack from=" << m_currentHdr.GetAddr1 ());
728  SnrTag tag;
729  packet->RemovePacketTag (tag);
731  rxSnr, txMode);
733  rxSnr, txMode, tag.Get ());
734  bool gotAck = false;
737  {
740  gotAck = true;
741  }
744  {
747  gotAck = true;
748  }
749  if (gotAck)
750  {
751  m_listener->GotAck (rxSnr, txMode);
752  }
753  if (m_txParams.HasNextPacket ())
754  {
757  }
758  }
759  else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self
762  {
763  NS_LOG_DEBUG ("got block ack from " << hdr.GetAddr2 ());
764  CtrlBAckResponseHeader blockAck;
765  packet->RemoveHeader (blockAck);
767  m_listener->GotBlockAck (&blockAck, hdr.GetAddr2 ());
768  }
769  else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
770  {
771  CtrlBAckRequestHeader blockAckReq;
772  packet->RemoveHeader (blockAckReq);
773  if (!blockAckReq.IsMultiTid ())
774  {
775  uint8_t tid = blockAckReq.GetTidInfo ();
776  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), tid));
777  if (it != m_bAckAgreements.end ())
778  {
779  //Update block ack cache
780  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), tid));
781  NS_ASSERT (i != m_bAckCaches.end ());
782  (*i).second.UpdateWithBlockAckReq (blockAckReq.GetStartingSequence ());
783 
785  /* See section 11.5.3 in IEEE802.11 for mean of this timer */
786  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
787  if ((*it).second.first.IsImmediateBlockAck ())
788  {
789  NS_LOG_DEBUG ("rx blockAckRequest/sendImmediateBlockAck from=" << hdr.GetAddr2 ());
792  blockAckReq,
793  hdr.GetAddr2 (),
794  hdr.GetDuration (),
795  txMode);
796  }
797  else
798  {
799  NS_FATAL_ERROR ("Delayed block ack not supported.");
800  }
801  }
802  else
803  {
804  NS_LOG_DEBUG ("There's not a valid agreement for this block ack request.");
805  }
806  }
807  else
808  {
809  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
810  }
811  }
812  else if (hdr.IsCtl ())
813  {
814  NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ());
815  }
816  else if (hdr.GetAddr1 () == m_self)
817  {
818  m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
819  rxSnr, txMode);
820 
821  if (hdr.IsQosData () && StoreMpduIfNeeded (packet, hdr))
822  {
823  /* From section 9.10.4 in IEEE802.11:
824  Upon the receipt of a QoS data frame from the originator for which
825  the Block Ack agreement exists, the recipient shall buffer the MSDU
826  regardless of the value of the Ack Policy subfield within the
827  QoS Control field of the QoS data frame. */
828  if (hdr.IsQosAck ())
829  {
830  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
831  RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (),
832  hdr.GetAddr2 (), hdr.GetQosTid ());
837  hdr.GetAddr2 (),
838  hdr.GetDuration (),
839  txMode,
840  rxSnr);
841  }
842  else if (hdr.IsQosBlockAck ())
843  {
844  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
845  /* See section 11.5.3 in IEEE802.11 for mean of this timer */
846  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
847  }
848  return;
849  }
850  else if (hdr.IsQosData () && hdr.IsQosBlockAck ())
851  {
852  /* This happens if a packet with ack policy Block Ack is received and a block ack
853  agreement for that packet doesn't exist.
854 
855  From section 11.5.3 in IEEE802.11e:
856  When a recipient does not have an active Block ack for a TID, but receives
857  data MPDUs with the Ack Policy subfield set to Block Ack, it shall discard
858  them and shall send a DELBA frame using the normal access
859  mechanisms. */
860  AcIndex ac = QosUtilsMapTidToAc (hdr.GetQosTid ());
861  m_edcaListeners[ac]->BlockAckInactivityTimeout (hdr.GetAddr2 (), hdr.GetQosTid ());
862  return;
863  }
864  else if (hdr.IsQosData () && hdr.IsQosNoAck ())
865  {
866  NS_LOG_DEBUG ("rx unicast/noAck from=" << hdr.GetAddr2 ());
867  }
868  else if (hdr.IsData () || hdr.IsMgt ())
869  {
870  NS_LOG_DEBUG ("rx unicast/sendAck from=" << hdr.GetAddr2 ());
874  hdr.GetAddr2 (),
875  hdr.GetDuration (),
876  txMode,
877  rxSnr);
878  }
879  goto rxPacket;
880  }
881  else if (hdr.GetAddr1 ().IsGroup ())
882  {
883  if (hdr.IsData () || hdr.IsMgt ())
884  {
885  NS_LOG_DEBUG ("rx group from=" << hdr.GetAddr2 ());
886  goto rxPacket;
887  }
888  else
889  {
890  // DROP
891  }
892  }
893  else if (m_promisc)
894  {
895  NS_ASSERT (hdr.GetAddr1 () != m_self);
896  if (hdr.IsData ())
897  {
898  goto rxPacket;
899  }
900  }
901  else
902  {
903  //NS_LOG_DEBUG_VERBOSE ("rx not-for-me from %d", GetSource (packet));
904  }
905  return;
906 rxPacket:
907  WifiMacTrailer fcs;
908  packet->RemoveTrailer (fcs);
909  m_rxCallback (packet, &hdr);
910  return;
911 }
912 
913 uint32_t
914 MacLow::GetAckSize (void) const
915 {
916  WifiMacHeader ack;
918  return ack.GetSize () + 4;
919 }
920 uint32_t
922 {
923  WifiMacHeader hdr;
925  CtrlBAckResponseHeader blockAck;
926  if (type == BASIC_BLOCK_ACK)
927  {
928  blockAck.SetType (BASIC_BLOCK_ACK);
929  }
930  else if (type == COMPRESSED_BLOCK_ACK)
931  {
932  blockAck.SetType (COMPRESSED_BLOCK_ACK);
933  }
934  else if (type == MULTI_TID_BLOCK_ACK)
935  {
936  //Not implemented
937  NS_ASSERT (false);
938  }
939  return hdr.GetSize () + blockAck.GetSerializedSize () + 4;
940 }
941 uint32_t
942 MacLow::GetRtsSize (void) const
943 {
944  WifiMacHeader rts;
946  return rts.GetSize () + 4;
947 }
948 Time
950 {
951  WifiTxVector ackTxVector = GetAckTxVectorForData (to, dataTxVector.GetMode());
952  return GetAckDuration (ackTxVector);
953 }
954 Time
956 {
957  WifiPreamble preamble;
958  if (ackTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
959  preamble= WIFI_PREAMBLE_HT_MF;
960  else
961  preamble=WIFI_PREAMBLE_LONG;
962  return m_phy->CalculateTxDuration (GetAckSize (), ackTxVector, preamble);
963 }
964 Time
965 MacLow::GetBlockAckDuration (Mac48Address to, WifiTxVector blockAckReqTxVector, enum BlockAckType type) const
966 {
967  /*
968  * For immediate BlockAck we should transmit the frame with the same WifiMode
969  * as the BlockAckReq.
970  *
971  * from section 9.6 in IEEE802.11e:
972  * The BlockAck control frame shall be sent at the same rate and modulation class as
973  * the BlockAckReq frame if it is sent in response to a BlockAckReq frame.
974  */
975  WifiPreamble preamble;
976  if (blockAckReqTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
977  preamble= WIFI_PREAMBLE_HT_MF;
978  else
979  preamble=WIFI_PREAMBLE_LONG;
980  return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxVector, preamble);
981 }
982 Time
984 {
985  WifiTxVector ctsTxVector = GetCtsTxVectorForRts (to, rtsTxVector.GetMode());
986  return GetCtsDuration (ctsTxVector);
987 }
988 
989 Time
991 {
992  WifiPreamble preamble;
993  if (ctsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
994  preamble= WIFI_PREAMBLE_HT_MF;
995  else
996  preamble=WIFI_PREAMBLE_LONG;
997  return m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble);
998 }
999 uint32_t
1001 {
1002  WifiMacHeader cts;
1003  cts.SetType (WIFI_MAC_CTL_CTS);
1004  return cts.GetSize () + 4;
1005 }
1006 uint32_t
1008 {
1009  WifiMacTrailer fcs;
1010  return packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
1011 }
1012 
1015 {
1016  return m_stationManager->GetCtsToSelfTxVector (hdr, packet);
1017 }
1018 
1021 {
1022  Mac48Address to = hdr->GetAddr1 ();
1023  return m_stationManager->GetRtsTxVector (to, hdr, packet);
1024 }
1027 {
1028  Mac48Address to = hdr->GetAddr1 ();
1029  WifiMacTrailer fcs;
1030  uint32_t size = packet->GetSize ()+ hdr->GetSize () + fcs.GetSerializedSize ();
1031  //size is not used in anything!! will not worry about aggregation
1032  return m_stationManager->GetDataTxVector (to, hdr, packet, size);
1033 }
1036 {
1037  return m_stationManager->GetCtsTxVector (to, rtsTxMode);
1038 }
1041 {
1042  return m_stationManager->GetAckTxVector (to, dataTxMode);
1043 }
1046 {
1047  return m_stationManager->GetBlockAckTxVector (to, dataTxMode);
1048 }
1049 
1052 {
1053  return GetCtsTxVector (to, rtsTxMode);
1054 }
1057 {
1058  return GetAckTxVector (to, dataTxMode);
1059 }
1060 
1061 
1062 Time
1064  const WifiMacHeader* hdr,
1065  const MacLowTransmissionParameters& params) const
1066 {
1067  WifiPreamble preamble;
1068  Time txTime = Seconds (0);
1069  if (params.MustSendRts ())
1070  {
1071  WifiTxVector rtsTxVector = GetRtsTxVector (packet, hdr);
1072  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
1073  if (m_phy->GetGreenfield () && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1074  {
1075  preamble = WIFI_PREAMBLE_HT_GF;
1076  }
1077  else if (rtsTxVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HT)
1078  {
1079  preamble = WIFI_PREAMBLE_HT_MF;
1080  }
1081  else
1082  {
1083  preamble = WIFI_PREAMBLE_LONG;
1084  }
1085  txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble);
1086  txTime += GetCtsDuration (hdr->GetAddr1 (), rtsTxVector);
1087  txTime += Time (GetSifs () * 2);
1088  }
1089  WifiTxVector dataTxVector = GetDataTxVector (packet, hdr);
1090  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
1091  if ( m_phy->GetGreenfield()&& m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1092  preamble= WIFI_PREAMBLE_HT_GF;
1093  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1094  preamble= WIFI_PREAMBLE_HT_MF;
1095  else
1096  preamble=WIFI_PREAMBLE_LONG;
1097  uint32_t dataSize = GetSize (packet, hdr);
1098  txTime += m_phy->CalculateTxDuration (dataSize, dataTxVector, preamble);
1099  if (params.MustWaitAck ())
1100  {
1101  txTime += GetSifs ();
1102  txTime += GetAckDuration (hdr->GetAddr1 (), dataTxVector);
1103  }
1104  return txTime;
1105 }
1106 
1107 Time
1109  const WifiMacHeader* hdr,
1110  const MacLowTransmissionParameters& params) const
1111 {
1112  Time txTime = CalculateOverallTxTime (packet, hdr, params);
1113  if (params.HasNextPacket ())
1114  {
1115  WifiTxVector dataTxVector = GetDataTxVector (packet, hdr);
1116  WifiPreamble preamble;
1117  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
1118  if ( m_phy->GetGreenfield()&& m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1119  preamble= WIFI_PREAMBLE_HT_GF;
1120  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1121  preamble= WIFI_PREAMBLE_HT_MF;
1122  else
1123  preamble=WIFI_PREAMBLE_LONG;
1124  txTime += GetSifs ();
1125  txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataTxVector, preamble);
1126  }
1127  return txTime;
1128 }
1129 
1130 void
1132 {
1134  Time duration = hdr.GetDuration ();
1135 
1136  if (hdr.IsCfpoll ()
1137  && hdr.GetAddr2 () == m_bssid)
1138  {
1139  // see section 9.3.2.2 802.11-1999
1140  DoNavResetNow (duration);
1141  return;
1142  }
1145  else if (hdr.GetAddr1 () != m_self)
1146  {
1147  // see section 9.2.5.4 802.11-1999
1148  bool navUpdated = DoNavStartNow (duration);
1149  if (hdr.IsRts () && navUpdated)
1150  {
1159  WifiMacHeader cts;
1160  cts.SetType (WIFI_MAC_CTL_CTS);
1161  WifiTxVector txVector=GetRtsTxVector (packet, &hdr);
1162  Time navCounterResetCtsMissedDelay =
1163  m_phy->CalculateTxDuration (cts.GetSerializedSize (), txVector, preamble) +
1164  Time (2 * GetSifs ()) + Time (2 * GetSlotTime ());
1165  m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay,
1167  Simulator::Now ());
1168  }
1169  }
1170 }
1171 
1172 void
1174 {
1175  if (m_phy->GetLastRxStartTime () < rtsEndRxTime)
1176  {
1177  DoNavResetNow (Seconds (0.0));
1178  }
1179 }
1180 
1181 void
1183 {
1184  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1185  {
1186  (*i)->NavReset (duration);
1187  }
1189  m_lastNavStart = duration;
1190 }
1191 bool
1193 {
1194  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1195  {
1196  (*i)->NavStart (duration);
1197  }
1198  Time newNavEnd = Simulator::Now () + duration;
1199  Time oldNavEnd = m_lastNavStart + m_lastNavDuration;
1200  if (newNavEnd > oldNavEnd)
1201  {
1203  m_lastNavDuration = duration;
1204  return true;
1205  }
1206  return false;
1207 }
1208 void
1210 {
1211  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1212  {
1213  (*i)->AckTimeoutStart (duration);
1214  }
1215 }
1216 void
1218 {
1219  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1220  {
1221  (*i)->AckTimeoutReset ();
1222  }
1223 }
1224 void
1226 {
1227  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1228  {
1229  (*i)->CtsTimeoutStart (duration);
1230  }
1231 }
1232 void
1234 {
1235  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1236  {
1237  (*i)->CtsTimeoutReset ();
1238  }
1239 }
1240 
1241 void
1243  WifiTxVector txVector, WifiPreamble preamble)
1244 {
1245  NS_LOG_FUNCTION (this << packet << hdr << txVector);
1246  NS_LOG_DEBUG ("send " << hdr->GetTypeString () <<
1247  ", to=" << hdr->GetAddr1 () <<
1248  ", size=" << packet->GetSize () <<
1249  ", mode=" << txVector.GetMode() <<
1250  ", duration=" << hdr->GetDuration () <<
1251  ", seq=0x" << std::hex << m_currentHdr.GetSequenceControl () << std::dec);
1252  m_phy->SendPacket (packet, txVector.GetMode(), preamble, txVector);
1253 }
1254 
1255 void
1257 {
1258  NS_LOG_FUNCTION (this);
1259  NS_LOG_DEBUG ("cts timeout");
1263  m_stationManager->ReportRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1264  m_currentPacket = 0;
1266  m_listener = 0;
1267  listener->MissedCts ();
1268 }
1269 void
1271 {
1272  NS_LOG_FUNCTION (this);
1273  NS_LOG_DEBUG ("normal ack timeout");
1277  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1279  m_listener = 0;
1280  listener->MissedAck ();
1281 }
1282 void
1284 {
1285  NS_LOG_FUNCTION (this);
1286  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1288  m_listener = 0;
1289  if (m_phy->IsStateIdle ())
1290  {
1291  NS_LOG_DEBUG ("fast Ack idle missed");
1292  listener->MissedAck ();
1293  }
1294  else
1295  {
1296  NS_LOG_DEBUG ("fast Ack ok");
1297  }
1298 }
1299 void
1301 {
1302  NS_LOG_FUNCTION (this);
1303  NS_LOG_DEBUG ("block ack timeout");
1304 
1305  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1307  m_listener = 0;
1308  listener->MissedBlockAck ();
1309 }
1310 void
1312 {
1313  NS_LOG_FUNCTION (this);
1314  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1316  m_listener = 0;
1317  if (m_phy->IsStateIdle ())
1318  {
1319  NS_LOG_DEBUG ("super fast Ack failed");
1320  listener->MissedAck ();
1321  }
1322  else
1323  {
1324  NS_LOG_DEBUG ("super fast Ack ok");
1325  listener->GotAck (0.0, WifiMode ());
1326  }
1327 }
1328 
1329 void
1331 {
1332  NS_LOG_FUNCTION (this);
1333  /* send an RTS for this packet. */
1334  WifiMacHeader rts;
1335  rts.SetType (WIFI_MAC_CTL_RTS);
1336  rts.SetDsNotFrom ();
1337  rts.SetDsNotTo ();
1338  rts.SetNoRetry ();
1339  rts.SetNoMoreFragments ();
1340  rts.SetAddr1 (m_currentHdr.GetAddr1 ());
1341  rts.SetAddr2 (m_self);
1343  Time duration = Seconds (0);
1344 
1345  WifiPreamble preamble;
1346  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
1347  if ( m_phy->GetGreenfield()&& m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1348  preamble= WIFI_PREAMBLE_HT_GF;
1349  else if (rtsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1350  preamble= WIFI_PREAMBLE_HT_MF;
1351  else
1352  preamble=WIFI_PREAMBLE_LONG;
1353 
1354  if (m_txParams.HasDurationId ())
1355  {
1356  duration += m_txParams.GetDurationId ();
1357  }
1358  else
1359  {
1361  duration += GetSifs ();
1362  duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxVector);
1363  duration += GetSifs ();
1365  dataTxVector, preamble);
1366  duration += GetSifs ();
1367  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1368  }
1369  rts.SetDuration (duration);
1370 
1371  Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble);
1372  Time timerDelay = txDuration + GetCtsTimeout ();
1373 
1375  NotifyCtsTimeoutStartNow (timerDelay);
1377 
1378  Ptr<Packet> packet = Create<Packet> ();
1379  packet->AddHeader (rts);
1380  WifiMacTrailer fcs;
1381  packet->AddTrailer (fcs);
1382 
1383  ForwardDown (packet, &rts, rtsTxVector,preamble);
1384 }
1385 
1386 void
1388 {
1389  WifiPreamble preamble;
1390 
1391  //Since it is data then it can have format = GF
1392  if (m_phy->GetGreenfield() && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1393  preamble= WIFI_PREAMBLE_HT_GF;
1394  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1395  preamble= WIFI_PREAMBLE_HT_MF;
1396  else
1397  preamble=WIFI_PREAMBLE_LONG;
1398 
1399  Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxVector, preamble);
1401  {
1402  Time timerDelay = txDuration + GetAckTimeout ();
1404  NotifyAckTimeoutStartNow (timerDelay);
1406  }
1407  else if (m_txParams.MustWaitFastAck ())
1408  {
1409  Time timerDelay = txDuration + GetPifs ();
1411  NotifyAckTimeoutStartNow (timerDelay);
1413  }
1414  else if (m_txParams.MustWaitSuperFastAck ())
1415  {
1416  Time timerDelay = txDuration + GetPifs ();
1418  NotifyAckTimeoutStartNow (timerDelay);
1421  }
1422  else if (m_txParams.MustWaitBasicBlockAck ())
1423  {
1424  Time timerDelay = txDuration + GetBasicBlockAckTimeout ();
1427  }
1429  {
1430  Time timerDelay = txDuration + GetCompressedBlockAckTimeout ();
1433  }
1434  else if (m_txParams.HasNextPacket ())
1435  {
1436  if (m_stationManager->HasHtSupported())
1437  {
1438  Time delay = txDuration + GetRifs ();
1441  }
1442  else
1443  {
1444  Time delay = txDuration + GetSifs ();
1447  }
1448  }
1449  else
1450  {
1451  // since we do not expect any timer to be triggered.
1452  Simulator::Schedule(txDuration, &MacLow::EndTxNoAck, this);
1453  }
1454 }
1455 
1456 void
1458 {
1459  NS_LOG_FUNCTION (this);
1460  /* send this packet directly. No RTS is needed. */
1462  WifiPreamble preamble;
1463 
1464  if (m_phy->GetGreenfield() && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1465  //In the future has to make sure that receiver has greenfield enabled
1466  preamble= WIFI_PREAMBLE_HT_GF;
1467  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1468  preamble= WIFI_PREAMBLE_HT_MF;
1469  else
1470  preamble=WIFI_PREAMBLE_LONG;
1471 
1472  StartDataTxTimers (dataTxVector);
1473 
1474  Time duration = Seconds (0.0);
1475  if (m_txParams.HasDurationId ())
1476  {
1477  duration += m_txParams.GetDurationId ();
1478  }
1479  else
1480  {
1482  {
1483  duration += GetSifs ();
1484  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, BASIC_BLOCK_ACK);
1485  }
1487  {
1488  duration += GetSifs ();
1489  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, COMPRESSED_BLOCK_ACK);
1490  }
1491  else if (m_txParams.MustWaitAck ())
1492  {
1493  duration += GetSifs ();
1494  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1495  }
1496  if (m_txParams.HasNextPacket ())
1497  {
1498  duration += GetSifs ();
1500  dataTxVector, preamble);
1501  if (m_txParams.MustWaitAck ())
1502  {
1503  duration += GetSifs ();
1504  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1505  }
1506  }
1507  }
1508  m_currentHdr.SetDuration (duration);
1509 
1511  WifiMacTrailer fcs;
1512  m_currentPacket->AddTrailer (fcs);
1513 
1514  ForwardDown (m_currentPacket, &m_currentHdr, dataTxVector,preamble);
1515  m_currentPacket = 0;
1516 }
1517 
1518 bool
1519 MacLow::IsNavZero (void) const
1520 {
1522  {
1523  return true;
1524  }
1525  else
1526  {
1527  return false;
1528  }
1529 }
1530 void
1532 {
1533  WifiMacHeader cts;
1534  cts.SetType (WIFI_MAC_CTL_CTS);
1535  cts.SetDsNotFrom ();
1536  cts.SetDsNotTo ();
1537  cts.SetNoMoreFragments ();
1538  cts.SetNoRetry ();
1539  cts.SetAddr1 (m_self);
1540 
1542 
1543  WifiPreamble preamble;
1544  if (ctsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1545  preamble= WIFI_PREAMBLE_HT_MF;
1546  else
1547  preamble=WIFI_PREAMBLE_LONG;
1548 
1549  Time duration = Seconds (0);
1550 
1551  if (m_txParams.HasDurationId ())
1552  {
1553  duration += m_txParams.GetDurationId ();
1554  }
1555  else
1556  {
1558  duration += GetSifs ();
1560  dataTxVector, preamble);
1562  {
1563 
1564  duration += GetSifs ();
1565  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, BASIC_BLOCK_ACK);
1566  }
1568  {
1569  duration += GetSifs ();
1570  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, COMPRESSED_BLOCK_ACK);
1571  }
1572  else if (m_txParams.MustWaitAck ())
1573  {
1574  duration += GetSifs ();
1575  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1576  }
1577  if (m_txParams.HasNextPacket ())
1578  {
1579  duration += GetSifs ();
1581  dataTxVector, preamble);
1583  {
1584  duration += GetSifs ();
1585  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, COMPRESSED_BLOCK_ACK);
1586  }
1587  else if (m_txParams.MustWaitAck ())
1588  {
1589  duration += GetSifs ();
1590  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1591  }
1592  }
1593  }
1594 
1595  cts.SetDuration (duration);
1596 
1597  Ptr<Packet> packet = Create<Packet> ();
1598  packet->AddHeader (cts);
1599  WifiMacTrailer fcs;
1600  packet->AddTrailer (fcs);
1601 
1602  ForwardDown (packet, &cts, ctsTxVector,preamble);
1603 
1604  Time txDuration = m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble);
1605  txDuration += GetSifs ();
1607 
1608  m_sendDataEvent = Simulator::Schedule (txDuration,
1609  &MacLow::SendDataAfterCts, this,
1610  cts.GetAddr1 (),
1611  duration,
1612  ctsTxVector.GetMode());
1613 }
1614 void
1615 MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode rtsTxMode, double rtsSnr)
1616 {
1617  NS_LOG_FUNCTION (this << source << duration << rtsTxMode << rtsSnr);
1618  /* send a CTS when you receive a RTS
1619  * right after SIFS.
1620  */
1621  WifiTxVector ctsTxVector = GetCtsTxVector (source, rtsTxMode);
1622  WifiMacHeader cts;
1623  cts.SetType (WIFI_MAC_CTL_CTS);
1624  cts.SetDsNotFrom ();
1625  cts.SetDsNotTo ();
1626  cts.SetNoMoreFragments ();
1627  cts.SetNoRetry ();
1628  cts.SetAddr1 (source);
1629  duration -= GetCtsDuration (source, ctsTxVector);
1630  duration -= GetSifs ();
1631  NS_ASSERT (duration >= MicroSeconds (0));
1632  cts.SetDuration (duration);
1633 
1634  Ptr<Packet> packet = Create<Packet> ();
1635  packet->AddHeader (cts);
1636  WifiMacTrailer fcs;
1637  packet->AddTrailer (fcs);
1638 
1639  SnrTag tag;
1640  tag.Set (rtsSnr);
1641  packet->AddPacketTag (tag);
1642 
1643  WifiPreamble preamble;
1644  if (ctsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1645  preamble= WIFI_PREAMBLE_HT_MF;
1646  else
1647  preamble=WIFI_PREAMBLE_LONG;
1648  ForwardDown (packet, &cts, ctsTxVector,preamble);
1649 }
1650 
1651 void
1653 {
1654  NS_LOG_FUNCTION (this);
1655  /* send the third step in a
1656  * RTS/CTS/DATA/ACK hanshake
1657  */
1658  NS_ASSERT (m_currentPacket != 0);
1660 
1661  WifiPreamble preamble;
1662  if (m_phy->GetGreenfield() && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1663  //In the future has to make sure that receiver has greenfield enabled
1664  preamble= WIFI_PREAMBLE_HT_GF;
1665  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1666  preamble= WIFI_PREAMBLE_HT_MF;
1667  else
1668  preamble=WIFI_PREAMBLE_LONG;
1669 
1670  StartDataTxTimers (dataTxVector);
1671  Time newDuration = Seconds (0);
1672  newDuration += GetSifs ();
1673  newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1675  dataTxVector, preamble);
1676  duration -= txDuration;
1677  duration -= GetSifs ();
1678 
1679  duration = std::max (duration, newDuration);
1680  NS_ASSERT (duration >= MicroSeconds (0));
1681  m_currentHdr.SetDuration (duration);
1682 
1684  WifiMacTrailer fcs;
1685  m_currentPacket->AddTrailer (fcs);
1686 
1687  ForwardDown (m_currentPacket, &m_currentHdr, dataTxVector,preamble);
1688  m_currentPacket = 0;
1689 }
1690 
1691 void
1693 {
1694  m_listener->StartNext ();
1695 }
1696 
1697 void
1699 {
1701  m_listener = 0;
1702  listener->EndTxNoAck ();
1703 }
1704 
1705 void
1707 {
1708  NS_LOG_FUNCTION (this);
1710  m_listener = 0;
1711  listener->MissedAck ();
1712  NS_LOG_DEBUG ("fast Ack busy but missed");
1713 }
1714 
1715 void
1716 MacLow::SendAckAfterData (Mac48Address source, Time duration, WifiMode dataTxMode, double dataSnr)
1717 {
1718  NS_LOG_FUNCTION (this);
1719  /* send an ACK when you receive
1720  * a packet after SIFS.
1721  */
1722  WifiTxVector ackTxVector = GetAckTxVector (source, dataTxMode);
1723  WifiMacHeader ack;
1724  ack.SetType (WIFI_MAC_CTL_ACK);
1725  ack.SetDsNotFrom ();
1726  ack.SetDsNotTo ();
1727  ack.SetNoRetry ();
1728  ack.SetNoMoreFragments ();
1729  ack.SetAddr1 (source);
1730  duration -= GetAckDuration (ackTxVector);
1731  duration -= GetSifs ();
1732  NS_ASSERT (duration >= MicroSeconds (0));
1733  ack.SetDuration (duration);
1734 
1735  Ptr<Packet> packet = Create<Packet> ();
1736  packet->AddHeader (ack);
1737  WifiMacTrailer fcs;
1738  packet->AddTrailer (fcs);
1739 
1740  SnrTag tag;
1741  tag.Set (dataSnr);
1742  packet->AddPacketTag (tag);
1743 
1744  //since ACK is a control response it can't have Fomat =GF
1745  WifiPreamble preamble;
1746  if (ackTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1747  preamble= WIFI_PREAMBLE_HT_MF;
1748  else
1749  preamble=WIFI_PREAMBLE_LONG;
1750  ForwardDown (packet, &ack, ackTxVector, preamble);
1751 }
1752 
1753 bool
1755 {
1756  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1757  if (it != m_bAckAgreements.end ())
1758  {
1759  WifiMacTrailer fcs;
1760  packet->RemoveTrailer (fcs);
1761  BufferedPacket bufferedPacket (packet, hdr);
1762 
1763  uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
1764  uint16_t mappedSeqControl = QosUtilsMapSeqControlToUniqueInteger (hdr.GetSequenceControl (), endSequence);
1765 
1766  BufferedPacketI i = (*it).second.second.begin ();
1767  for (; i != (*it).second.second.end ()
1768  && QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceControl (), endSequence) < mappedSeqControl; i++)
1769  {
1770  ;
1771  }
1772  (*it).second.second.insert (i, bufferedPacket);
1773 
1774  //Update block ack cache
1775  BlockAckCachesI j = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1776  NS_ASSERT (j != m_bAckCaches.end ());
1777  (*j).second.UpdateWithMpdu (&hdr);
1778 
1779  return true;
1780  }
1781  return false;
1782 }
1783 
1784 void
1786  uint16_t startingSeq)
1787 {
1788  uint8_t tid = respHdr->GetTid ();
1789  BlockAckAgreement agreement (originator, tid);
1790  if (respHdr->IsImmediateBlockAck ())
1791  {
1792  agreement.SetImmediateBlockAck ();
1793  }
1794  else
1795  {
1796  agreement.SetDelayedBlockAck ();
1797  }
1798  agreement.SetAmsduSupport (respHdr->IsAmsduSupported ());
1799  agreement.SetBufferSize (respHdr->GetBufferSize () + 1);
1800  agreement.SetTimeout (respHdr->GetTimeout ());
1801  agreement.SetStartingSequence (startingSeq);
1802 
1803  std::list<BufferedPacket> buffer (0);
1804  AgreementKey key (originator, respHdr->GetTid ());
1805  AgreementValue value (agreement, buffer);
1806  m_bAckAgreements.insert (std::make_pair (key, value));
1807 
1808  BlockAckCache cache;
1809  cache.Init (startingSeq, respHdr->GetBufferSize () + 1);
1810  m_bAckCaches.insert (std::make_pair (key, cache));
1811 
1812  if (respHdr->GetTimeout () != 0)
1813  {
1814  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, respHdr->GetTid ()));
1815  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
1816 
1817  AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
1818 
1819  it->second.first.m_inactivityEvent = Simulator::Schedule (timeout,
1821  m_edcaListeners[ac],
1822  originator, tid);
1823  }
1824 }
1825 
1826 void
1828 {
1829  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1830  if (it != m_bAckAgreements.end ())
1831  {
1832  RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (), originator, tid);
1833  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
1834  m_bAckAgreements.erase (it);
1835 
1836  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
1837  NS_ASSERT (i != m_bAckCaches.end ());
1838  m_bAckCaches.erase (i);
1839  }
1840 }
1841 
1842 void
1844 {
1845  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1846  if (it != m_bAckAgreements.end ())
1847  {
1848  uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
1849  uint16_t mappedStart = QosUtilsMapSeqControlToUniqueInteger (seq, endSequence);
1850  uint16_t guard = (*it).second.second.begin ()->second.GetSequenceControl () & 0xfff0;
1851  BufferedPacketI last = (*it).second.second.begin ();
1852 
1853  BufferedPacketI i = (*it).second.second.begin ();
1854  for (; i != (*it).second.second.end ()
1855  && QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceNumber (), endSequence) < mappedStart;)
1856  {
1857  if (guard == (*i).second.GetSequenceControl ())
1858  {
1859  if (!(*i).second.IsMoreFragments ())
1860  {
1861  while (last != i)
1862  {
1863  m_rxCallback ((*last).first, &(*last).second);
1864  last++;
1865  }
1866  m_rxCallback ((*last).first, &(*last).second);
1867  last++;
1868  /* go to next packet */
1869  while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
1870  {
1871  i++;
1872  }
1873  if (i != (*it).second.second.end ())
1874  {
1875  guard = (*i).second.GetSequenceControl () & 0xfff0;
1876  last = i;
1877  }
1878  }
1879  else
1880  {
1881  guard++;
1882  }
1883  }
1884  else
1885  {
1886  /* go to next packet */
1887  while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
1888  {
1889  i++;
1890  }
1891  if (i != (*it).second.second.end ())
1892  {
1893  guard = (*i).second.GetSequenceControl () & 0xfff0;
1894  last = i;
1895  }
1896  }
1897  }
1898  (*it).second.second.erase ((*it).second.second.begin (), i);
1899  }
1900 }
1901 
1902 void
1904 {
1905  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1906  if (it != m_bAckAgreements.end ())
1907  {
1908  uint16_t startingSeqCtrl = ((*it).second.first.GetStartingSequence () << 4) & 0xfff0;
1909  uint16_t guard = startingSeqCtrl;
1910 
1911  BufferedPacketI lastComplete = (*it).second.second.begin ();
1912  BufferedPacketI i = (*it).second.second.begin ();
1913  for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
1914  {
1915  if (!(*i).second.IsMoreFragments ())
1916  {
1917  while (lastComplete != i)
1918  {
1919  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
1920  lastComplete++;
1921  }
1922  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
1923  lastComplete++;
1924  }
1925  guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
1926  }
1927  (*it).second.first.SetStartingSequence ((guard >> 4) & 0x0fff);
1928  /* All packets already forwarded to WifiMac must be removed from buffer:
1929  [begin (), lastComplete) */
1930  (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
1931  }
1932 }
1933 
1934 void
1935 MacLow::SendBlockAckResponse (const CtrlBAckResponseHeader* blockAck, Mac48Address originator, bool immediate,
1936  Time duration, WifiMode blockAckReqTxMode)
1937 {
1938  Ptr<Packet> packet = Create<Packet> ();
1939  packet->AddHeader (*blockAck);
1940 
1941  WifiMacHeader hdr;
1943  hdr.SetAddr1 (originator);
1944  hdr.SetAddr2 (GetAddress ());
1945  hdr.SetDsNotFrom ();
1946  hdr.SetDsNotTo ();
1947  hdr.SetNoRetry ();
1948  hdr.SetNoMoreFragments ();
1949 
1950  WifiTxVector blockAckTxVector = GetBlockAckTxVector (originator, blockAckReqTxMode);
1951  WifiTxVector blockAckReqTxVector;
1952  blockAckReqTxVector.SetMode(blockAckReqTxMode);
1953  blockAckReqTxVector.SetNss(1);
1954  blockAckReqTxVector.SetStbc(false);
1955 
1956  m_currentPacket = packet;
1957  m_currentHdr = hdr;
1958  if (immediate)
1959  {
1961  duration -= GetSifs ();
1962  if (blockAck->IsBasic ())
1963  {
1964  duration -= GetBlockAckDuration (originator, blockAckReqTxVector, BASIC_BLOCK_ACK);
1965  }
1966  else if (blockAck->IsCompressed ())
1967  {
1968  duration -= GetBlockAckDuration (originator, blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1969  }
1970  else if (blockAck->IsMultiTid ())
1971  {
1972  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
1973  }
1974  }
1975  else
1976  {
1977  m_txParams.EnableAck ();
1978  duration += GetSifs ();
1979  duration += GetAckDuration (originator, blockAckReqTxVector);
1980  }
1982 
1983  if (!immediate)
1984  {
1985  StartDataTxTimers (blockAckTxVector);
1986  }
1987 
1988  NS_ASSERT (duration >= MicroSeconds (0));
1989  hdr.SetDuration (duration);
1990  //here should be present a control about immediate or delayed block ack
1991  //for now we assume immediate
1992  packet->AddHeader (hdr);
1993  WifiMacTrailer fcs;
1994  packet->AddTrailer (fcs);
1995  WifiPreamble preamble;
1996  if (blockAckTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1997  preamble= WIFI_PREAMBLE_HT_MF;
1998  else
1999  preamble=WIFI_PREAMBLE_LONG;
2000  ForwardDown (packet, &hdr, blockAckTxVector,preamble);
2001  m_currentPacket = 0;
2002 }
2003 
2004 void
2006  Time duration, WifiMode blockAckReqTxMode)
2007 {
2008  NS_LOG_FUNCTION (this);
2009  CtrlBAckResponseHeader blockAck;
2010  uint8_t tid;
2011  bool immediate = false;
2012  if (!reqHdr.IsMultiTid ())
2013  {
2014  tid = reqHdr.GetTidInfo ();
2015  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
2016  if (it != m_bAckAgreements.end ())
2017  {
2018  blockAck.SetStartingSequence (reqHdr.GetStartingSequence ());
2019  blockAck.SetTidInfo (tid);
2020  immediate = (*it).second.first.IsImmediateBlockAck ();
2021  if (reqHdr.IsBasic ())
2022  {
2023  blockAck.SetType (BASIC_BLOCK_ACK);
2024  }
2025  else if (reqHdr.IsCompressed ())
2026  {
2027  blockAck.SetType (COMPRESSED_BLOCK_ACK);
2028  }
2029  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
2030  NS_ASSERT (i != m_bAckCaches.end ());
2031  (*i).second.FillBlockAckBitmap (&blockAck);
2032 
2033  /* All packets with smaller sequence than starting sequence control must be passed up to Wifimac
2034  * See 9.10.3 in IEEE8022.11e standard.
2035  */
2037  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
2038  }
2039  else
2040  {
2041  NS_LOG_DEBUG ("there's not a valid block ack agreement with " << originator);
2042  }
2043  }
2044  else
2045  {
2046  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
2047  }
2048 
2049  SendBlockAckResponse (&blockAck, originator, immediate, duration, blockAckReqTxMode);
2050 }
2051 
2052 void
2054 {
2055  if (agreement.GetTimeout () != 0)
2056  {
2057  NS_ASSERT (agreement.m_inactivityEvent.IsRunning ());
2058  agreement.m_inactivityEvent.Cancel ();
2059  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
2060 
2061  AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
2062  //std::map<AcIndex, MacLowTransmissionListener*>::iterator it = m_edcaListeners.find (ac);
2063  //NS_ASSERT (it != m_edcaListeners.end ());
2064 
2065  agreement.m_inactivityEvent = Simulator::Schedule (timeout,
2067  m_edcaListeners[ac],
2068  agreement.GetPeer (),
2069  agreement.GetTid ());
2070  }
2071 }
2072 
2073 void
2075 {
2076  m_edcaListeners.insert (std::make_pair (ac, listener));
2077 }
2078 
2079 } // 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:541
uint32_t GetAckSize(void) const
Return the total ACK size (including FCS trailer).
Definition: mac-low.cc:914
virtual ~MacLowDcfListener()
Definition: mac-low.cc:64
void SetPifs(Time pifs)
Set PCF Interframe Space (PIFS) of this MacLow.
Definition: mac-low.cc:481
Time m_ctsTimeout
CTS timeout duration.
Definition: mac-low.h:1106
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:79
EventId m_navCounterResetCtsMissed
Event to reset NAV when CTS is not received.
Definition: mac-low.h:1094
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:2053
enum ns3::MacLowTransmissionParameters::@89 m_waitAck
EventId m_blockAckTimeoutEvent
Block ACK timeout event.
Definition: mac-low.h:1087
Time GetBlockAckDuration(Mac48Address to, WifiTxVector blockAckReqTxVector, enum BlockAckType type) const
Definition: mac-low.cc:965
Callback template class.
Definition: callback.h:924
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:955
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:496
EventId m_waitSifsEvent
Wait for SIFS event.
Definition: mac-low.h:1092
void SendDataAfterCts(Mac48Address source, Time duration, WifiMode txMode)
Send DATA after receiving CTS.
Definition: mac-low.cc:1652
void DoNavResetNow(Time duration)
Reset NAV with the given duration.
Definition: mac-low.cc:1182
bool IsPromisc(void) const
Check if MacLow is operating in promiscuous mode.
Definition: mac-low.cc:551
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:1084
Time m_pifs
PCF Interframe Space (PIFS) duration.
Definition: mac-low.h:1109
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:1192
void FastAckFailedTimeout(void)
Event handler when fast ACK timeout occurs (busy).
Definition: mac-low.cc:1706
Mac48Address GetBssid(void) const
Return the Basic Service Set Identification.
Definition: mac-low.cc:546
void SetSifs(Time sifs)
Set Short Interframe Space (SIFS) of this MacLow.
Definition: mac-low.cc:471
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:1125
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:1014
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:317
#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
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:1081
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:557
Time GetCompressedBlockAckTimeout() const
Return Compressed Block ACK timeout of this MacLow.
Definition: mac-low.cc:516
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:1102
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:1089
MacLowRxCallback m_rxCallback
Callback to pass packet up.
Definition: mac-low.h:1072
Time GetCtsTimeout(void) const
Return CTS timeout of this MacLow.
Definition: mac-low.cc:521
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:1085
EventId m_sendAckEvent
Event to send ACK.
Definition: mac-low.h:1090
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:990
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:1692
std::vector< MacLowDcfListener * >::const_iterator DcfListenersCI
typedef for an iterator for a list of MacLowDcfListener.
Definition: mac-low.h:1076
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:456
void NormalAckTimeout(void)
Event handler when normal ACK timeout occurs.
Definition: mac-low.cc:1270
void SetBasicBlockAckTimeout(Time blockAckTimeout)
Set Basic Block ACK timeout of this MacLow.
Definition: mac-low.cc:446
bool IsAmsduSupported(void) const
Return whether A-MSDU capability is supported.
Definition: mgt-headers.cc:953
BlockAckCaches m_bAckCaches
Definition: mac-low.h:1135
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:1827
Time m_lastNavDuration
The duration of the latest NAV.
Definition: mac-low.h:1113
virtual uint32_t GetSerializedSize(void) const
std::pair< Ptr< Packet >, WifiMacHeader > BufferedPacket
Definition: mac-low.h:1122
void SendCtsToSelf(void)
Send CTS for a CTS-to-self mechanism.
Definition: mac-low.cc:1531
bool m_ctsToSelfSupported
Definition: mac-low.h:1139
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:1716
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:1785
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:921
Listener for PHY events.
Definition: mac-low.cc:249
receive notifications about phy events.
Definition: wifi-phy.h:44
void CtsTimeout(void)
Event handler when CTS timeout occurs.
Definition: mac-low.cc:1256
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:1698
std::map< AgreementKey, BlockAckCache >::iterator BlockAckCachesI
Definition: mac-low.h:1132
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:1040
void SetAckTimeout(Time ackTimeout)
Set ACK timeout of this MacLow.
Definition: mac-low.cc:441
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:1935
Time GetRifs(void) const
Return Reduced Interframe Space (RIFS) of this MacLow.
Definition: mac-low.cc:531
HT PHY (Clause 20)
Definition: wifi-mode.h:56
virtual void NotifyRxStart(Time duration)
Definition: mac-low.cc:264
void NavCounterResetCtsMissed(Time rtsEndRxTime)
Reset NAV after CTS was missed when the NAV was setted with RTS.
Definition: mac-low.cc:1173
Ptr< WifiRemoteStationManager > m_stationManager
Pointer to WifiRemoteStationManager (rate control)
Definition: mac-low.h:1071
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:1242
Mac48Address GetAddress(void) const
Return the MAC address of this MacLow.
Definition: mac-low.cc:501
uint32_t GetNextPacketSize(void) const
Definition: mac-low.cc:204
Agreements m_bAckAgreements
Definition: mac-low.h:1134
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:1056
bool IsMgt(void) const
Return true if the Type is Management.
void RegisterDcfListener(MacLowDcfListener *listener)
Definition: mac-low.cc:562
virtual uint32_t GetSerializedSize(void) const
void NotifySwitchingStartNow(Time duration)
Definition: mac-low.cc:640
Time m_slotTime
Slot duration.
Definition: mac-low.h:1108
bool m_promisc
Flag if the device is operating in promiscuous mode.
Definition: mac-low.h:1115
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:350
void StartTransmission(Ptr< const Packet > packet, const WifiMacHeader *hdr, MacLowTransmissionParameters parameters, MacLowTransmissionListener *listener)
Definition: mac-low.cc:569
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:1123
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:1300
void NotifyCtsTimeoutStartNow(Time duration)
Notify DcfManager (via DcfListener) that CTS timer should be started for the given duration...
Definition: mac-low.cc:1225
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:2005
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:1311
void SetBssid(Mac48Address ad)
Set the Basic Service Set Identification.
Definition: mac-low.cc:491
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:942
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.
Time CalculateTransmissionTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters &parameters) const
Definition: mac-low.cc:1108
EventId m_normalAckTimeoutEvent
Normal ACK timeout event.
Definition: mac-low.h:1083
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:1387
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:1233
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:620
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:1103
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:1283
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:1088
void RxCompleteBufferedPacketsWithSmallerSequence(uint16_t seq, Mac48Address originator, uint8_t tid)
Definition: mac-low.cc:1843
void SetPhy(Ptr< WifiPhy > phy)
Set up WifiPhy associated with this MacLow.
Definition: mac-low.cc:422
virtual bool IsStateTx(void)=0
Time m_basicBlockAckTimeout
Basic block ACK timeout duration.
Definition: mac-low.h:1104
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:1107
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:626
Time GetSlotTime(void) const
Return slot duration of this MacLow.
Definition: mac-low.cc:536
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:1112
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:1020
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:1026
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:1091
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:1099
void SetRifs(Time rifs)
Set Reduced Interframe Space (RIFS) of this MacLow.
Definition: mac-low.cc:486
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: mac-low.cc:325
void NotifyAckTimeoutResetNow()
Notify DcfManager (via DcfListener) that ACK timer should be resetted.
Definition: mac-low.cc:1217
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:1063
QueueListeners m_edcaListeners
Definition: mac-low.h:1138
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:1045
bool IsData(void) const
Return true if the Type is DATA.
Mac48Address m_self
Address of this MacLow (Mac48Address)
Definition: mac-low.h:1101
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:1086
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:1519
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:1209
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:476
Ptr< Packet > m_currentPacket
Current packet transmitted/to be transmitted.
Definition: mac-low.h:1097
Time GetSifs(void) const
Return Short Interframe Space (SIFS) of this MacLow.
Definition: mac-low.cc:526
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:1615
ns3::MacLow * m_macLow
Definition: mac-low.cc:284
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:213
std::map< AgreementKey, AgreementValue >::iterator AgreementsI
Definition: mac-low.h:1129
EventId m_endTxNoAckEvent
Event for finishing transmission that does not require ACK.
Definition: mac-low.h:1093
virtual void NotifyTxStart(Time duration)
Definition: mac-low.cc:273
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:461
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:466
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:506
EventId m_waitRifsEvent
Wait for RIFS event.
Definition: mac-low.h:1095
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:1457
void SetTimeout(uint16_t timeout)
Set timeout.
uint32_t GetCtsSize(void) const
Return the total CTS size (including FCS trailer).
Definition: mac-low.cc:1000
WifiMacHeader m_currentHdr
Header of the current packet.
Definition: mac-low.h:1098
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:436
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.
virtual void SendPacket(Ptr< const Packet > packet, WifiMode mode, enum WifiPreamble preamble, WifiTxVector txvector)=0
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:1242
void ReceiveOk(Ptr< Packet > packet, double rxSnr, WifiMode txMode, WifiPreamble preamble)
Definition: mac-low.cc:656
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:1105
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:2074
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:1126
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:1051
void SetBufferSize(uint16_t bufferSize)
Set buffer size.
Time GetBasicBlockAckTimeout() const
Return Basic Block ACK timeout of this MacLow.
Definition: mac-low.cc:511
void NotifyNav(Ptr< const Packet > packet, const WifiMacHeader &hdr, WifiMode txMode, WifiPreamble preamble)
Definition: mac-low.cc:1131
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:1110
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:1035
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:1754
bool MustWaitNormalAck(void) const
Definition: mac-low.cc:153
virtual bool GetGreenfield(void) const =0
virtual ~MacLow()
Definition: mac-low.cc:311
Ptr< WifiPhy > m_phy
Pointer to WifiPhy (actually send/receives frames)
Definition: mac-low.h:1070
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:451
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:430
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:1117
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:1007
MacLowTransmissionListener * m_listener
Transmission listener for the current packet.
Definition: mac-low.h:1100
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:1330
void RxCompleteBufferedPacketsUntilFirstLost(Mac48Address originator, uint8_t tid)
Definition: mac-low.cc:1903