A Discrete-Event Network Simulator
API
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 #include "yans-wifi-phy.h"
38 #include "ampdu-tag.h"
39 #include "wifi-mac-queue.h"
40 #include "mpdu-aggregator.h"
41 
42 #undef NS_LOG_APPEND_CONTEXT
43 #define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] "
44 
45 
46 namespace ns3 {
47 
48 NS_LOG_COMPONENT_DEFINE ("MacLow");
49 
51 {
52 }
54 {
55 }
56 void
58 {
59 }
60 void
62 {
63 }
65 {
66 }
68 {
69 }
70 
72 {
73 }
75 {
76 }
77 
79 {
80 }
82 {
83 }
84 void
86 {
87 }
88 uint16_t
90 {
91  return 0;
92 }
93 uint16_t
95 {
96  return 0;
97 }
100 {
101  return 0;
102 }
103 void
104 MacLowBlockAckEventListener::RemoveFromBaQueue (uint8_t tid, Mac48Address recipient, uint16_t seqnumber)
105 {
106 }
107 uint32_t
109 {
110  return 0;
111 }
112 uint32_t
114 {
115  return 0;
116 }
117 
119  : m_nextSize (0),
120  m_waitAck (ACK_NONE),
121  m_sendRts (false),
122  m_overrideDurationId (Seconds (0))
123 {
124 }
125 void
127 {
128  m_nextSize = size;
129 }
130 void
132 {
133  m_nextSize = 0;
134 }
135 void
137 {
138  m_overrideDurationId = durationId;
139 }
140 void
142 {
144 }
145 void
147 {
149 }
150 void
152 {
154 }
155 void
157 {
159 }
160 void
162 {
164 }
165 void
167 {
169 }
170 void
172 {
174 }
175 void
177 {
179 }
180 void
182 {
183  m_sendRts = true;
184 }
185 void
187 {
188  m_sendRts = false;
189 }
190 bool
192 {
193  return (m_waitAck != ACK_NONE);
194 }
195 bool
197 {
198  return (m_waitAck == ACK_NORMAL);
199 }
200 bool
202 {
203  return (m_waitAck == ACK_FAST);
204 }
205 bool
207 {
208  return (m_waitAck == ACK_SUPER_FAST);
209 }
210 bool
212 {
213  return (m_waitAck == BLOCK_ACK_BASIC) ? true : false;
214 }
215 bool
217 {
218  return (m_waitAck == BLOCK_ACK_COMPRESSED) ? true : false;
219 }
220 bool
222 {
223  return (m_waitAck == BLOCK_ACK_MULTI_TID) ? true : false;
224 }
225 bool
227 {
228  return m_sendRts;
229 }
230 bool
232 {
233  return (m_overrideDurationId != Seconds (0));
234 }
235 Time
237 {
239  return m_overrideDurationId;
240 }
241 bool
243 {
244  return (m_nextSize != 0);
245 }
246 uint32_t
248 {
250  return m_nextSize;
251 }
252 
253 std::ostream &operator << (std::ostream &os, const MacLowTransmissionParameters &params)
254 {
255  os << "["
256  << "send rts=" << params.m_sendRts << ", "
257  << "next size=" << params.m_nextSize << ", "
258  << "dur=" << params.m_overrideDurationId << ", "
259  << "ack=";
260  switch (params.m_waitAck)
261  {
263  os << "none";
264  break;
266  os << "normal";
267  break;
269  os << "fast";
270  break;
272  os << "super-fast";
273  break;
275  os << "basic-block-ack";
276  break;
278  os << "compressed-block-ack";
279  break;
281  os << "multi-tid-block-ack";
282  break;
283  }
284  os << "]";
285  return os;
286 }
287 
288 
293 {
294 public:
301  : m_macLow (macLow)
302  {
303  }
305  {
306  }
307  virtual void NotifyRxStart (Time duration)
308  {
309  }
310  virtual void NotifyRxEndOk (void)
311  {
312  }
313  virtual void NotifyRxEndError (void)
314  {
315  }
316  virtual void NotifyTxStart (Time duration, double txPowerDbm)
317  {
318  }
319  virtual void NotifyMaybeCcaBusyStart (Time duration)
320  {
321  }
322  virtual void NotifySwitchingStart (Time duration)
323  {
324  m_macLow->NotifySwitchingStartNow (duration);
325  }
326  virtual void NotifySleep (void)
327  {
329  }
330  virtual void NotifyWakeup (void)
331  {
332  }
333 private:
335 };
336 
337 
339  : m_normalAckTimeoutEvent (),
340  m_fastAckTimeoutEvent (),
341  m_superFastAckTimeoutEvent (),
342  m_fastAckFailedTimeoutEvent (),
343  m_blockAckTimeoutEvent (),
344  m_ctsTimeoutEvent (),
345  m_sendCtsEvent (),
346  m_sendAckEvent (),
347  m_sendDataEvent (),
348  m_waitSifsEvent (),
349  m_endTxNoAckEvent (),
350  m_mpduAggregator (0),
351  m_currentPacket (0),
352  m_listener (0),
353  m_phyMacLowListener (0),
354  m_ctsToSelfSupported (false),
355  m_receivedAtLeastOneMpdu (false)
356 {
357  NS_LOG_FUNCTION (this);
359  m_lastNavStart = Seconds (0);
360  m_promisc = false;
361  m_ampdu = false;
362  m_sentMpdus = 0;
363  m_aggregateQueue = CreateObject<WifiMacQueue> ();
364 }
365 
367 {
368  NS_LOG_FUNCTION (this);
369 }
370 
371 void
373 {
376 }
377 
378 void
380 {
381  if (m_phyMacLowListener != 0 )
382  {
384  delete m_phyMacLowListener;
386  }
387 }
388 
389 void
391 {
392  NS_LOG_FUNCTION (this);
405  m_phy = 0;
406  m_stationManager = 0;
407  if (m_phyMacLowListener != 0)
408  {
409  delete m_phyMacLowListener;
411  }
412  m_mpduAggregator = 0;
413  m_sentMpdus = 0;
414  m_aggregateQueue = 0;
415  m_ampdu = false;
416 }
417 
418 void
420 {
421  NS_LOG_FUNCTION (this);
422  bool oneRunning = false;
424  {
426  oneRunning = true;
427  }
429  {
431  oneRunning = true;
432  }
434  {
436  oneRunning = true;
437  }
439  {
441  oneRunning = true;
442  }
444  {
446  oneRunning = true;
447  }
449  {
451  oneRunning = true;
452  }
453  if (m_sendCtsEvent.IsRunning ())
454  {
456  oneRunning = true;
457  }
458  if (m_sendAckEvent.IsRunning ())
459  {
461  oneRunning = true;
462  }
463  if (m_sendDataEvent.IsRunning ())
464  {
466  oneRunning = true;
467  }
468  if (m_waitSifsEvent.IsRunning ())
469  {
471  oneRunning = true;
472  }
473  if (m_waitRifsEvent.IsRunning ())
474  {
476  oneRunning = true;
477  }
479  {
481  oneRunning = true;
482  }
483  if (oneRunning && m_listener != 0)
484  {
485  m_listener->Cancel ();
486  m_listener = 0;
487  }
488 }
489 
490 void
492 {
493  m_phy = phy;
497 }
499 MacLow::GetPhy (void) const
500 {
501  return m_phy;
502 }
503 void
505 {
509  m_phy = 0;
510 }
511 void
513 {
514  m_stationManager = manager;
515 }
516 
517 void
519 {
520  m_self = ad;
521 }
522 void
524 {
525  m_ackTimeout = ackTimeout;
526 }
527 void
529 {
530  m_basicBlockAckTimeout = blockAckTimeout;
531 }
532 void
534 {
535  m_compressedBlockAckTimeout = blockAckTimeout;
536 }
537 void
539 {
540  m_ctsToSelfSupported = enable;
541 }
542 bool
544 {
545  return m_ctsToSelfSupported;
546 }
547 void
549 {
550  m_ctsTimeout = ctsTimeout;
551 }
552 void
554 {
555  m_sifs = sifs;
556 }
557 void
559 {
560  m_slotTime = slotTime;
561 }
562 void
564 {
565  m_pifs = pifs;
566 }
567 void
569 {
570  m_rifs = rifs;
571 }
572 void
574 {
575  m_bssid = bssid;
576 }
577 void
579 {
580  m_promisc = true;
581 }
583 MacLow::GetAddress (void) const
584 {
585  return m_self;
586 }
587 Time
589 {
590  return m_ackTimeout;
591 }
592 Time
594 {
595  return m_basicBlockAckTimeout;
596 }
597 Time
599 {
601 }
602 Time
604 {
605  return m_ctsTimeout;
606 }
607 Time
608 MacLow::GetSifs (void) const
609 {
610  return m_sifs;
611 }
612 Time
613 MacLow::GetRifs (void) const
614 {
615  return m_rifs;
616 }
617 Time
619 {
620  return m_slotTime;
621 }
622 Time
623 MacLow::GetPifs (void) const
624 {
625  return m_pifs;
626 }
628 MacLow::GetBssid (void) const
629 {
630  return m_bssid;
631 }
632 bool
633 MacLow::IsPromisc (void) const
634 {
635  return m_promisc;
636 }
637 
638 void
640 {
641  m_rxCallback = callback;
642 }
643 void
645 {
646  m_dcfListeners.push_back (listener);
647 }
648 
649 bool
651 {
652  uint32_t size, actualSize;
653  WifiMacTrailer fcs;
654  size = packet->GetSize () + hdr.GetSize () + fcs.GetSerializedSize ();
655  Ptr<Packet> p = AggregateToAmpdu (packet, hdr);
656  actualSize = p->GetSize();
657  if (actualSize > size)
658  {
659  m_currentPacket = p;
660  return true;
661  }
662  else
663  return false;
664 }
665 
666 void
668  const WifiMacHeader* hdr,
670  MacLowTransmissionListener *listener)
671 {
672  NS_LOG_FUNCTION (this << packet << hdr << params << listener);
673  /* m_currentPacket is not NULL because someone started
674  * a transmission and was interrupted before one of:
675  * - ctsTimeout
676  * - sendDataAfterCTS
677  * expired. This means that one of these timers is still
678  * running. They are all cancelled below anyway by the
679  * call to CancelAllEvents (because of at least one
680  * of these two timer) which will trigger a call to the
681  * previous listener's cancel method.
682  *
683  * This typically happens because the high-priority
684  * QapScheduler has taken access to the channel from
685  * one of the Edca of the QAP.
686  */
687  m_currentHdr = *hdr;
688  CancelAllEvents ();
689  m_listener = listener;
690  m_txParams = params;
691 
692  //NS_ASSERT (m_phy->IsStateIdle ());
693 
694  if(m_aggregateQueue->GetSize () == 0)
695  {
696  m_currentPacket = packet->Copy ();
698  }
699  else
700  {
701  /*m_aggregateQueue > 0 occurs when a RTS/CTS exchange failed before an A-MPDU transmission.
702  *In that case, we transmit the same A-MPDU as previously.
703  */
704  m_sentMpdus = m_aggregateQueue->GetSize ();
705  m_ampdu = true;
706  }
707 
708  NS_LOG_DEBUG ("startTx size=" << GetSize (m_currentPacket, &m_currentHdr) <<
709  ", to=" << m_currentHdr.GetAddr1 () << ", listener=" << m_listener);
710 
711  if (m_ampdu)
713 
714  if (m_txParams.MustSendRts ())
715  {
716  SendRtsForPacket ();
717  }
718  else
719  {
721  {
722  SendCtsToSelf();
723  }
724  else
725  {
726  SendDataPacket ();
727  }
728  }
729 
730  /* When this method completes, we have taken ownership of the medium. */
731  NS_ASSERT (m_phy->IsStateTx ());
732 }
733 bool
735 {
737  return m_stationManager->NeedCtsToSelf (dataTxVector);
738 }
739 void
741 {
742  NS_LOG_FUNCTION (this << packet << rxSnr);
743  NS_LOG_DEBUG ("rx failed ");
744  AmpduTag ampdu;
745  Ptr<Packet> pkt = packet->Copy();
746  bool isInAmpdu = pkt->RemovePacketTag(ampdu);
747 
748  if(isInAmpdu && m_receivedAtLeastOneMpdu && (ampdu.GetNoOfMpdus() == 1))
749  {
751  MpduAggregator::DeaggregatedMpdusCI n = packets.begin ();
752  WifiMacHeader hdr;
753  (*n).first->PeekHeader(hdr);
754  if(hdr.IsQosData())
755  {
756  NS_LOG_DEBUG ("last a-mpdu subframe detected/sendImmediateBlockAck from=" << hdr.GetAddr2 ());
759  hdr.GetQosTid(),
760  hdr.GetAddr2 (),
761  hdr.GetDuration (),
762  m_currentMode);
763  }
764  else if (hdr.IsBlockAckReq())
765  {
766  NS_LOG_DEBUG("last a-mpdu subframe is BAR");
767  }
768  m_receivedAtLeastOneMpdu = false;
769  }
770  else if (m_txParams.MustWaitFastAck ())
771  {
775  }
776  return;
777 }
778 
779 void
781 {
782  NS_LOG_DEBUG ("switching channel. Cancelling MAC pending events");
783  m_stationManager->Reset ();
784  CancelAllEvents ();
786  {
788  }
791  m_currentPacket = 0;
792  m_listener = 0;
793 }
794 
795 void
797 {
798  NS_LOG_DEBUG ("Device in sleep mode. Cancelling MAC pending events");
799  CancelAllEvents ();
801  {
803  }
806  m_currentPacket = 0;
807  m_listener = 0;
808 }
809 
810 void
811 MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamble preamble, bool ampduSubframe)
812 {
813  NS_LOG_FUNCTION (this << packet << rxSnr << txMode << preamble);
814  /* A packet is received from the PHY.
815  * When we have handled this packet,
816  * we handle any packet present in the
817  * packet queue.
818  */
819  WifiMacHeader hdr;
820  packet->RemoveHeader (hdr);
821 
822  bool isPrevNavZero = IsNavZero ();
823  NS_LOG_DEBUG ("duration/id=" << hdr.GetDuration ());
824  NotifyNav (packet,hdr, txMode, preamble);
825  if (hdr.IsRts ())
826  {
827  /* see section 9.2.5.7 802.11-1999
828  * A STA that is addressed by an RTS frame shall transmit a CTS frame after a SIFS
829  * period if the NAV at the STA receiving the RTS frame indicates that the medium is
830  * idle. If the NAV at the STA receiving the RTS indicates the medium is not idle,
831  * that STA shall not respond to the RTS frame.
832  */
833  if (ampduSubframe)
834  {
835  NS_FATAL_ERROR ("Received RTS as part of an A-MPDU");
836  }
837  else
838  {
839  if (isPrevNavZero
840  && hdr.GetAddr1 () == m_self)
841  {
842  NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
844  m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
845  rxSnr, txMode);
848  hdr.GetAddr2 (),
849  hdr.GetDuration (),
850  txMode,
851  rxSnr);
852  }
853  else
854  {
855  NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
856  }
857  }
858  }
859  else if (hdr.IsCts ()
860  && hdr.GetAddr1 () == m_self
862  && m_currentPacket != 0)
863  {
864  if (ampduSubframe)
865  {
866  NS_FATAL_ERROR ("Received CTS as part of an A-MPDU");
867  }
868  NS_LOG_DEBUG ("receive cts from=" << m_currentHdr.GetAddr1 ());
869  SnrTag tag;
870  packet->RemovePacketTag (tag);
872  rxSnr, txMode);
874  rxSnr, txMode, tag.Get ());
875 
878  m_listener->GotCts (rxSnr, txMode);
882  hdr.GetAddr1 (),
883  hdr.GetDuration (),
884  txMode);
885  }
886  else if (hdr.IsAck ()
887  && hdr.GetAddr1 () == m_self
891  && m_txParams.MustWaitAck ())
892  {
893  NS_LOG_DEBUG ("receive ack from=" << m_currentHdr.GetAddr1 ());
894  SnrTag tag;
895  packet->RemovePacketTag (tag);
897  rxSnr, txMode);
899  rxSnr, txMode, tag.Get ());
900 
901  bool gotAck = false;
904  {
907  gotAck = true;
908  }
911  {
914  gotAck = true;
915  }
916  if (gotAck)
917  {
918  m_listener->GotAck (rxSnr, txMode);
919  }
920  if (m_txParams.HasNextPacket ())
921  {
924  }
925  }
926  else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self
929  {
930  NS_LOG_DEBUG ("got block ack from " << hdr.GetAddr2 ());
931  CtrlBAckResponseHeader blockAck;
932  packet->RemoveHeader (blockAck);
935  m_listener->GotBlockAck (&blockAck, hdr.GetAddr2 (),txMode);
936  m_sentMpdus = 0;
937  m_ampdu = false;
938  }
939  else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
940  {
941  CtrlBAckRequestHeader blockAckReq;
942  packet->RemoveHeader (blockAckReq);
943  if (!blockAckReq.IsMultiTid ())
944  {
945  uint8_t tid = blockAckReq.GetTidInfo ();
946  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), tid));
947  if (it != m_bAckAgreements.end ())
948  {
949  //Update block ack cache
950  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), tid));
951  NS_ASSERT (i != m_bAckCaches.end ());
952  (*i).second.UpdateWithBlockAckReq (blockAckReq.GetStartingSequence ());
953 
955  /* See section 11.5.3 in IEEE 802.11 for mean of this timer */
956  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
957  if ((*it).second.first.IsImmediateBlockAck ())
958  {
959  NS_LOG_DEBUG ("rx blockAckRequest/sendImmediateBlockAck from=" << hdr.GetAddr2 ());
962  blockAckReq,
963  hdr.GetAddr2 (),
964  hdr.GetDuration (),
965  txMode);
966  }
967  else
968  {
969  NS_FATAL_ERROR ("Delayed block ack not supported.");
970  }
971  m_receivedAtLeastOneMpdu = false;
972  }
973  else
974  {
975  NS_LOG_DEBUG ("There's not a valid agreement for this block ack request.");
976  }
977  }
978  else
979  {
980  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
981  }
982  }
983  else if (hdr.IsCtl ())
984  {
985  NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ());
986  m_receivedAtLeastOneMpdu = false;
987  }
988  else if (hdr.GetAddr1 () == m_self)
989  {
990  m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
991  rxSnr, txMode);
992  if (hdr.IsQosData () && ReceiveMpdu (packet, hdr))
993  {
994  /* From section 9.10.4 in IEEE 802.11:
995  Upon the receipt of a QoS data frame from the originator for which
996  the Block Ack agreement exists, the recipient shall buffer the MSDU
997  regardless of the value of the Ack Policy subfield within the
998  QoS Control field of the QoS data frame. */;
999  if (hdr.IsQosAck () && !ampduSubframe)
1000  {
1001  NS_LOG_DEBUG ("rx QoS unicast/sendAck from=" << hdr.GetAddr2 ());
1002  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1003 
1004  RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (),
1005  hdr.GetAddr2 (), hdr.GetQosTid ());
1009  &MacLow::SendAckAfterData, this,
1010  hdr.GetAddr2 (),
1011  hdr.GetDuration (),
1012  txMode,
1013  rxSnr);
1014  m_receivedAtLeastOneMpdu = false;
1015  }
1016  else if (hdr.IsQosBlockAck ())
1017  {
1018  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1019  /* See section 11.5.3 in IEEE 802.11 for mean of this timer */
1020  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
1021  }
1022  return;
1023  }
1024  else if (hdr.IsQosData () && hdr.IsQosBlockAck ())
1025  {
1026  /* This happens if a packet with ack policy Block Ack is received and a block ack
1027  agreement for that packet doesn't exist.
1028 
1029  From section 11.5.3 in IEEE 802.11e:
1030  When a recipient does not have an active Block ack for a TID, but receives
1031  data MPDUs with the Ack Policy subfield set to Block Ack, it shall discard
1032  them and shall send a DELBA frame using the normal access
1033  mechanisms. */
1034  AcIndex ac = QosUtilsMapTidToAc (hdr.GetQosTid ());
1035  m_edcaListeners[ac]->BlockAckInactivityTimeout (hdr.GetAddr2 (), hdr.GetQosTid ());
1036  return;
1037  }
1038  else if (hdr.IsQosData () && hdr.IsQosNoAck ())
1039  {
1040  if (ampduSubframe)
1041  {
1042  NS_LOG_DEBUG ("rx Ampdu with No Ack Policy from=" << hdr.GetAddr2 ());
1043  }
1044  else
1045  {
1046  NS_LOG_DEBUG ("rx unicast/noAck from=" << hdr.GetAddr2 ());
1047  }
1048  }
1049  else if (hdr.IsData () || hdr.IsMgt ())
1050  {
1051  if (hdr.IsMgt() && ampduSubframe)
1052  {
1053  NS_FATAL_ERROR ("Received management packet as part of an A-MPDU");
1054  }
1055  else
1056  {
1057  NS_LOG_DEBUG ("rx unicast/sendAck from=" << hdr.GetAddr2 ());
1060  &MacLow::SendAckAfterData, this,
1061  hdr.GetAddr2 (),
1062  hdr.GetDuration (),
1063  txMode,
1064  rxSnr);
1065  }
1066  }
1067  goto rxPacket;
1068  }
1069  else if (hdr.GetAddr1 ().IsGroup ())
1070  {
1071  if (ampduSubframe)
1072  {
1073  NS_FATAL_ERROR ("Received group addressed packet as part of an A-MPDU");
1074  }
1075  else
1076  {
1077  if (hdr.IsData () || hdr.IsMgt ())
1078  {
1079  NS_LOG_DEBUG ("rx group from=" << hdr.GetAddr2 ());
1080  m_receivedAtLeastOneMpdu = false;
1081  goto rxPacket;
1082  }
1083  else
1084  {
1085  // DROP
1086  }
1087  }
1088  }
1089  else if (m_promisc)
1090  {
1091  NS_ASSERT (hdr.GetAddr1 () != m_self);
1092  if (hdr.IsData ())
1093  {
1094  goto rxPacket;
1095  }
1096  }
1097  else
1098  {
1099  //NS_LOG_DEBUG_VERBOSE ("rx not-for-me from %d", GetSource (packet));
1100  }
1101  return;
1102 rxPacket:
1103  WifiMacTrailer fcs;
1104  packet->RemoveTrailer (fcs);
1105  m_rxCallback (packet, &hdr);
1106  return;
1107 }
1108 
1109 uint8_t
1111 {
1112  uint8_t tid = 0;
1113  if (hdr.IsQosData ())
1114  tid = hdr.GetQosTid ();
1115  else if (hdr.IsBlockAckReq ())
1116  {
1117  CtrlBAckRequestHeader baReqHdr;
1118  packet->PeekHeader (baReqHdr);
1119  tid = baReqHdr.GetTidInfo();
1120  }
1121  else if (hdr.IsBlockAck ())
1122  {
1123  CtrlBAckResponseHeader baRespHdr;
1124  packet->PeekHeader (baRespHdr);
1125  tid = baRespHdr.GetTidInfo ();
1126  }
1127  return tid;
1128 }
1129 
1130 uint32_t
1132 {
1133  WifiMacHeader ack;
1134  ack.SetType (WIFI_MAC_CTL_ACK);
1135  return ack.GetSize () + 4;
1136 }
1137 uint32_t
1139 {
1140  WifiMacHeader hdr;
1142  CtrlBAckResponseHeader blockAck;
1143  if (type == BASIC_BLOCK_ACK)
1144  {
1145  blockAck.SetType (BASIC_BLOCK_ACK);
1146  }
1147  else if (type == COMPRESSED_BLOCK_ACK)
1148  {
1149  blockAck.SetType (COMPRESSED_BLOCK_ACK);
1150  }
1151  else if (type == MULTI_TID_BLOCK_ACK)
1152  {
1153  //Not implemented
1154  NS_ASSERT (false);
1155  }
1156  return hdr.GetSize () + blockAck.GetSerializedSize () + 4;
1157 }
1158 uint32_t
1160 {
1161  WifiMacHeader rts;
1162  rts.SetType (WIFI_MAC_CTL_RTS);
1163  return rts.GetSize () + 4;
1164 }
1165 Time
1167 {
1168  WifiTxVector ackTxVector = GetAckTxVectorForData (to, dataTxVector.GetMode());
1169  return GetAckDuration (ackTxVector);
1170 }
1171 Time
1173 {
1174  WifiPreamble preamble;
1175  if (ackTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1176  preamble= WIFI_PREAMBLE_HT_MF;
1177  else
1178  preamble=WIFI_PREAMBLE_LONG;
1179  return m_phy->CalculateTxDuration (GetAckSize (), ackTxVector, preamble, m_phy->GetFrequency(), 0, 0);
1180 }
1181 Time
1182 MacLow::GetBlockAckDuration (Mac48Address to, WifiTxVector blockAckReqTxVector, enum BlockAckType type) const
1183 {
1184  /*
1185  * For immediate BlockAck we should transmit the frame with the same WifiMode
1186  * as the BlockAckReq.
1187  *
1188  * from section 9.6 in IEEE 802.11e:
1189  * The BlockAck control frame shall be sent at the same rate and modulation class as
1190  * the BlockAckReq frame if it is sent in response to a BlockAckReq frame.
1191  */
1192  WifiPreamble preamble;
1193  if (blockAckReqTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1194  preamble= WIFI_PREAMBLE_HT_MF;
1195  else
1196  preamble=WIFI_PREAMBLE_LONG;
1197  return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxVector, preamble, m_phy->GetFrequency(), 0, 0);
1198 }
1199 Time
1201 {
1202  WifiTxVector ctsTxVector = GetCtsTxVectorForRts (to, rtsTxVector.GetMode());
1203  return GetCtsDuration (ctsTxVector);
1204 }
1205 
1206 Time
1208 {
1209  WifiPreamble preamble;
1210  if (ctsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1211  preamble= WIFI_PREAMBLE_HT_MF;
1212  else
1213  preamble=WIFI_PREAMBLE_LONG;
1214  return m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble, m_phy->GetFrequency(), 0, 0);
1215 }
1216 uint32_t
1218 {
1219  WifiMacHeader cts;
1220  cts.SetType (WIFI_MAC_CTL_CTS);
1221  return cts.GetSize () + 4;
1222 }
1223 uint32_t
1225 {
1226  uint32_t size;
1227  WifiMacTrailer fcs;
1228  if (m_ampdu)
1229  size = packet->GetSize ();
1230  else
1231  size= packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
1232  return size;
1233 }
1234 
1237 {
1238  return m_stationManager->GetCtsToSelfTxVector (hdr, packet);
1239 }
1240 
1243 {
1244  Mac48Address to = hdr->GetAddr1 ();
1245  return m_stationManager->GetRtsTxVector (to, hdr, packet);
1246 }
1249 {
1250  Mac48Address to = hdr->GetAddr1 ();
1251  WifiMacTrailer fcs;
1252  uint32_t size = packet->GetSize ()+ hdr->GetSize () + fcs.GetSerializedSize ();
1253  //size is not used in anything!! will not worry about aggregation
1254  return m_stationManager->GetDataTxVector (to, hdr, packet, size);
1255 }
1258 {
1259  return m_stationManager->GetCtsTxVector (to, rtsTxMode);
1260 }
1263 {
1264  return m_stationManager->GetAckTxVector (to, dataTxMode);
1265 }
1268 {
1269  return m_stationManager->GetBlockAckTxVector (to, dataTxMode);
1270 }
1271 
1274 {
1275  return GetCtsTxVector (to, rtsTxMode);
1276 }
1279 {
1280  return GetAckTxVector (to, dataTxMode);
1281 }
1282 
1283 
1284 Time
1286  const WifiMacHeader* hdr,
1287  const MacLowTransmissionParameters& params) const
1288 {
1289  WifiPreamble preamble;
1290  Time txTime = Seconds (0);
1291  if (params.MustSendRts ())
1292  {
1293  WifiTxVector rtsTxVector = GetRtsTxVector (packet, hdr);
1294  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
1295  if (m_phy->GetGreenfield () && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1296  {
1297  preamble = WIFI_PREAMBLE_HT_GF;
1298  }
1299  else if (rtsTxVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HT)
1300  {
1301  preamble = WIFI_PREAMBLE_HT_MF;
1302  }
1303  else
1304  {
1305  preamble = WIFI_PREAMBLE_LONG;
1306  }
1307  txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble, m_phy->GetFrequency(), 0, 0);
1308  txTime += GetCtsDuration (hdr->GetAddr1 (), rtsTxVector);
1309  txTime += Time (GetSifs () * 2);
1310  }
1311  WifiTxVector dataTxVector = GetDataTxVector (packet, hdr);
1312  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
1313  if ( m_phy->GetGreenfield()&& m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1314  preamble= WIFI_PREAMBLE_HT_GF;
1315  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1316  preamble= WIFI_PREAMBLE_HT_MF;
1317  else
1318  preamble=WIFI_PREAMBLE_LONG;
1319  uint32_t dataSize = GetSize (packet, hdr);
1320  txTime += m_phy->CalculateTxDuration (dataSize, dataTxVector, preamble, m_phy->GetFrequency(), 0, 0);
1321  if (params.MustWaitAck ())
1322  {
1323  txTime += GetSifs ();
1324  txTime += GetAckDuration (hdr->GetAddr1 (), dataTxVector);
1325  }
1326  return txTime;
1327 }
1328 
1329 Time
1331  const WifiMacHeader* hdr,
1332  const MacLowTransmissionParameters& params) const
1333 {
1334  Time txTime = CalculateOverallTxTime (packet, hdr, params);
1335  if (params.HasNextPacket ())
1336  {
1337  WifiTxVector dataTxVector = GetDataTxVector (packet, hdr);
1338  WifiPreamble preamble;
1339  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
1340  if ( m_phy->GetGreenfield()&& m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1341  preamble= WIFI_PREAMBLE_HT_GF;
1342  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1343  preamble= WIFI_PREAMBLE_HT_MF;
1344  else
1345  preamble=WIFI_PREAMBLE_LONG;
1346  txTime += GetSifs ();
1347  txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataTxVector, preamble, m_phy->GetFrequency(), 0, 0);
1348  }
1349  return txTime;
1350 }
1351 
1352 void
1354 {
1356  Time duration = hdr.GetDuration ();
1357 
1358  if (hdr.IsCfpoll ()
1359  && hdr.GetAddr2 () == m_bssid)
1360  {
1361  // see section 9.3.2.2 802.11-1999
1362  DoNavResetNow (duration);
1363  return;
1364  }
1367  else if (hdr.GetAddr1 () != m_self)
1368  {
1369  // see section 9.2.5.4 802.11-1999
1370  bool navUpdated = DoNavStartNow (duration);
1371  if (hdr.IsRts () && navUpdated)
1372  {
1381  WifiMacHeader cts;
1382  cts.SetType (WIFI_MAC_CTL_CTS);
1383  WifiTxVector txVector=GetRtsTxVector (packet, &hdr);
1384  Time navCounterResetCtsMissedDelay =
1385  m_phy->CalculateTxDuration (cts.GetSerializedSize (), txVector, preamble, m_phy->GetFrequency(), 0, 0) +
1386  Time (2 * GetSifs ()) + Time (2 * GetSlotTime ());
1387  m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay,
1389  Simulator::Now ());
1390  }
1391  }
1392 }
1393 
1394 void
1396 {
1397  if (m_phy->GetLastRxStartTime () < rtsEndRxTime)
1398  {
1399  DoNavResetNow (Seconds (0.0));
1400  }
1401 }
1402 
1403 void
1405 {
1406  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1407  {
1408  (*i)->NavReset (duration);
1409  }
1411  m_lastNavStart = duration;
1412 }
1413 bool
1415 {
1416  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1417  {
1418  (*i)->NavStart (duration);
1419  }
1420  Time newNavEnd = Simulator::Now () + duration;
1421  Time oldNavEnd = m_lastNavStart + m_lastNavDuration;
1422  if (newNavEnd > oldNavEnd)
1423  {
1425  m_lastNavDuration = duration;
1426  return true;
1427  }
1428  return false;
1429 }
1430 void
1432 {
1433  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1434  {
1435  (*i)->AckTimeoutStart (duration);
1436  }
1437 }
1438 void
1440 {
1441  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1442  {
1443  (*i)->AckTimeoutReset ();
1444  }
1445 }
1446 void
1448 {
1449  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1450  {
1451  (*i)->CtsTimeoutStart (duration);
1452  }
1453 }
1454 void
1456 {
1457  for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1458  {
1459  (*i)->CtsTimeoutReset ();
1460  }
1461 }
1462 
1463 void
1465  WifiTxVector txVector, WifiPreamble preamble)
1466 {
1467  NS_LOG_FUNCTION (this << packet << hdr << txVector);
1468  NS_LOG_DEBUG ("send " << hdr->GetTypeString () <<
1469  ", to=" << hdr->GetAddr1 () <<
1470  ", size=" << packet->GetSize () <<
1471  ", mode=" << txVector.GetMode() <<
1472  ", duration=" << hdr->GetDuration () <<
1473  ", seq=0x" << std::hex << m_currentHdr.GetSequenceControl () << std::dec);
1474  if (!m_ampdu || hdr->IsRts ())
1475  {
1476  m_phy->SendPacket (packet, txVector, preamble, 0);
1477  }
1478  else
1479  {
1480  Ptr<Packet> newPacket;
1481  Ptr <const Packet> dequeuedPacket;
1482  WifiMacHeader newHdr;
1483  WifiMacTrailer fcs;
1484  uint32_t queueSize = m_aggregateQueue->GetSize ();
1485  bool last = false;
1486  uint8_t packetType = 0;
1487  //Add packet tag
1488  AmpduTag ampdutag;
1489  ampdutag.SetAmpdu (true);
1490  Time delay = Seconds (0);
1491  for ( ; queueSize > 0; queueSize--)
1492  {
1493  dequeuedPacket = m_aggregateQueue->Dequeue (&newHdr);
1494  newPacket = dequeuedPacket->Copy ();
1495  newHdr.SetDuration (hdr->GetDuration ());
1496  newPacket->AddHeader (newHdr);
1497  newPacket->AddTrailer (fcs);
1498  if (queueSize == 1)
1499  {
1500  last = true;
1501  packetType = 2;
1502  }
1503  m_mpduAggregator->AddHeaderAndPad (newPacket, last);
1504 
1505  ampdutag.SetNoOfMpdus(queueSize);
1506  newPacket->AddPacketTag(ampdutag);
1507  if (delay == Seconds (0))
1508  {
1509  NS_LOG_DEBUG("Sending MPDU as part of A-MPDU");
1510  packetType = 1;
1511  m_phy->SendPacket (newPacket, txVector, preamble, packetType);
1512  }
1513  else
1514  {
1515  Simulator::Schedule (delay, &MacLow::SendPacket, this, newPacket, txVector, preamble, packetType);
1516  }
1517  if(queueSize > 1)
1518  delay = delay + m_phy->CalculateTxDuration (GetSize (newPacket, &newHdr), txVector, preamble, m_phy->GetFrequency(), packetType, 0);
1519  preamble = WIFI_PREAMBLE_NONE;
1520  }
1521  }
1522 }
1523 
1524 void
1525 MacLow::SendPacket (Ptr<const Packet> packet, WifiTxVector txVector, WifiPreamble preamble, uint8_t packetType)
1526 {
1527  NS_LOG_DEBUG("Sending MPDU as part of A-MPDU");
1528  m_phy->SendPacket (packet, txVector, preamble, packetType);
1529 }
1530 
1531 void
1533 {
1534  NS_LOG_FUNCTION (this);
1535  NS_LOG_DEBUG ("cts timeout");
1539  m_stationManager->ReportRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1540  if(m_sentMpdus == 0)
1541  {
1542  m_currentPacket = 0;
1543  }
1545  m_listener = 0;
1546  m_sentMpdus = 0;
1547  m_ampdu = false;
1548  listener->MissedCts ();
1549 }
1550 void
1552 {
1553  NS_LOG_FUNCTION (this);
1554  NS_LOG_DEBUG ("normal ack timeout");
1558  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1560  m_listener = 0;
1561  m_sentMpdus = 0;
1562  m_ampdu = false;
1563  listener->MissedAck ();
1564 }
1565 void
1567 {
1568  NS_LOG_FUNCTION (this);
1569  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1571  m_listener = 0;
1572  if (m_phy->IsStateIdle ())
1573  {
1574  NS_LOG_DEBUG ("fast Ack idle missed");
1575  listener->MissedAck ();
1576  }
1577  else
1578  {
1579  NS_LOG_DEBUG ("fast Ack ok");
1580  }
1581 }
1582 void
1584 {
1585  NS_LOG_FUNCTION (this);
1586  NS_LOG_DEBUG ("block ack timeout");
1587 
1588  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1590  m_listener = 0;
1591  m_sentMpdus = 0;
1592  m_ampdu = false;
1593  listener->MissedBlockAck ();
1594 }
1595 void
1597 {
1598  NS_LOG_FUNCTION (this);
1599  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1601  m_listener = 0;
1602  if (m_phy->IsStateIdle ())
1603  {
1604  NS_LOG_DEBUG ("super fast Ack failed");
1605  listener->MissedAck ();
1606  }
1607  else
1608  {
1609  NS_LOG_DEBUG ("super fast Ack ok");
1610  listener->GotAck (0.0, WifiMode ());
1611  }
1612 }
1613 
1614 void
1616 {
1617  NS_LOG_FUNCTION (this);
1618  /* send an RTS for this packet. */
1619  WifiMacHeader rts;
1620  rts.SetType (WIFI_MAC_CTL_RTS);
1621  rts.SetDsNotFrom ();
1622  rts.SetDsNotTo ();
1623  rts.SetNoRetry ();
1624  rts.SetNoMoreFragments ();
1625  rts.SetAddr1 (m_currentHdr.GetAddr1 ());
1626  rts.SetAddr2 (m_self);
1628  Time duration = Seconds (0);
1629 
1630  WifiPreamble preamble;
1631  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
1632  if ( m_phy->GetGreenfield()&& m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1633  preamble= WIFI_PREAMBLE_HT_GF;
1634  else if (rtsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1635  preamble= WIFI_PREAMBLE_HT_MF;
1636  else
1637  preamble=WIFI_PREAMBLE_LONG;
1638 
1639  if (m_txParams.HasDurationId ())
1640  {
1641  duration += m_txParams.GetDurationId ();
1642  }
1643  else
1644  {
1646  duration += GetSifs ();
1647  duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxVector);
1648  duration += GetSifs ();
1650  dataTxVector, preamble, m_phy->GetFrequency(), 0, 0);
1651  duration += GetSifs ();
1653  {
1654  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2(), dataTxVector.GetMode());
1655  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), blockAckReqTxVector, BASIC_BLOCK_ACK);
1656  }
1658  {
1659  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2(), dataTxVector.GetMode());
1660  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1661  }
1662  else if (m_txParams.MustWaitAck ())
1663  {
1664  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1665  }
1666  if (m_txParams.HasNextPacket ())
1667  {
1669  dataTxVector, preamble, m_phy->GetFrequency(), 0, 0);
1670  if (m_txParams.MustWaitAck ())
1671  {
1672  duration += GetSifs ();
1673  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1674  }
1675  }
1676  }
1677  rts.SetDuration (duration);
1678 
1679  Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble, m_phy->GetFrequency(), 0, 0);
1680  Time timerDelay = txDuration + GetCtsTimeout ();
1681 
1683  NotifyCtsTimeoutStartNow (timerDelay);
1685 
1686  Ptr<Packet> packet = Create<Packet> ();
1687  packet->AddHeader (rts);
1688  WifiMacTrailer fcs;
1689  packet->AddTrailer (fcs);
1690 
1691  ForwardDown (packet, &rts, rtsTxVector,preamble);
1692 }
1693 
1694 void
1696 {
1697  WifiPreamble preamble;
1698 
1699  //Since it is data then it can have format = GF
1700  if (m_phy->GetGreenfield() && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1701  preamble= WIFI_PREAMBLE_HT_GF;
1702  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1703  preamble= WIFI_PREAMBLE_HT_MF;
1704  else
1705  preamble=WIFI_PREAMBLE_LONG;
1706 
1707  Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxVector, preamble, m_phy->GetFrequency(), 0, 0);
1709  {
1710  Time timerDelay = txDuration + GetAckTimeout ();
1712  NotifyAckTimeoutStartNow (timerDelay);
1714  }
1715  else if (m_txParams.MustWaitFastAck ())
1716  {
1717  Time timerDelay = txDuration + GetPifs ();
1719  NotifyAckTimeoutStartNow (timerDelay);
1721  }
1722  else if (m_txParams.MustWaitSuperFastAck ())
1723  {
1724  Time timerDelay = txDuration + GetPifs ();
1726  NotifyAckTimeoutStartNow (timerDelay);
1729  }
1730  else if (m_txParams.MustWaitBasicBlockAck ())
1731  {
1732  Time timerDelay = txDuration + GetBasicBlockAckTimeout ();
1734  NotifyAckTimeoutStartNow (timerDelay);
1736  }
1738  {
1739  Time timerDelay = txDuration + GetCompressedBlockAckTimeout ();
1741  NotifyAckTimeoutStartNow (timerDelay);
1743  }
1744  else if (m_txParams.HasNextPacket ())
1745  {
1746  if (m_stationManager->HasHtSupported())
1747  {
1748  Time delay = txDuration + GetRifs ();
1751  }
1752  else
1753  {
1754  Time delay = txDuration + GetSifs ();
1757  }
1758  }
1759  else
1760  {
1761  // since we do not expect any timer to be triggered.
1762  Simulator::Schedule(txDuration, &MacLow::EndTxNoAck, this);
1763  }
1764 }
1765 
1766 void
1768 {
1769  NS_LOG_FUNCTION (this);
1770  /* send this packet directly. No RTS is needed. */
1772  WifiPreamble preamble;
1773 
1774  if (m_phy->GetGreenfield() && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1775  //In the future has to make sure that receiver has greenfield enabled
1776  preamble= WIFI_PREAMBLE_HT_GF;
1777  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1778  preamble= WIFI_PREAMBLE_HT_MF;
1779  else
1780  preamble=WIFI_PREAMBLE_LONG;
1781 
1782  StartDataTxTimers (dataTxVector);
1783 
1784  Time duration = Seconds (0.0);
1785  if (m_txParams.HasDurationId ())
1786  {
1787  duration += m_txParams.GetDurationId ();
1788  }
1789  else
1790  {
1792  {
1793  duration += GetSifs ();
1794  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), dataTxVector.GetMode());
1795  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), blockAckReqTxVector, BASIC_BLOCK_ACK);
1796  }
1798  {
1799  duration += GetSifs ();
1800  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), dataTxVector.GetMode());
1801  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1802  }
1803  else if (m_txParams.MustWaitAck ())
1804  {
1805  duration += GetSifs ();
1806  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1807  }
1808  if (m_txParams.HasNextPacket ())
1809  {
1810  duration += GetSifs ();
1812  dataTxVector, preamble, m_phy->GetFrequency(), 0, 0);
1813  if (m_txParams.MustWaitAck ())
1814  {
1815  duration += GetSifs ();
1816  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1817  }
1818  }
1819  }
1820  m_currentHdr.SetDuration (duration);
1821 
1822  if (!m_ampdu)
1823  {
1825  WifiMacTrailer fcs;
1826  m_currentPacket->AddTrailer (fcs);
1827  }
1828 
1829  ForwardDown (m_currentPacket, &m_currentHdr, dataTxVector,preamble);
1830  m_currentPacket = 0;
1831 }
1832 
1833 bool
1834 MacLow::IsNavZero (void) const
1835 {
1837  {
1838  return true;
1839  }
1840  else
1841  {
1842  return false;
1843  }
1844 }
1845 void
1847 {
1848  WifiMacHeader cts;
1849  cts.SetType (WIFI_MAC_CTL_CTS);
1850  cts.SetDsNotFrom ();
1851  cts.SetDsNotTo ();
1852  cts.SetNoMoreFragments ();
1853  cts.SetNoRetry ();
1854  cts.SetAddr1 (m_self);
1855 
1857 
1858  WifiPreamble preamble;
1859  if (ctsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1860  preamble= WIFI_PREAMBLE_HT_MF;
1861  else
1862  preamble=WIFI_PREAMBLE_LONG;
1863 
1864  Time duration = Seconds (0);
1865 
1866  if (m_txParams.HasDurationId ())
1867  {
1868  duration += m_txParams.GetDurationId ();
1869  }
1870  else
1871  {
1873  duration += GetSifs ();
1875  dataTxVector, preamble, m_phy->GetFrequency(), 0, 0);
1877  {
1878 
1879  duration += GetSifs ();
1880  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), dataTxVector.GetMode());
1881  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), blockAckReqTxVector, BASIC_BLOCK_ACK);
1882  }
1884  {
1885  duration += GetSifs ();
1886  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), dataTxVector.GetMode());
1887  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1888  }
1889  else if (m_txParams.MustWaitAck ())
1890  {
1891  duration += GetSifs ();
1892  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1893  }
1894  if (m_txParams.HasNextPacket ())
1895  {
1896  duration += GetSifs ();
1898  dataTxVector, preamble, m_phy->GetFrequency(), 0, 0);
1900  {
1901  duration += GetSifs ();
1902  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), dataTxVector.GetMode());
1903  duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1904  }
1905  else if (m_txParams.MustWaitAck ())
1906  {
1907  duration += GetSifs ();
1908  duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
1909  }
1910  }
1911  }
1912 
1913  cts.SetDuration (duration);
1914 
1915  Ptr<Packet> packet = Create<Packet> ();
1916  packet->AddHeader (cts);
1917  WifiMacTrailer fcs;
1918  packet->AddTrailer (fcs);
1919 
1920  ForwardDown (packet, &cts, ctsTxVector,preamble);
1921 
1922  Time txDuration = m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble, m_phy->GetFrequency(), 0, 0);
1923  txDuration += GetSifs ();
1925 
1926  m_sendDataEvent = Simulator::Schedule (txDuration,
1927  &MacLow::SendDataAfterCts, this,
1928  cts.GetAddr1 (),
1929  duration,
1930  ctsTxVector.GetMode());
1931 }
1932 void
1933 MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode rtsTxMode, double rtsSnr)
1934 {
1935  NS_LOG_FUNCTION (this << source << duration << rtsTxMode << rtsSnr);
1936  /* send a CTS when you receive a RTS
1937  * right after SIFS.
1938  */
1939  WifiTxVector ctsTxVector = GetCtsTxVector (source, rtsTxMode);
1940  WifiMacHeader cts;
1941  cts.SetType (WIFI_MAC_CTL_CTS);
1942  cts.SetDsNotFrom ();
1943  cts.SetDsNotTo ();
1944  cts.SetNoMoreFragments ();
1945  cts.SetNoRetry ();
1946  cts.SetAddr1 (source);
1947  duration -= GetCtsDuration (source, ctsTxVector);
1948  duration -= GetSifs ();
1949  NS_ASSERT (duration >= MicroSeconds (0));
1950  cts.SetDuration (duration);
1951 
1952  Ptr<Packet> packet = Create<Packet> ();
1953  packet->AddHeader (cts);
1954  WifiMacTrailer fcs;
1955  packet->AddTrailer (fcs);
1956 
1957  SnrTag tag;
1958  tag.Set (rtsSnr);
1959  packet->AddPacketTag (tag);
1960 
1961  WifiPreamble preamble;
1962  if (ctsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1963  preamble= WIFI_PREAMBLE_HT_MF;
1964  else
1965  preamble=WIFI_PREAMBLE_LONG;
1966  ForwardDown (packet, &cts, ctsTxVector,preamble);
1967 }
1968 
1969 void
1971 {
1972  NS_LOG_FUNCTION (this);
1973  /* send the third step in a
1974  * RTS/CTS/DATA/ACK hanshake
1975  */
1976  NS_ASSERT (m_currentPacket != 0);
1978 
1979  WifiPreamble preamble;
1980  if (m_phy->GetGreenfield() && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
1981  //In the future has to make sure that receiver has greenfield enabled
1982  preamble= WIFI_PREAMBLE_HT_GF;
1983  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
1984  preamble= WIFI_PREAMBLE_HT_MF;
1985  else
1986  preamble=WIFI_PREAMBLE_LONG;
1987 
1988  StartDataTxTimers (dataTxVector);
1989  Time newDuration = Seconds (0);
1991  {
1992  newDuration += GetSifs ();
1993  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), dataTxVector.GetMode());
1994  newDuration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), blockAckReqTxVector, BASIC_BLOCK_ACK);
1995  }
1997  {
1998  newDuration += GetSifs ();
1999  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), dataTxVector.GetMode());
2000  newDuration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
2001  }
2002  else if (m_txParams.MustWaitAck ())
2003  {
2004  newDuration += GetSifs ();
2005  newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
2006  }
2007  if (m_txParams.HasNextPacket ())
2008  {
2009  newDuration += GetSifs ();
2010  newDuration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (), dataTxVector, preamble, m_phy->GetFrequency(), 0, 0);
2012  {
2013  newDuration += GetSifs ();
2014  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), dataTxVector.GetMode());
2015  newDuration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
2016  }
2017  else if (m_txParams.MustWaitAck ())
2018  {
2019  newDuration += GetSifs ();
2020  newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
2021  }
2022  }
2023 
2024  Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr),dataTxVector, preamble, m_phy->GetFrequency(), 0, 0);
2025  duration -= txDuration;
2026  duration -= GetSifs ();
2027 
2028  duration = std::max (duration, newDuration);
2029  NS_ASSERT (duration >= MicroSeconds (0));
2030  m_currentHdr.SetDuration (duration);
2031 
2032  if (!m_ampdu)
2033  {
2035  WifiMacTrailer fcs;
2036  m_currentPacket->AddTrailer (fcs);
2037  }
2038 
2039  ForwardDown (m_currentPacket, &m_currentHdr, dataTxVector,preamble);
2040  m_currentPacket = 0;
2041 }
2042 
2043 void
2045 {
2046  m_listener->StartNext ();
2047 }
2048 
2049 void
2051 {
2053  m_listener = 0;
2054  listener->EndTxNoAck ();
2055 }
2056 
2057 void
2059 {
2060  NS_LOG_FUNCTION (this);
2062  m_listener = 0;
2063  listener->MissedAck ();
2064  NS_LOG_DEBUG ("fast Ack busy but missed");
2065 }
2066 
2067 void
2068 MacLow::SendAckAfterData (Mac48Address source, Time duration, WifiMode dataTxMode, double dataSnr)
2069 {
2070  NS_LOG_FUNCTION (this);
2071  /* send an ACK when you receive
2072  * a packet after SIFS.
2073  */
2074  WifiTxVector ackTxVector = GetAckTxVector (source, dataTxMode);
2075  WifiMacHeader ack;
2076  ack.SetType (WIFI_MAC_CTL_ACK);
2077  ack.SetDsNotFrom ();
2078  ack.SetDsNotTo ();
2079  ack.SetNoRetry ();
2080  ack.SetNoMoreFragments ();
2081  ack.SetAddr1 (source);
2082  duration -= GetAckDuration (ackTxVector);
2083  duration -= GetSifs ();
2084  NS_ASSERT (duration >= MicroSeconds (0));
2085  ack.SetDuration (duration);
2086 
2087  Ptr<Packet> packet = Create<Packet> ();
2088  packet->AddHeader (ack);
2089  WifiMacTrailer fcs;
2090  packet->AddTrailer (fcs);
2091 
2092  SnrTag tag;
2093  tag.Set (dataSnr);
2094  packet->AddPacketTag (tag);
2095 
2096  //since ACK is a control response it can't have format GF
2097  WifiPreamble preamble;
2098  if (ackTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
2099  preamble= WIFI_PREAMBLE_HT_MF;
2100  else
2101  preamble=WIFI_PREAMBLE_LONG;
2102  ForwardDown (packet, &ack, ackTxVector, preamble);
2103 }
2104 
2105 bool
2106 MacLow::IsInWindow (uint16_t seq, uint16_t winstart, uint16_t winsize)
2107 {
2108  return ((seq - winstart+ 4096) % 4096) < winsize;
2109 }
2110 
2111 bool
2113  {
2114  if (m_stationManager->HasHtSupported ())
2115  {
2116  Mac48Address originator = hdr.GetAddr2 ();
2117  uint8_t tid = 0;
2118  if (hdr.IsQosData ())
2119  tid = hdr.GetQosTid ();
2120  uint16_t seqNumber = hdr.GetSequenceNumber ();
2121  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
2122  if (it != m_bAckAgreements.end ())
2123  {
2124  //Implement HT immediate Block Ack support for HT Delayed Block Ack is not added yet
2125  if (!QosUtilsIsOldPacket ((*it).second.first.GetStartingSequence (), seqNumber))
2126  {
2127  StoreMpduIfNeeded (packet, hdr);
2128  if (!IsInWindow(hdr.GetSequenceNumber (), (*it).second.first.GetStartingSequence (), (*it).second.first.GetBufferSize ()))
2129  {
2130  uint16_t delta = (seqNumber - (*it).second.first.GetWinEnd()+ 4096) % 4096;
2131  if (delta > 1)
2132  {
2133  (*it).second.first.SetWinEnd (seqNumber);
2134  int16_t winEnd = (*it).second.first.GetWinEnd ();
2135  int16_t bufferSize = (*it).second.first.GetBufferSize ();
2136  uint16_t sum = ((uint16_t)(std::abs(winEnd - bufferSize + 1))) % 4096;
2137  (*it).second.first.SetStartingSequence (sum);
2138  RxCompleteBufferedPacketsWithSmallerSequence ((*it).second.first.GetStartingSequence (), originator, tid);
2139  }
2140  }
2141  RxCompleteBufferedPacketsUntilFirstLost (originator, tid); //forwards up packets starting from winstart and set winstart to last +1
2142  (*it).second.first.SetWinEnd(((*it).second.first.GetStartingSequence()+(*it).second.first.GetBufferSize()-1)%4096);
2143  }
2144  return true;
2145  }
2146  return false;
2147  }
2148  else
2149  return StoreMpduIfNeeded (packet,hdr);
2150 }
2151 
2152 bool
2154 {
2155  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
2156  if (it != m_bAckAgreements.end ())
2157  {
2158  WifiMacTrailer fcs;
2159  packet->RemoveTrailer (fcs);
2160  BufferedPacket bufferedPacket (packet, hdr);
2161 
2162  uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
2163  uint16_t mappedSeqControl = QosUtilsMapSeqControlToUniqueInteger (hdr.GetSequenceControl (), endSequence);
2164 
2165  BufferedPacketI i = (*it).second.second.begin ();
2166  for (; i != (*it).second.second.end ()
2167  && QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceControl (), endSequence) < mappedSeqControl; i++)
2168  {
2169  ;
2170  }
2171  (*it).second.second.insert (i, bufferedPacket);
2172 
2173  //Update block ack cache
2174  BlockAckCachesI j = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
2175  NS_ASSERT (j != m_bAckCaches.end ());
2176  (*j).second.UpdateWithMpdu (&hdr);
2177  return true;
2178  }
2179  return false;
2180 }
2181 
2182 void
2184  uint16_t startingSeq)
2185 {
2186  uint8_t tid = respHdr->GetTid ();
2187  BlockAckAgreement agreement (originator, tid);
2188  if (respHdr->IsImmediateBlockAck ())
2189  {
2190  agreement.SetImmediateBlockAck ();
2191  }
2192  else
2193  {
2194  agreement.SetDelayedBlockAck ();
2195  }
2196  agreement.SetAmsduSupport (respHdr->IsAmsduSupported ());
2197  agreement.SetBufferSize (respHdr->GetBufferSize () + 1);
2198  agreement.SetTimeout (respHdr->GetTimeout ());
2199  agreement.SetStartingSequence (startingSeq);
2200 
2201  std::list<BufferedPacket> buffer (0);
2202  AgreementKey key (originator, respHdr->GetTid ());
2203  AgreementValue value (agreement, buffer);
2204  m_bAckAgreements.insert (std::make_pair (key, value));
2205 
2206  BlockAckCache cache;
2207  cache.Init (startingSeq, respHdr->GetBufferSize () + 1);
2208  m_bAckCaches.insert (std::make_pair (key, cache));
2209 
2210  if (respHdr->GetTimeout () != 0)
2211  {
2212  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, respHdr->GetTid ()));
2213  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
2214 
2215  AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
2216 
2217  it->second.first.m_inactivityEvent = Simulator::Schedule (timeout,
2219  m_edcaListeners[ac],
2220  originator, tid);
2221  }
2222 }
2223 
2224 void
2226 {
2227  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
2228  if (it != m_bAckAgreements.end ())
2229  {
2230  RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (), originator, tid);
2231  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
2232  m_bAckAgreements.erase (it);
2233 
2234  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
2235  NS_ASSERT (i != m_bAckCaches.end ());
2236  m_bAckCaches.erase (i);
2237  }
2238 }
2239 
2240 void
2242 {
2243  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
2244  if (it != m_bAckAgreements.end ())
2245  {
2246  uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
2247  uint16_t mappedStart = QosUtilsMapSeqControlToUniqueInteger (seq, endSequence);
2248  BufferedPacketI last = (*it).second.second.begin ();
2249  uint16_t guard = 0;
2250  if (last != (*it).second.second.end ())
2251  {
2252  guard = (*it).second.second.begin ()->second.GetSequenceControl () & 0xfff0;
2253  }
2254  BufferedPacketI i = (*it).second.second.begin ();
2255  for (; i != (*it).second.second.end ()
2256  && QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceNumber (), endSequence) < mappedStart;)
2257  {
2258  if (guard == (*i).second.GetSequenceControl ())
2259  {
2260  if (!(*i).second.IsMoreFragments ())
2261  {
2262  while (last != i)
2263  {
2264  m_rxCallback ((*last).first, &(*last).second);
2265  last++;
2266  }
2267  m_rxCallback ((*last).first, &(*last).second);
2268  last++;
2269  /* go to next packet */
2270  while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
2271  {
2272  i++;
2273  }
2274  if (i != (*it).second.second.end ())
2275  {
2276  guard = (*i).second.GetSequenceControl () & 0xfff0;
2277  last = i;
2278  }
2279  }
2280  else
2281  {
2282  guard++;
2283  }
2284  }
2285  else
2286  {
2287  /* go to next packet */
2288  while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
2289  {
2290  i++;
2291  }
2292  if (i != (*it).second.second.end ())
2293  {
2294  guard = (*i).second.GetSequenceControl () & 0xfff0;
2295  last = i;
2296  }
2297  }
2298  }
2299  (*it).second.second.erase ((*it).second.second.begin (), i);
2300  }
2301 }
2302 
2303 void
2305 {
2306  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
2307  if (it != m_bAckAgreements.end ())
2308  {
2309  uint16_t startingSeqCtrl = ((*it).second.first.GetStartingSequence () << 4) & 0xfff0;
2310  uint16_t guard = startingSeqCtrl;
2311 
2312  BufferedPacketI lastComplete = (*it).second.second.begin ();
2313  BufferedPacketI i = (*it).second.second.begin ();
2314  for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
2315  {
2316  if (!(*i).second.IsMoreFragments ())
2317  {
2318  while (lastComplete != i)
2319  {
2320  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
2321  lastComplete++;
2322  }
2323  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
2324  lastComplete++;
2325  }
2326  guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
2327  }
2328  (*it).second.first.SetStartingSequence ((guard >> 4) & 0x0fff);
2329  /* All packets already forwarded to WifiMac must be removed from buffer:
2330  [begin (), lastComplete) */
2331  (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
2332  }
2333 }
2334 void
2335 MacLow::SendBlockAckResponse (const CtrlBAckResponseHeader* blockAck, Mac48Address originator, bool immediate,
2336  Time duration, WifiMode blockAckReqTxMode)
2337 {
2338  Ptr<Packet> packet = Create<Packet> ();
2339  packet->AddHeader (*blockAck);
2340 
2341  WifiMacHeader hdr;
2343  hdr.SetAddr1 (originator);
2344  hdr.SetAddr2 (GetAddress ());
2345  hdr.SetDsNotFrom ();
2346  hdr.SetDsNotTo ();
2347  hdr.SetNoRetry ();
2348  hdr.SetNoMoreFragments ();
2349 
2350  WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (originator, blockAckReqTxMode);
2351 
2352  m_currentPacket = packet;
2353  m_currentHdr = hdr;
2354  if (immediate)
2355  {
2357  duration -= GetSifs ();
2358  if (blockAck->IsBasic ())
2359  {
2360  duration -= GetBlockAckDuration (originator, blockAckReqTxVector, BASIC_BLOCK_ACK);
2361  }
2362  else if (blockAck->IsCompressed ())
2363  {
2364  duration -= GetBlockAckDuration (originator, blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
2365  }
2366  else if (blockAck->IsMultiTid ())
2367  {
2368  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
2369  }
2370  }
2371  else
2372  {
2373  m_txParams.EnableAck ();
2374  duration += GetSifs ();
2375  duration += GetAckDuration (originator, blockAckReqTxVector);
2376  }
2378 
2379  if (!immediate)
2380  {
2381  StartDataTxTimers (blockAckReqTxVector);
2382  }
2383 
2384  NS_ASSERT (duration >= MicroSeconds (0));
2385  hdr.SetDuration (duration);
2386  //here should be present a control about immediate or delayed block ack
2387  //for now we assume immediate
2388  packet->AddHeader (hdr);
2389  WifiMacTrailer fcs;
2390  packet->AddTrailer (fcs);
2391  WifiPreamble preamble;
2392  if (blockAckReqTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
2393  preamble= WIFI_PREAMBLE_HT_MF;
2394  else
2395  preamble=WIFI_PREAMBLE_LONG;
2396  ForwardDown (packet, &hdr, blockAckReqTxVector, preamble);
2397  m_currentPacket = 0;
2398 }
2399 void
2400 MacLow::SendBlockAckAfterAmpdu (uint8_t tid, Mac48Address originator, Time duration, WifiMode blockAckReqTxMode)
2401 {
2402  NS_LOG_FUNCTION (this);
2403  CtrlBAckResponseHeader blockAck;
2404  uint16_t seqNumber = 0;
2405  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
2406  NS_ASSERT (i != m_bAckCaches.end ());
2407  seqNumber = (*i).second.GetWinStart ();
2408 
2409  bool immediate = true;
2410  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
2411  blockAck.SetStartingSequence (seqNumber);
2412  blockAck.SetTidInfo (tid);
2413  immediate = (*it).second.first.IsImmediateBlockAck ();
2414  blockAck.SetType (COMPRESSED_BLOCK_ACK);
2415  NS_LOG_DEBUG ("Got Implicit block Ack Req with seq " << seqNumber);
2416  (*i).second.FillBlockAckBitmap (&blockAck);
2417 
2418  SendBlockAckResponse (&blockAck, originator, immediate, duration, blockAckReqTxMode);
2419 }
2420 
2421 void
2423  Time duration, WifiMode blockAckReqTxMode)
2424 {
2425  NS_LOG_FUNCTION (this);
2426  CtrlBAckResponseHeader blockAck;
2427  uint8_t tid = 0;
2428  bool immediate = false;
2429  if (!reqHdr.IsMultiTid ())
2430  {
2431  tid = reqHdr.GetTidInfo ();
2432  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
2433  if (it != m_bAckAgreements.end ())
2434  {
2435  blockAck.SetStartingSequence (reqHdr.GetStartingSequence ());
2436  blockAck.SetTidInfo (tid);
2437  immediate = (*it).second.first.IsImmediateBlockAck ();
2438  if (reqHdr.IsBasic ())
2439  {
2440  blockAck.SetType (BASIC_BLOCK_ACK);
2441  }
2442  else if (reqHdr.IsCompressed ())
2443  {
2444  blockAck.SetType (COMPRESSED_BLOCK_ACK);
2445  }
2446  BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
2447  NS_ASSERT (i != m_bAckCaches.end ());
2448  (*i).second.FillBlockAckBitmap (&blockAck);
2449  NS_LOG_DEBUG ("Got block Ack Req with seq " << reqHdr.GetStartingSequence ());
2450 
2451  if (!m_stationManager->HasHtSupported())
2452  {
2453  /* All packets with smaller sequence than starting sequence control must be passed up to Wifimac
2454  * See 9.10.3 in IEEE 802.11e standard.
2455  */
2457  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
2458  }
2459  else
2460  {
2461  if (!QosUtilsIsOldPacket ((*it).second.first.GetStartingSequence(), reqHdr.GetStartingSequence ()))
2462  {
2463  (*it).second.first.SetStartingSequence(reqHdr.GetStartingSequence ());
2464  (*it).second.first.SetWinEnd(((*it).second.first.GetStartingSequence()+(*it).second.first.GetBufferSize()-1) % 4096);
2466  RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
2467  (*it).second.first.SetWinEnd(((*it).second.first.GetStartingSequence()+(*it).second.first.GetBufferSize()-1) % 4096);
2468  }
2469  }
2470  }
2471  else
2472  {
2473  NS_LOG_DEBUG ("there's not a valid block ack agreement with " << originator);
2474  }
2475  }
2476  else
2477  {
2478  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
2479  }
2480 
2481  SendBlockAckResponse (&blockAck, originator, immediate, duration, blockAckReqTxMode);
2482 }
2483 
2484 void
2486 {
2487  if (agreement.GetTimeout () != 0)
2488  {
2489  NS_ASSERT (agreement.m_inactivityEvent.IsRunning ());
2490  agreement.m_inactivityEvent.Cancel ();
2491  Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
2492  AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
2493  //std::map<AcIndex, MacLowTransmissionListener*>::iterator it = m_edcaListeners.find (ac);
2494  //NS_ASSERT (it != m_edcaListeners.end ());
2495 
2496  agreement.m_inactivityEvent = Simulator::Schedule (timeout,
2498  m_edcaListeners[ac],
2499  agreement.GetPeer (),
2500  agreement.GetTid ());
2501  }
2502 }
2503 
2504 void
2506 {
2507  m_edcaListeners.insert (std::make_pair (ac, listener));
2508 }
2509 
2510 void
2512 {
2513  m_mpduAggregator = aggregator;
2514 }
2515 
2516 void
2517 MacLow::DeaggregateAmpduAndReceive (Ptr<Packet> aggregatedPacket, double rxSnr, WifiMode txMode, WifiPreamble preamble)
2518 {
2519  m_currentMode = txMode;
2520  AmpduTag ampdu;
2521  bool normalAck = false;
2522  bool ampduSubframe = false;
2523  if (aggregatedPacket->RemovePacketTag(ampdu))
2524  {
2525  ampduSubframe = true;
2527  MpduAggregator::DeaggregatedMpdusCI n = packets.begin ();
2528 
2529  WifiMacHeader firsthdr;
2530  (*n).first->PeekHeader(firsthdr);
2531  NS_LOG_DEBUG ("duration/id=" << firsthdr.GetDuration ());
2532  NotifyNav ((*n).first,firsthdr, txMode, preamble);
2533  if (firsthdr.GetAddr1 () == m_self)
2534  {
2535  m_receivedAtLeastOneMpdu = true;
2536  if (firsthdr.IsAck () || firsthdr.IsBlockAck () || firsthdr.IsBlockAckReq ())
2537  ReceiveOk ((*n).first, rxSnr, txMode, preamble, ampduSubframe);
2538  else if (firsthdr.IsData () || firsthdr.IsQosData ())
2539  {
2540  NS_LOG_DEBUG ("Deaagregate packet with sequence=" << firsthdr.GetSequenceNumber ());
2541  ReceiveOk ((*n).first, rxSnr, txMode, preamble, ampduSubframe);
2542  if (firsthdr.IsQosAck ())
2543  {
2544  NS_LOG_DEBUG ("Normal Ack");
2545  normalAck = true;
2546  }
2547  }
2548  else
2549  NS_FATAL_ERROR ("Received A-MPDU with invalid first MPDU type");
2550  }
2551 
2552  if (normalAck && (ampdu.GetNoOfMpdus () == 1))
2553  {
2554  //send block Ack
2555  if (firsthdr.IsBlockAckReq ())
2556  {
2557  NS_FATAL_ERROR ("Sending a BlockAckReq with QosPolicy equal to Normal Ack");
2558  }
2559  uint8_t tid = firsthdr.GetQosTid ();
2560  AgreementsI it = m_bAckAgreements.find (std::make_pair (firsthdr.GetAddr2 (), tid));
2561  if (it != m_bAckAgreements.end ())
2562  {
2564  /* See section 11.5.3 in IEEE 802.11 for mean of this timer */
2565  ResetBlockAckInactivityTimerIfNeeded (it->second.first);
2566  NS_LOG_DEBUG ("rx A-MPDU/sendImmediateBlockAck from=" << firsthdr.GetAddr2 ());
2569  firsthdr.GetQosTid(),
2570  firsthdr.GetAddr2 (),
2571  firsthdr.GetDuration (),
2572  txMode);
2573  }
2574  else
2575  {
2576  NS_LOG_DEBUG ("There's not a valid agreement for this block ack request.");
2577  }
2578  m_receivedAtLeastOneMpdu = false;
2579  }
2580  }
2581  else
2582  {
2583  ReceiveOk (aggregatedPacket,rxSnr, txMode, preamble, ampduSubframe);
2584  }
2585 }
2586 
2587 bool
2588 MacLow::StopAggregation(Ptr<const Packet> peekedPacket, WifiMacHeader peekedHdr, Ptr<Packet> aggregatedPacket, uint16_t size) const
2589 {
2590  WifiPreamble preamble;
2592  if (m_phy->GetGreenfield () && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
2593  preamble = WIFI_PREAMBLE_HT_GF;
2594  else
2595  preamble = WIFI_PREAMBLE_HT_MF;
2596 
2597  if (peekedPacket == 0)
2598  return true;
2599 
2600  //An HT STA shall not transmit a PPDU that has a duration that is greater than aPPDUMaxTime (10 milliseconds)
2601  if(m_phy->CalculateTxDuration (aggregatedPacket->GetSize () + peekedPacket->GetSize () + peekedHdr.GetSize () +WIFI_MAC_FCS_LENGTH,dataTxVector, preamble, m_phy->GetFrequency(), 0, 0) > MilliSeconds(10))
2602  return true;
2603 
2604  if (!m_mpduAggregator->CanBeAggregated (peekedPacket->GetSize () + peekedHdr.GetSize () + WIFI_MAC_FCS_LENGTH, aggregatedPacket, size))
2605  return true;
2606 
2607  return false;
2608 }
2609 
2612 {
2613  NS_ASSERT (m_aggregateQueue->GetSize () == 0);
2614  bool isAmpdu = false;
2615  Ptr<Packet> newPacket;
2616  WifiMacHeader peekedHdr;
2617  newPacket = packet->Copy();
2618  //missing hdr.IsAck() since we have no means of knowing the Tid of the Ack yet
2619  if (hdr.IsQosData() || hdr.IsBlockAck()|| hdr.IsBlockAckReq())
2620  {
2621  Time tstamp;
2622  uint8_t tid = GetTid (packet, hdr);
2623  Ptr<WifiMacQueue> queue;
2624  AcIndex ac = QosUtilsMapTidToAc (tid);
2625  //since a blockack agreement always preceeds mpdu aggregation there should always exist blockAck listener
2626  std::map<AcIndex, MacLowBlockAckEventListener*>::const_iterator listenerIt= m_edcaListeners.find(ac);
2627  NS_ASSERT (listenerIt != m_edcaListeners.end ());
2628  queue = listenerIt->second->GetQueue();
2629 
2630  if (!hdr.GetAddr1 ().IsBroadcast () && m_mpduAggregator!= 0)
2631  {
2632  //Have to make sure that their exist a block Ack agreement before sending an AMPDU (BlockAck Manager)
2633  if (listenerIt->second->GetBlockAckAgreementExists (hdr.GetAddr1(), tid))
2634  {
2635  /* here is performed mpdu aggregation */
2636  /* MSDU aggregation happened in edca if the user asked for it so m_currentPacket may contains a normal packet or a A-MSDU*/
2637  Ptr<Packet> currentAggregatedPacket = Create<Packet> ();
2638  peekedHdr = hdr;
2639  uint16_t startingSequenceNumber = 0;
2640  uint16_t currentSequenceNumber = 0;
2641  uint8_t qosPolicy = 0;
2642  uint16_t blockAckSize = 0;
2643  bool aggregated = false;
2644  int i = 0;
2645  Ptr<Packet> aggPacket = newPacket->Copy ();
2646 
2647  if (!hdr.IsBlockAckReq())
2648  {
2649  if (!hdr.IsBlockAck())
2650  {
2651  startingSequenceNumber = peekedHdr.GetSequenceNumber();
2652  peekedHdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
2653  }
2654  currentSequenceNumber = peekedHdr.GetSequenceNumber();
2655  newPacket->AddHeader (peekedHdr);
2656  WifiMacTrailer fcs;
2657  newPacket->AddTrailer (fcs);
2658 
2659  aggregated=m_mpduAggregator->Aggregate (newPacket, currentAggregatedPacket);
2660 
2661  if (aggregated)
2662  {
2663  NS_LOG_DEBUG ("Adding packet with Sequence number " << peekedHdr.GetSequenceNumber()<<" to A-MPDU");
2664  i++;
2665  m_sentMpdus++;
2666  m_aggregateQueue->Enqueue (aggPacket, peekedHdr);
2667  }
2668  }
2669  else if (hdr.IsBlockAckReq())
2670  {
2671  blockAckSize = packet->GetSize() + hdr.GetSize() + WIFI_MAC_FCS_LENGTH;
2672  qosPolicy = 3; //if the last subrame is block ack req then set ack policy of all frames to blockack
2673  CtrlBAckRequestHeader blockAckReq;
2674  packet->PeekHeader (blockAckReq);
2675  startingSequenceNumber = blockAckReq.GetStartingSequence ();
2676  }
2677  aggregated = false;
2678  bool retry = false;
2679  //looks for other packets to the same destination with the same Tid need to extend that to include MSDUs
2680  Ptr<const Packet> peekedPacket = listenerIt->second->PeekNextPacketInBaQueue (peekedHdr, peekedHdr.GetAddr1 (), tid, &tstamp);
2681  if (peekedPacket == 0)
2682  {
2683  peekedPacket = queue->PeekByTidAndAddress (&peekedHdr, tid,
2685  hdr.GetAddr1 (), &tstamp);
2686  currentSequenceNumber = listenerIt->second->PeekNextSequenceNumberfor (&peekedHdr);
2687  }
2688  else
2689  {
2690  retry = true;
2691  currentSequenceNumber = peekedHdr.GetSequenceNumber();
2692  }
2693 
2694  while (IsInWindow (currentSequenceNumber, startingSequenceNumber, 64) && !StopAggregation (peekedPacket, peekedHdr, currentAggregatedPacket, blockAckSize))
2695  {
2696  //for now always send AMPDU with normal ACK
2697  if (retry == false)
2698  {
2699  currentSequenceNumber = listenerIt->second->GetNextSequenceNumberfor (&peekedHdr);
2700  peekedHdr.SetSequenceNumber (currentSequenceNumber);
2701  peekedHdr.SetFragmentNumber (0);
2702  peekedHdr.SetNoMoreFragments ();
2703  peekedHdr.SetNoRetry ();
2704  }
2705  if (qosPolicy == 0)
2706  peekedHdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
2707  else
2708  peekedHdr.SetQosAckPolicy (WifiMacHeader::BLOCK_ACK);
2709 
2710  newPacket = peekedPacket->Copy ();
2711  Ptr<Packet> aggPacket = newPacket->Copy ();
2712 
2713  newPacket->AddHeader (peekedHdr);
2714  WifiMacTrailer fcs;
2715  newPacket->AddTrailer (fcs);
2716  aggregated = m_mpduAggregator->Aggregate (newPacket, currentAggregatedPacket);
2717  if (aggregated)
2718  {
2719  m_aggregateQueue->Enqueue (aggPacket, peekedHdr);
2720  if (i == 1 && hdr.IsQosData ())
2721  {
2722  listenerIt->second->CompleteMpduTx (packet, hdr, tstamp);
2723  }
2724  NS_LOG_DEBUG ("Adding packet with Sequence number " << peekedHdr.GetSequenceNumber()<<" to A-MPDU");
2725  i++;
2726  isAmpdu = true;
2727  m_sentMpdus++;
2728  listenerIt->second->CompleteMpduTx (peekedPacket, peekedHdr, tstamp);
2729  if (retry)
2730  listenerIt->second->RemoveFromBaQueue(tid, hdr.GetAddr1 (), peekedHdr.GetSequenceNumber ());
2731  else
2732  queue->Remove (peekedPacket);
2733  newPacket = 0;
2734  }
2735  else
2736  break;
2737  if (retry == true)
2738  {
2739  peekedPacket = listenerIt->second->PeekNextPacketInBaQueue(peekedHdr, hdr.GetAddr1(), tid, &tstamp);
2740  if (peekedPacket == 0)
2741  {
2742  //I reached the first packet that I added to this A-MPDU
2743  retry = false;
2744  peekedPacket = queue->PeekByTidAndAddress (&peekedHdr, tid,
2745  WifiMacHeader::ADDR1, hdr.GetAddr1 (), &tstamp);
2746  if (peekedPacket != 0)
2747  {
2748  //find what will the sequence number be so that we don't send more than 64 packets apart
2749  currentSequenceNumber = listenerIt->second->PeekNextSequenceNumberfor (&peekedHdr);
2750  }
2751  }
2752  else
2753  currentSequenceNumber = peekedHdr.GetSequenceNumber();
2754  }
2755  else
2756  {
2757  peekedPacket = queue->PeekByTidAndAddress (&peekedHdr, tid,
2758  WifiMacHeader::ADDR1, hdr.GetAddr1 (), &tstamp);
2759  if (peekedPacket != 0)
2760  {
2761  //find what will the sequence number be so that we don't send more than 64 packets apart
2762  currentSequenceNumber = listenerIt->second->PeekNextSequenceNumberfor (&peekedHdr);
2763  }
2764  }
2765  }
2766  if (isAmpdu)
2767  {
2768  if (hdr.IsBlockAckReq())
2769  {
2770  newPacket = packet->Copy();
2771  peekedHdr = hdr;
2772  Ptr<Packet> aggPacket = newPacket->Copy();
2773  m_aggregateQueue->Enqueue (aggPacket, peekedHdr);
2774  newPacket->AddHeader (peekedHdr);
2775  WifiMacTrailer fcs;
2776  newPacket->AddTrailer (fcs);
2777  m_mpduAggregator->Aggregate (newPacket, currentAggregatedPacket);
2778  }
2779  if (qosPolicy==0)
2780  {
2781  listenerIt->second->CompleteTransfer(hdr.GetAddr1 (),tid);
2782  }
2783  //Add packet tag
2784  AmpduTag ampdutag;
2785  ampdutag.SetAmpdu (true);
2786  ampdutag.SetNoOfMpdus(i);
2787  newPacket = currentAggregatedPacket;
2788  newPacket->AddPacketTag(ampdutag);
2789  currentAggregatedPacket = 0;
2790  NS_LOG_DEBUG ("tx unicast A-MPDU");
2791  listenerIt->second->SetAmpdu(true);
2792  }
2793  else
2794  {
2795  uint32_t queueSize = m_aggregateQueue->GetSize ();
2796  NS_ASSERT (queueSize <= 2); //since it is not an A-MPDU then only 2 packets should have been added to the queue no more
2797  if (queueSize >= 1)
2798  {
2799  //remove any packets that we added to the aggregate queue
2801  }
2802  }
2803  }
2804  }
2805  }
2806  return newPacket;
2807 }
2808 
2809 void
2811 {
2812  NS_LOG_DEBUG("Flush aggregate queue");
2813  m_aggregateQueue->Flush ();
2814 }
2815 
2816 } // 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:226
Time GetPifs(void) const
Return PCF Interframe Space (PIFS) of this MacLow.
Definition: mac-low.cc:623
uint32_t GetAckSize(void) const
Return the total ACK size (including FCS trailer).
Definition: mac-low.cc:1131
virtual ~MacLowDcfListener()
Definition: mac-low.cc:67
void SetPifs(Time pifs)
Set PCF Interframe Space (PIFS) of this MacLow.
Definition: mac-low.cc:563
Time m_ctsTimeout
CTS timeout duration.
Definition: mac-low.h:1284
uint16_t GetBufferSize(void) const
Return the buffer size.
Definition: mgt-headers.cc:947
virtual uint32_t GetFrequency(void) const =0
uint8_t GetTid(void) const
Return the Traffic ID (TID).
virtual uint32_t GetNOutstandingPackets(Mac48Address recipient, uint8_t tid)
Definition: mac-low.cc:108
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:1270
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 "...
Ptr< WifiPhy > GetPhy(void) const
Definition: mac-low.cc:499
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:2485
enum ns3::MacLowTransmissionParameters::@89 m_waitAck
EventId m_blockAckTimeoutEvent
Block ACK timeout event.
Definition: mac-low.h:1263
Time GetBlockAckDuration(Mac48Address to, WifiTxVector blockAckReqTxVector, enum BlockAckType type) const
Return the time required to transmit the Block ACK to the specified address given the TXVECTOR of the...
Definition: mac-low.cc:1182
Callback template class.
Definition: callback.h:978
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:53
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:1172
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:578
EventId m_waitSifsEvent
Wait for SIFS event.
Definition: mac-low.h:1268
void SendDataAfterCts(Mac48Address source, Time duration, WifiMode txMode)
Send DATA after receiving CTS.
Definition: mac-low.cc:1970
void DoNavResetNow(Time duration)
Reset NAV with the given duration.
Definition: mac-low.cc:1404
bool IsPromisc(void) const
Check if MacLow is operating in promiscuous mode.
Definition: mac-low.cc:633
bool m_receivedAtLeastOneMpdu
Flag whether an MPDU has already been successfully received while receiving an A-MPDU.
Definition: mac-low.h:1322
void EnableBasicBlockAck(void)
Wait BASICBLOCKACKTimeout for a Basic Block Ack Response frame.
Definition: mac-low.cc:151
Mac48Address GetPeer(void) const
Return the peer address.
EventId m_fastAckTimeoutEvent
Fast ACK timeout event.
Definition: mac-low.h:1260
Time m_pifs
PCF Interframe Space (PIFS) duration.
Definition: mac-low.h:1287
void ReceiveOk(Ptr< Packet > packet, double rxSnr, WifiMode txMode, WifiPreamble preamble, bool ampduSubframe)
Definition: mac-low.cc:811
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:836
bool DoNavStartNow(Time duration)
Start NAV with the given duration.
Definition: mac-low.cc:1414
void FastAckFailedTimeout(void)
Event handler when fast ACK timeout occurs (busy).
Definition: mac-low.cc:2058
Mac48Address GetBssid(void) const
Return the Basic Service Set Identification.
Definition: mac-low.cc:628
void SetSifs(Time sifs)
Set Short Interframe Space (SIFS) of this MacLow.
Definition: mac-low.cc:553
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:1304
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:1236
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:372
#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)
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octects of the IEEE 802.11 MAC FCS field.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
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:313
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:867
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...
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:766
static DeaggregatedMpdus Deaggregate(Ptr< Packet > aggregatedPacket)
Deaggregates an A-MPDU by removing the A-MPDU subframe header and padding.
bool IsBroadcast(void) const
bool StopAggregation(Ptr< const Packet > peekedPacket, WifiMacHeader peekedHdr, Ptr< Packet > aggregatedPacket, uint16_t size) const
Definition: mac-low.cc:2588
void NotifySleepNow(void)
This method is typically invoked by the PhyMacLowListener to notify the MAC layer that the device has...
Definition: mac-low.cc:796
uint8_t GetTid(Ptr< const Packet > packet, const WifiMacHeader hdr) const
Definition: mac-low.cc:1110
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:231
std::list< std::pair< Ptr< Packet >, AmpduSubframeHeader > >::const_iterator DeaggregatedMpdusCI
A constant iterator for a list of deaggregated packets and their A-MPDU subframe headers.
#define NS_FATAL_ERROR(msg)
Fatal error handling.
Definition: fatal-error.h:100
bool QosUtilsIsOldPacket(uint16_t startingSeq, uint16_t seqNumber)
This function checks if packet with sequence number seqNumber is an "old" packet. ...
Definition: qos-utils.cc:86
DcfListeners m_dcfListeners
List of MacLowDcfListener (pass events to Dcf)
Definition: mac-low.h:1257
uint8_t m_sentMpdus
Number of transmitted MPDUs in an A-MPDU that have not been acknowledged yet.
Definition: mac-low.h:1319
bool IsBlockAck(void) const
Return true if the header is a Block ACK header.
bool m_ampdu
Flag if the current transmission involves an A-MPDU.
Definition: mac-low.h:1294
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:65
void SetRxCallback(Callback< void, Ptr< Packet >, const WifiMacHeader * > callback)
Definition: mac-low.cc:639
Time GetCompressedBlockAckTimeout() const
Return Compressed Block ACK timeout of this MacLow.
Definition: mac-low.cc:598
Callback< R > MakeNullCallback(void)
Definition: callback.h:1436
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:819
Mac48Address m_bssid
BSSID address (Mac48Address)
Definition: mac-low.h:1280
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
Ptr< Packet > AggregateToAmpdu(Ptr< const Packet > packet, const WifiMacHeader hdr)
Definition: mac-low.cc:2611
EventId m_sendCtsEvent
Event to send CTS.
Definition: mac-low.h:1265
MacLowRxCallback m_rxCallback
Callback to pass packet up.
Definition: mac-low.h:1248
Time GetCtsTimeout(void) const
Return CTS timeout of this MacLow.
Definition: mac-low.cc:603
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:1261
EventId m_sendAckEvent
Event to send ACK.
Definition: mac-low.h:1266
listen to events coming from ns3::MacLow.
Definition: mac-low.h:58
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:93
void SendBlockAckAfterAmpdu(uint8_t tid, Mac48Address originator, Time duration, WifiMode blockAckReqTxMode)
Invoked after an A-MPDU has been received.
Definition: mac-low.cc:2400
Time GetCtsDuration(WifiTxVector ctsTxVector) const
Return the time required to transmit the CTS (including preamble and FCS).
Definition: mac-low.cc:1207
bool MustWaitFastAck(void) const
Definition: mac-low.cc:201
virtual void CompleteTransfer(Mac48Address address, uint8_t tid)
Definition: mac-low.cc:81
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:285
void WaitSifsAfterEndTx(void)
Event handler that is usually scheduled to fired at the appropriate time after completing transmissio...
Definition: mac-low.cc:2044
std::vector< MacLowDcfListener * >::const_iterator DcfListenersCI
typedef for an iterator for a list of MacLowDcfListener.
Definition: mac-low.h:1252
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:538
void NormalAckTimeout(void)
Event handler when normal ACK timeout occurs.
Definition: mac-low.cc:1551
void SetBasicBlockAckTimeout(Time blockAckTimeout)
Set Basic Block ACK timeout of this MacLow.
Definition: mac-low.cc:528
bool IsAmsduSupported(void) const
Return whether A-MSDU capability is supported.
Definition: mgt-headers.cc:953
void SetNoOfMpdus(uint8_t noofmpdus)
Definition: ampdu-tag.cc:60
BlockAckCaches m_bAckCaches
Definition: mac-low.h:1314
virtual uint16_t PeekNextSequenceNumberfor(WifiMacHeader *hdr)
Return the next sequence number for the Traffic ID and destination, but do not pick it (i...
Definition: mac-low.cc:94
virtual bool IsStateIdle(void)=0
Time GetDuration(void) const
Return the duration from the Duration/ID field (Time object).
virtual void CompleteMpduTx(Ptr< const Packet > packet, WifiMacHeader hdr, Time tstamp)
This function stores an MPDU (part of an A-MPDU) in blockackagreement (i.e.
Definition: mac-low.cc:85
void RemovePhyMacLowListener(Ptr< WifiPhy > phy)
Remove current WifiPhy listener for this MacLow.
Definition: mac-low.cc:379
virtual void GotBlockAck(const CtrlBAckResponseHeader *blockAck, Mac48Address source, WifiMode txMode)
Definition: mac-low.cc:57
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.
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
void DestroyBlockAckAgreement(Mac48Address originator, uint8_t tid)
Definition: mac-low.cc:2225
Time m_lastNavDuration
The duration of the latest NAV.
Definition: mac-low.h:1291
virtual uint32_t GetSerializedSize(void) const
std::pair< Ptr< Packet >, WifiMacHeader > BufferedPacket
Definition: mac-low.h:1301
void SendCtsToSelf(void)
Send CTS for a CTS-to-self mechanism.
Definition: mac-low.cc:1846
bool m_ctsToSelfSupported
Flag whether CTS-to-self is supported.
Definition: mac-low.h:1318
void SetAmpdu(bool supported)
Set m_ampdu to 1.
Definition: ampdu-tag.cc:54
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:2068
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:2183
Ptr< WifiMacQueue > m_aggregateQueue
Queue used for MPDU aggregation.
Definition: mac-low.h:1320
virtual void NotifyTxStart(Time duration, double txPowerDbm)
Definition: mac-low.cc:316
WifiMode m_currentMode
mode used for the current packet transmission
Definition: mac-low.h:1321
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:1138
Listener for PHY events.
Definition: mac-low.cc:292
virtual void NotifyWakeup(void)
Notify listeners that we woke up.
Definition: mac-low.cc:330
receive notifications about phy events.
Definition: wifi-phy.h:44
void CtsTimeout(void)
Event handler when CTS timeout occurs.
Definition: mac-low.cc:1532
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:2050
std::map< AgreementKey, BlockAckCache >::iterator BlockAckCachesI
Definition: mac-low.h:1311
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:1262
virtual void SetAmpdu(bool ampdu)
Definition: mac-low.cc:78
void SetAckTimeout(Time ackTimeout)
Set ACK timeout of this MacLow.
Definition: mac-low.cc:523
virtual void SendPacket(Ptr< const Packet > packet, WifiTxVector txvector, enum WifiPreamble preamble, uint8_t packetType)=0
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:2335
Time GetRifs(void) const
Return Reduced Interframe Space (RIFS) of this MacLow.
Definition: mac-low.cc:613
HT PHY (Clause 20)
Definition: wifi-mode.h:56
virtual void NotifyRxStart(Time duration)
Definition: mac-low.cc:307
virtual void NotifySleep(void)
Notify listeners that we went to sleep.
Definition: mac-low.cc:326
void NavCounterResetCtsMissed(Time rtsEndRxTime)
Reset NAV after CTS was missed when the NAV was setted with RTS.
Definition: mac-low.cc:1395
Ptr< WifiRemoteStationManager > m_stationManager
Pointer to WifiRemoteStationManager (rate control)
Definition: mac-low.h:1247
bool MustWaitMultiTidBlockAck(void) const
Definition: mac-low.cc:221
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:1290
Mac48Address GetAddress(void) const
Return the MAC address of this MacLow.
Definition: mac-low.cc:583
uint32_t GetNextPacketSize(void) const
Definition: mac-low.cc:247
Agreements m_bAckAgreements
Definition: mac-low.h:1313
bool HasNextPacket(void) const
Definition: mac-low.cc:242
The aim of the AmpduTag is to provide means for a MAC to specify that a packet includes A-MPDU since ...
Definition: ampdu-tag.h:35
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:1278
virtual void RemoveFromBaQueue(uint8_t tid, Mac48Address recipient, uint16_t seqnumber)
Remove a packet after you peek in the retransmit queue and get it.
Definition: mac-low.cc:104
Time CalculateTxDuration(uint32_t size, WifiTxVector txvector, enum WifiPreamble preamble, double frequency, uint8_t packetType, uint8_t incFlag)
Definition: wifi-phy.cc:576
bool IsMgt(void) const
Return true if the Type is Management.
void RegisterDcfListener(MacLowDcfListener *listener)
Definition: mac-low.cc:644
virtual uint32_t GetSerializedSize(void) const
void NotifySwitchingStartNow(Time duration)
Definition: mac-low.cc:780
Time m_slotTime
Slot duration.
Definition: mac-low.h:1286
bool m_promisc
Flag if the device is operating in promiscuous mode.
Definition: mac-low.h:1293
void CancelAllEvents(void)
Cancel all scheduled events.
Definition: mac-low.cc:419
virtual void StartTransmission(Ptr< const Packet > packet, const WifiMacHeader *hdr, MacLowTransmissionParameters parameters, MacLowTransmissionListener *listener)
Definition: mac-low.cc:667
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
std::list< BufferedPacket >::iterator BufferedPacketI
Definition: mac-low.h:1302
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
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:277
void BlockAckTimeout(void)
Event handler when block ACK timeout occurs.
Definition: mac-low.cc:1583
void NotifyCtsTimeoutStartNow(Time duration)
Notify DcfManager (via DcfListener) that CTS timer should be started for the given duration...
Definition: mac-low.cc:1447
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:2422
virtual uint32_t GetNRetryNeededPackets(Mac48Address recipient, uint8_t tid) const
Definition: mac-low.cc:113
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:156
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SuperFastAckTimeout(void)
Event handler when super fast ACK timeout occurs.
Definition: mac-low.cc:1596
void SetBssid(Mac48Address ad)
Set the Basic Service Set Identification.
Definition: mac-low.cc:573
virtual void UnregisterListener(WifiPhyListener *listener)=0
listen for block ack events.
Definition: mac-low.h:191
uint32_t GetRtsSize(void) const
Return the total RTS size (including FCS trailer).
Definition: mac-low.cc:1159
bool IsGroup(void) const
void EnableAck(void)
Wait ACKTimeout for an ACK.
Definition: mac-low.cc:171
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:1330
virtual uint16_t GetNextSequenceNumberfor(WifiMacHeader *hdr)
Return the next sequence number for the given header.
Definition: mac-low.cc:89
EventId m_normalAckTimeoutEvent
Normal ACK timeout event.
Definition: mac-low.h:1259
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:1695
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:1455
bool MustWaitBasicBlockAck(void) const
Definition: mac-low.cc:211
bool MustWaitCompressedBlockAck(void) const
Definition: mac-low.cc:216
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:734
an EUI-48 address
Definition: mac48-address.h:43
virtual ~MacLowBlockAckEventListener()
Definition: mac-low.cc:74
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:1281
bool IsInWindow(uint16_t seq, uint16_t winstart, uint16_t winsize)
Definition: mac-low.cc:2106
listen to NAV eventsThis class is typically connected to an instance of ns3::Dcf and calls to its met...
Definition: mac-low.h:148
void FastAckTimeout(void)
Event handler when fast ACK timeout occurs (idle).
Definition: mac-low.cc:1566
void DisableRts(void)
Do not send rts and wait for cts before sending data.
Definition: mac-low.cc:186
void EnableMultiTidBlockAck(void)
NOT IMPLEMENTED FOR NOW.
Definition: mac-low.cc:161
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:223
EventId m_ctsTimeoutEvent
CTS timeout event.
Definition: mac-low.h:1264
void RxCompleteBufferedPacketsWithSmallerSequence(uint16_t seq, Mac48Address originator, uint8_t tid)
Definition: mac-low.cc:2241
void SetPhy(Ptr< WifiPhy > phy)
Set up WifiPhy associated with this MacLow.
Definition: mac-low.cc:491
virtual bool IsStateTx(void)=0
Time m_basicBlockAckTimeout
Basic block ACK timeout duration.
Definition: mac-low.h:1282
Time GetDurationId(void) const
Definition: mac-low.cc:236
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:61
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
Time m_sifs
Short Interframe Space (SIFS) duration.
Definition: mac-low.h:1285
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:740
Time GetSlotTime(void) const
Return slot duration of this MacLow.
Definition: mac-low.cc:618
void SetDelayedBlockAck(void)
Set Block ACK policy to delayed ACK.
Time m_lastNavStart
The time when the latest NAV started.
Definition: mac-low.h:1290
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support.
virtual void NotifyMaybeCcaBusyStart(Time duration)
Definition: mac-low.cc:319
WifiTxVector GetRtsTxVector(Ptr< const Packet > packet, const WifiMacHeader *hdr) const
Return a TXVECTOR for the RTS frame given the destination.
Definition: mac-low.cc:1242
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:1248
handle RTS/CTS/DATA/ACK transactions.
Definition: mac-low.h:475
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:1267
bool ReceiveMpdu(Ptr< Packet > packet, WifiMacHeader hdr)
This method updates the reorder buffer and the scoreboard when an MPDU is received in an HT station a...
Definition: mac-low.cc:2112
MacLowTransmissionParameters m_txParams
Transmission parameters of the current packet.
Definition: mac-low.h:1277
void SetRifs(Time rifs)
Set Reduced Interframe Space (RIFS) of this MacLow.
Definition: mac-low.cc:568
virtual void DoDispose(void)
Destructor implementation.
Definition: mac-low.cc:390
void NotifyAckTimeoutResetNow()
Notify DcfManager (via DcfListener) that ACK timer should be resetted.
Definition: mac-low.cc:1439
bool MustWaitSuperFastAck(void) const
Definition: mac-low.cc:206
Time CalculateOverallTxTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters &params) const
Definition: mac-low.cc:1285
QueueListeners m_edcaListeners
Definition: mac-low.h:1317
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:1267
bool IsData(void) const
Return true if the Type is DATA.
Mac48Address m_self
Address of this MacLow (Mac48Address)
Definition: mac-low.h:1279
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:1262
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:1834
void EnableRts(void)
Send a RTS, and wait CTSTimeout for a CTS.
Definition: mac-low.cc:181
void NotifyAckTimeoutStartNow(Time duration)
Notify DcfManager (via DcfListener) that ACK timer should be started for the given duration...
Definition: mac-low.cc:1431
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:558
Ptr< Packet > m_currentPacket
Current packet transmitted/to be transmitted.
Definition: mac-low.h:1275
Time GetSifs(void) const
Return Short Interframe Space (SIFS) of this MacLow.
Definition: mac-low.cc:608
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:843
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:1933
ns3::MacLow * m_macLow
Definition: mac-low.cc:334
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:859
std::map< AgreementKey, AgreementValue >::iterator AgreementsI
Definition: mac-low.h:1308
EventId m_endTxNoAckEvent
Event for finishing transmission that does not require ACK.
Definition: mac-low.h:1269
void SendPacket(Ptr< const Packet > packet, WifiTxVector txVector, WifiPreamble preamble, uint8_t packetType)
Forward the packet down to WifiPhy for transmission.
Definition: mac-low.cc:1525
void EnableOverrideDurationId(Time durationId)
Definition: mac-low.cc:136
virtual void SetReceiveOkCallback(RxOkCallback callback)=0
bool GetCtsToSelfSupported() const
Return whether CTS-to-self capability is supported.
Definition: mac-low.cc:543
std::list< std::pair< Ptr< Packet >, AmpduSubframeHeader > > DeaggregatedMpdus
A list of deaggregated packets and their A-MPDU subframe headers.
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
void SetCtsTimeout(Time ctsTimeout)
Set CTS timeout of this MacLow.
Definition: mac-low.cc:548
void EnableNextData(uint32_t size)
Definition: mac-low.cc:126
void SetImmediateBlockAck(void)
Set Block ACK policy to immediate ACK.
void DeaggregateAmpduAndReceive(Ptr< Packet > aggregatedPacket, double rxSnr, WifiMode txMode, WifiPreamble preamble)
Definition: mac-low.cc:2517
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:141
Time GetAckTimeout(void) const
Return ACK timeout of this MacLow.
Definition: mac-low.cc:588
EventId m_waitRifsEvent
Wait for RIFS event.
Definition: mac-low.h:1271
void DisableNextData(void)
Do not attempt to send data burst after current transmission.
Definition: mac-low.cc:131
void SendDataPacket(void)
Send DATA packet, which can be DATA-ACK or RTS-CTS-DATA-ACK transaction.
Definition: mac-low.cc:1767
void SetTimeout(uint16_t timeout)
Set timeout.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:875
uint32_t GetCtsSize(void) const
Return the total CTS size (including FCS trailer).
Definition: mac-low.cc:1217
WifiMacHeader m_currentHdr
Header of the current packet.
Definition: mac-low.h:1276
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:518
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.
tuple address
Definition: first.py:37
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:1464
PhyMacLowListener(ns3::MacLow *macLow)
Create a PhyMacLowListener for the given MacLow.
Definition: mac-low.cc:300
Time m_compressedBlockAckTimeout
Compressed block ACK timeout duration.
Definition: mac-low.h:1283
WifiMode GetMode(void) const
bool MustWaitAck(void) const
Definition: mac-low.cc:191
virtual Ptr< const Packet > PeekNextPacketInBaQueue(WifiMacHeader &header, Mac48Address recipient, uint8_t tid, Time *timestamp)
Definition: mac-low.cc:99
bool IsRts(void) const
Return true if the header is a RTS header.
Headers for Block ack request.
Definition: ctrl-headers.h:49
bool IsAmpdu(Ptr< const Packet > packet, const WifiMacHeader hdr)
Checks if the given packet will be aggregated to an A-MPDU or not.
Definition: mac-low.cc:650
bool IsAck(void) const
Return true if the header is an ACK header.
void FlushAggregateQueue(void)
This function is called to flush the aggregate queue, which is used for A-MPDU.
Definition: mac-low.cc:2810
void RegisterBlockAckListenerForAc(enum AcIndex ac, MacLowBlockAckEventListener *listener)
Definition: mac-low.cc:2505
virtual ~PhyMacLowListener()
Definition: mac-low.cc:304
void ResetPhy(void)
Remove WifiPhy associated with this MacLow.
Definition: mac-low.cc:504
void DisableAck(void)
Do not wait for Ack after data transmission.
Definition: mac-low.cc:176
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:59
std::pair< BlockAckAgreement, std::list< BufferedPacket > > AgreementValue
Definition: mac-low.h:1305
virtual void NotifySwitchingStart(Time duration)
Definition: mac-low.cc:322
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:1273
void SetBufferSize(uint16_t bufferSize)
Set buffer size.
Time GetBasicBlockAckTimeout() const
Return Basic Block ACK timeout of this MacLow.
Definition: mac-low.cc:593
void NotifyNav(Ptr< const Packet > packet, const WifiMacHeader &hdr, WifiMode txMode, WifiPreamble preamble)
Definition: mac-low.cc:1353
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:1288
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:1257
uint8_t GetNoOfMpdus(void) const
Definition: ampdu-tag.cc:93
Introspection did not find any typical Config paths.
Definition: snr-tag.h:34
bool StoreMpduIfNeeded(Ptr< Packet > packet, WifiMacHeader hdr)
This method checks if exists a valid established block ack agreement.
Definition: mac-low.cc:2153
bool MustWaitNormalAck(void) const
Definition: mac-low.cc:196
virtual bool GetGreenfield(void) const =0
virtual ~MacLow()
Definition: mac-low.cc:366
Ptr< MpduAggregator > m_mpduAggregator
Definition: mac-low.h:1273
Ptr< WifiPhy > m_phy
Pointer to WifiPhy (actually send/receives frames)
Definition: mac-low.h:1246
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:533
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:310
void SetWifiRemoteStationManager(Ptr< WifiRemoteStationManager > manager)
Set up WifiRemoteStationManager associated with this MacLow.
Definition: mac-low.cc:512
bool IsQosAck(void) const
Return if the QoS ACK policy is Normal ACK.
class PhyMacLowListener * m_phyMacLowListener
Listener needed to monitor when a channel switching occurs.
Definition: mac-low.h:1296
void SetMpduAggregator(Ptr< MpduAggregator > aggregator)
Set up MpduAggregator associated with this MacLow.
Definition: mac-low.cc:2511
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:1224
MacLowTransmissionListener * m_listener
Transmission listener for the current packet.
Definition: mac-low.h:1278
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:1615
void RxCompleteBufferedPacketsUntilFirstLost(Mac48Address originator, uint8_t tid)
Definition: mac-low.cc:2304
uint16_t GetSequenceNumber(void) const
Return the sequence number of the header.