src/wifi/model/mac-low.cc
changeset 6852 8f1a53d3f6ca
parent 6848 1f453ad50ef3
child 7045 d13fa06886ce
equal deleted inserted replaced
6851:7fdad61b88f1 6852:8f1a53d3f6ca
       
     1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
       
     2 /*
       
     3  * Copyright (c) 2005,2006 INRIA
       
     4  * Copyright (c) 2009 MIRKO BANCHI
       
     5  *
       
     6  * This program is free software; you can redistribute it and/or modify
       
     7  * it under the terms of the GNU General Public License version 2 as 
       
     8  * published by the Free Software Foundation;
       
     9  *
       
    10  * This program is distributed in the hope that it will be useful,
       
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    13  * GNU General Public License for more details.
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License
       
    16  * along with this program; if not, write to the Free Software
       
    17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    18  *
       
    19  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
       
    20  * Author: Mirko Banchi <mk.banchi@gmail.com>
       
    21  */
       
    22 
       
    23 #include "ns3/assert.h"
       
    24 #include "ns3/packet.h"
       
    25 #include "ns3/simulator.h"
       
    26 #include "ns3/tag.h"
       
    27 #include "ns3/log.h"
       
    28 #include "ns3/node.h"
       
    29 #include "ns3/double.h"
       
    30 
       
    31 #include "mac-low.h"
       
    32 #include "wifi-phy.h"
       
    33 #include "wifi-mac-trailer.h"
       
    34 #include "qos-utils.h"
       
    35 #include "edca-txop-n.h"
       
    36 
       
    37 NS_LOG_COMPONENT_DEFINE ("MacLow");
       
    38 
       
    39 #undef NS_LOG_APPEND_CONTEXT
       
    40 #define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] "
       
    41 
       
    42 
       
    43 namespace ns3 {
       
    44 
       
    45 class SnrTag : public Tag
       
    46 {
       
    47 public:
       
    48 
       
    49   static TypeId GetTypeId (void);
       
    50   virtual TypeId GetInstanceTypeId (void) const;
       
    51 
       
    52   virtual uint32_t GetSerializedSize (void) const;
       
    53   virtual void Serialize (TagBuffer i) const;
       
    54   virtual void Deserialize (TagBuffer i);
       
    55   virtual void Print (std::ostream &os) const;
       
    56 
       
    57   void Set (double snr);
       
    58   double Get (void) const;
       
    59 private:
       
    60   double m_snr;
       
    61 };
       
    62 
       
    63 TypeId 
       
    64 SnrTag::GetTypeId (void)
       
    65 {
       
    66   static TypeId tid = TypeId ("ns3::SnrTag")
       
    67     .SetParent<Tag> ()
       
    68     .AddConstructor<SnrTag> ()
       
    69     .AddAttribute ("Snr", "The snr of the last packet received",
       
    70                    DoubleValue (0.0),
       
    71                    MakeDoubleAccessor (&SnrTag::Get),
       
    72                    MakeDoubleChecker<double> ())
       
    73   ;
       
    74   return tid;
       
    75 }
       
    76 TypeId 
       
    77 SnrTag::GetInstanceTypeId (void) const
       
    78 {
       
    79   return GetTypeId ();
       
    80 }
       
    81 
       
    82 uint32_t 
       
    83 SnrTag::GetSerializedSize (void) const
       
    84 {
       
    85   return sizeof (double);
       
    86 }
       
    87 void 
       
    88 SnrTag::Serialize (TagBuffer i) const
       
    89 {
       
    90   i.WriteDouble (m_snr);
       
    91 }
       
    92 void 
       
    93 SnrTag::Deserialize (TagBuffer i)
       
    94 {
       
    95   m_snr = i.ReadDouble ();
       
    96 }
       
    97 void 
       
    98 SnrTag::Print (std::ostream &os) const
       
    99 {
       
   100   os << "Snr=" << m_snr;
       
   101 }
       
   102 void 
       
   103 SnrTag::Set (double snr)
       
   104 {
       
   105   m_snr = snr;
       
   106 }
       
   107 double 
       
   108 SnrTag::Get (void) const
       
   109 {
       
   110   return m_snr;
       
   111 }
       
   112 
       
   113 
       
   114 MacLowTransmissionListener::MacLowTransmissionListener ()
       
   115 {
       
   116 }
       
   117 MacLowTransmissionListener::~MacLowTransmissionListener ()
       
   118 {
       
   119 }
       
   120 void
       
   121 MacLowTransmissionListener::GotBlockAck (const CtrlBAckResponseHeader *blockAck,
       
   122                                          Mac48Address source)
       
   123 {
       
   124 }
       
   125 void
       
   126 MacLowTransmissionListener::MissedBlockAck (void)
       
   127 {
       
   128 }
       
   129 MacLowDcfListener::MacLowDcfListener ()
       
   130 {
       
   131 }
       
   132 MacLowDcfListener::~MacLowDcfListener ()
       
   133 {
       
   134 }
       
   135 
       
   136 MacLowBlockAckEventListener::MacLowBlockAckEventListener ()
       
   137 {
       
   138 }
       
   139 MacLowBlockAckEventListener::~MacLowBlockAckEventListener ()
       
   140 {
       
   141 }
       
   142 
       
   143 MacLowTransmissionParameters::MacLowTransmissionParameters ()
       
   144   : m_nextSize (0),
       
   145     m_waitAck (ACK_NONE),
       
   146     m_sendRts (false),
       
   147     m_overrideDurationId (Seconds (0))
       
   148 {
       
   149 }
       
   150 void
       
   151 MacLowTransmissionParameters::EnableNextData (uint32_t size)
       
   152 {
       
   153   m_nextSize = size;
       
   154 }
       
   155 void
       
   156 MacLowTransmissionParameters::DisableNextData (void)
       
   157 {
       
   158   m_nextSize = 0;
       
   159 }
       
   160 void
       
   161 MacLowTransmissionParameters::EnableOverrideDurationId (Time durationId)
       
   162 {
       
   163   m_overrideDurationId = durationId;
       
   164 }
       
   165 void
       
   166 MacLowTransmissionParameters::DisableOverrideDurationId (void)
       
   167 {
       
   168   m_overrideDurationId = Seconds (0);
       
   169 }
       
   170 void
       
   171 MacLowTransmissionParameters::EnableSuperFastAck (void)
       
   172 {
       
   173   m_waitAck = ACK_SUPER_FAST;
       
   174 }
       
   175 void
       
   176 MacLowTransmissionParameters::EnableBasicBlockAck (void)
       
   177 {
       
   178   m_waitAck = BLOCK_ACK_BASIC;
       
   179 }
       
   180 void
       
   181 MacLowTransmissionParameters::EnableCompressedBlockAck (void)
       
   182 {
       
   183   m_waitAck = BLOCK_ACK_COMPRESSED;
       
   184 }
       
   185 void
       
   186 MacLowTransmissionParameters::EnableMultiTidBlockAck (void)
       
   187 {
       
   188   m_waitAck = BLOCK_ACK_MULTI_TID;
       
   189 }
       
   190 void
       
   191 MacLowTransmissionParameters::EnableFastAck (void)
       
   192 {
       
   193   m_waitAck = ACK_FAST;
       
   194 }
       
   195 void
       
   196 MacLowTransmissionParameters::EnableAck (void)
       
   197 {
       
   198   m_waitAck = ACK_NORMAL;
       
   199 }
       
   200 void
       
   201 MacLowTransmissionParameters::DisableAck (void)
       
   202 {
       
   203   m_waitAck = ACK_NONE;
       
   204 }
       
   205 void
       
   206 MacLowTransmissionParameters::EnableRts (void)
       
   207 {
       
   208   m_sendRts = true;
       
   209 }
       
   210 void
       
   211 MacLowTransmissionParameters::DisableRts (void)
       
   212 {
       
   213   m_sendRts = false;
       
   214 }
       
   215 bool
       
   216 MacLowTransmissionParameters::MustWaitAck (void) const
       
   217 {
       
   218   return (m_waitAck != ACK_NONE);
       
   219 }
       
   220 bool
       
   221 MacLowTransmissionParameters::MustWaitNormalAck (void) const
       
   222 {
       
   223   return (m_waitAck == ACK_NORMAL);
       
   224 }
       
   225 bool
       
   226 MacLowTransmissionParameters::MustWaitFastAck (void) const
       
   227 {
       
   228   return (m_waitAck == ACK_FAST);
       
   229 }
       
   230 bool
       
   231 MacLowTransmissionParameters::MustWaitSuperFastAck (void) const
       
   232 {
       
   233   return (m_waitAck == ACK_SUPER_FAST);
       
   234 }
       
   235 bool
       
   236 MacLowTransmissionParameters::MustWaitBasicBlockAck (void) const
       
   237 {
       
   238   return (m_waitAck == BLOCK_ACK_BASIC) ? true : false;
       
   239 }
       
   240 bool
       
   241 MacLowTransmissionParameters::MustWaitCompressedBlockAck (void) const
       
   242 {
       
   243   return (m_waitAck == BLOCK_ACK_COMPRESSED) ? true : false;
       
   244 }
       
   245 bool
       
   246 MacLowTransmissionParameters::MustWaitMultiTidBlockAck (void) const
       
   247 {
       
   248   return (m_waitAck == BLOCK_ACK_MULTI_TID) ? true : false;
       
   249 }
       
   250 bool 
       
   251 MacLowTransmissionParameters::MustSendRts (void) const
       
   252 {
       
   253   return m_sendRts;
       
   254 }
       
   255 bool 
       
   256 MacLowTransmissionParameters::HasDurationId (void) const
       
   257 {
       
   258   return (m_overrideDurationId != Seconds (0));
       
   259 }
       
   260 Time
       
   261 MacLowTransmissionParameters::GetDurationId (void) const
       
   262 {
       
   263   NS_ASSERT (m_overrideDurationId != Seconds (0));
       
   264   return m_overrideDurationId;
       
   265 }
       
   266 bool 
       
   267 MacLowTransmissionParameters::HasNextPacket (void) const
       
   268 {
       
   269   return (m_nextSize != 0);
       
   270 }
       
   271 uint32_t 
       
   272 MacLowTransmissionParameters::GetNextPacketSize (void) const
       
   273 {
       
   274   NS_ASSERT (HasNextPacket ());
       
   275   return m_nextSize;
       
   276 }
       
   277 
       
   278 std::ostream &operator << (std::ostream &os, const MacLowTransmissionParameters &params)
       
   279 {
       
   280   os << "[" 
       
   281      << "send rts=" << params.m_sendRts << ", "
       
   282      << "next size=" << params.m_nextSize << ", "
       
   283      << "dur=" << params.m_overrideDurationId << ", "
       
   284      << "ack=";
       
   285   switch (params.m_waitAck) {
       
   286     case MacLowTransmissionParameters::ACK_NONE:
       
   287       os << "none";
       
   288       break;
       
   289     case MacLowTransmissionParameters::ACK_NORMAL:
       
   290       os << "normal";
       
   291       break;
       
   292     case MacLowTransmissionParameters::ACK_FAST:
       
   293       os << "fast";
       
   294       break;
       
   295     case MacLowTransmissionParameters::ACK_SUPER_FAST:
       
   296       os << "super-fast";
       
   297       break;
       
   298     case MacLowTransmissionParameters::BLOCK_ACK_BASIC:
       
   299       os << "basic-block-ack";
       
   300       break;
       
   301     case MacLowTransmissionParameters::BLOCK_ACK_COMPRESSED:
       
   302       os << "compressed-block-ack";
       
   303       break;
       
   304     case MacLowTransmissionParameters::BLOCK_ACK_MULTI_TID:
       
   305       os << "multi-tid-block-ack";
       
   306       break;
       
   307     }
       
   308   os << "]";
       
   309   return os;
       
   310 }
       
   311 
       
   312 
       
   313 /***************************************************************
       
   314  *         Listener for PHY events. Forwards to MacLow
       
   315  ***************************************************************/
       
   316 
       
   317 
       
   318 class PhyMacLowListener : public ns3::WifiPhyListener {
       
   319 public:
       
   320   PhyMacLowListener (ns3::MacLow *macLow)
       
   321     : m_macLow (macLow) {}
       
   322   virtual ~PhyMacLowListener () {}
       
   323   virtual void NotifyRxStart (Time duration) {}
       
   324   virtual void NotifyRxEndOk (void) {}
       
   325   virtual void NotifyRxEndError (void) {}
       
   326   virtual void NotifyTxStart (Time duration) {}
       
   327   virtual void NotifyMaybeCcaBusyStart (Time duration) {}
       
   328   virtual void NotifySwitchingStart (Time duration) { 
       
   329     m_macLow->NotifySwitchingStartNow (duration);
       
   330   }
       
   331 private:
       
   332   ns3::MacLow *m_macLow;
       
   333 };
       
   334 
       
   335 
       
   336 MacLow::MacLow ()
       
   337   : m_normalAckTimeoutEvent (),
       
   338     m_fastAckTimeoutEvent (),
       
   339     m_superFastAckTimeoutEvent (),
       
   340     m_fastAckFailedTimeoutEvent (),
       
   341     m_blockAckTimeoutEvent (),
       
   342     m_ctsTimeoutEvent (),
       
   343     m_sendCtsEvent (),
       
   344     m_sendAckEvent (),
       
   345     m_sendDataEvent (),
       
   346     m_waitSifsEvent (),
       
   347     m_currentPacket (0),
       
   348     m_listener (0)
       
   349 {
       
   350   NS_LOG_FUNCTION (this);
       
   351   m_lastNavDuration = Seconds (0);
       
   352   m_lastNavStart = Seconds (0);
       
   353 }
       
   354 
       
   355 MacLow::~MacLow ()
       
   356 {
       
   357   NS_LOG_FUNCTION (this);
       
   358 }
       
   359 
       
   360 void 
       
   361 MacLow::SetupPhyMacLowListener (Ptr<WifiPhy> phy)
       
   362 {
       
   363   m_phyMacLowListener = new PhyMacLowListener (this); 
       
   364   phy->RegisterListener (m_phyMacLowListener);
       
   365 }
       
   366 
       
   367 
       
   368 void 
       
   369 MacLow::DoDispose (void)
       
   370 {
       
   371   NS_LOG_FUNCTION (this);
       
   372   m_normalAckTimeoutEvent.Cancel ();
       
   373   m_fastAckTimeoutEvent.Cancel ();
       
   374   m_superFastAckTimeoutEvent.Cancel ();
       
   375   m_fastAckFailedTimeoutEvent.Cancel ();
       
   376   m_blockAckTimeoutEvent.Cancel ();
       
   377   m_ctsTimeoutEvent.Cancel ();
       
   378   m_sendCtsEvent.Cancel ();
       
   379   m_sendAckEvent.Cancel ();
       
   380   m_sendDataEvent.Cancel ();
       
   381   m_waitSifsEvent.Cancel ();
       
   382   m_phy = 0;
       
   383   m_stationManager = 0;
       
   384   delete m_phyMacLowListener;
       
   385   m_phyMacLowListener = 0;
       
   386 }
       
   387 
       
   388 void
       
   389 MacLow::CancelAllEvents (void)
       
   390 {
       
   391   NS_LOG_FUNCTION (this);
       
   392   bool oneRunning = false;
       
   393   if (m_normalAckTimeoutEvent.IsRunning ()) 
       
   394     {
       
   395       m_normalAckTimeoutEvent.Cancel ();
       
   396       oneRunning = true;
       
   397     }
       
   398   if (m_fastAckTimeoutEvent.IsRunning ()) 
       
   399     {
       
   400       m_fastAckTimeoutEvent.Cancel ();
       
   401       oneRunning = true;
       
   402     }
       
   403   if (m_superFastAckTimeoutEvent.IsRunning ()) 
       
   404     {
       
   405       m_superFastAckTimeoutEvent.Cancel ();
       
   406       oneRunning = true;
       
   407     }
       
   408   if (m_fastAckFailedTimeoutEvent.IsRunning ()) 
       
   409     {
       
   410       m_fastAckFailedTimeoutEvent.Cancel ();
       
   411       oneRunning = true;
       
   412     }
       
   413   if (m_blockAckTimeoutEvent.IsRunning ())
       
   414     {
       
   415       m_blockAckTimeoutEvent.Cancel ();
       
   416       oneRunning = true;
       
   417     }
       
   418   if (m_ctsTimeoutEvent.IsRunning ()) 
       
   419     {
       
   420       m_ctsTimeoutEvent.Cancel ();
       
   421       oneRunning = true;
       
   422     }
       
   423   if (m_sendCtsEvent.IsRunning ()) 
       
   424     {
       
   425       m_sendCtsEvent.Cancel ();
       
   426       oneRunning = true;
       
   427     }
       
   428   if (m_sendAckEvent.IsRunning ()) 
       
   429     {
       
   430       m_sendAckEvent.Cancel ();
       
   431       oneRunning = true;
       
   432     }
       
   433   if (m_sendDataEvent.IsRunning ()) 
       
   434     {
       
   435       m_sendDataEvent.Cancel ();
       
   436       oneRunning = true;
       
   437     }
       
   438   if (m_waitSifsEvent.IsRunning ()) 
       
   439     {
       
   440       m_waitSifsEvent.Cancel ();
       
   441       oneRunning = true;
       
   442     }
       
   443   if (oneRunning && m_listener != 0) 
       
   444     {
       
   445       m_listener->Cancel ();
       
   446       m_listener = 0;
       
   447     }
       
   448 }
       
   449 
       
   450 void
       
   451 MacLow::SetPhy (Ptr<WifiPhy> phy)
       
   452 {
       
   453   m_phy = phy;
       
   454   m_phy->SetReceiveOkCallback (MakeCallback (&MacLow::ReceiveOk, this));
       
   455   m_phy->SetReceiveErrorCallback (MakeCallback (&MacLow::ReceiveError, this));
       
   456   SetupPhyMacLowListener(phy); 
       
   457 }
       
   458 void 
       
   459 MacLow::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> manager)
       
   460 {
       
   461   m_stationManager = manager;
       
   462 }
       
   463 
       
   464 void 
       
   465 MacLow::SetAddress (Mac48Address ad)
       
   466 {
       
   467   m_self = ad;
       
   468 }
       
   469 void 
       
   470 MacLow::SetAckTimeout (Time ackTimeout)
       
   471 {
       
   472   m_ackTimeout = ackTimeout;
       
   473 }
       
   474 void
       
   475 MacLow::SetBasicBlockAckTimeout (Time blockAckTimeout)
       
   476 {
       
   477   m_basicBlockAckTimeout = blockAckTimeout;
       
   478 }
       
   479 void
       
   480 MacLow::SetCompressedBlockAckTimeout (Time blockAckTimeout)
       
   481 {
       
   482   m_compressedBlockAckTimeout = blockAckTimeout;
       
   483 }
       
   484 void 
       
   485 MacLow::SetCtsTimeout (Time ctsTimeout)
       
   486 {
       
   487   m_ctsTimeout = ctsTimeout;
       
   488 }
       
   489 void
       
   490 MacLow::SetSifs (Time sifs)
       
   491 {
       
   492   m_sifs = sifs;
       
   493 }
       
   494 void 
       
   495 MacLow::SetSlotTime (Time slotTime)
       
   496 {
       
   497   m_slotTime = slotTime;
       
   498 }
       
   499 void 
       
   500 MacLow::SetPifs (Time pifs)
       
   501 {
       
   502   m_pifs = pifs;
       
   503 }
       
   504 void
       
   505 MacLow::SetBssid (Mac48Address bssid)
       
   506 {
       
   507   m_bssid = bssid;
       
   508 }
       
   509 Mac48Address 
       
   510 MacLow::GetAddress (void) const
       
   511 {
       
   512   return m_self;
       
   513 }
       
   514 Time 
       
   515 MacLow::GetAckTimeout (void) const
       
   516 {
       
   517   return m_ackTimeout;
       
   518 }
       
   519 Time
       
   520 MacLow::GetBasicBlockAckTimeout () const
       
   521 {
       
   522   return m_basicBlockAckTimeout;
       
   523 }
       
   524 Time
       
   525 MacLow::GetCompressedBlockAckTimeout () const
       
   526 {
       
   527   return m_compressedBlockAckTimeout;
       
   528 }
       
   529 Time 
       
   530 MacLow::GetCtsTimeout (void) const
       
   531 {
       
   532   return m_ctsTimeout;
       
   533 }
       
   534 Time
       
   535 MacLow::GetSifs (void) const
       
   536 {
       
   537   return m_sifs;
       
   538 }
       
   539 Time 
       
   540 MacLow::GetSlotTime (void) const
       
   541 {
       
   542   return m_slotTime;
       
   543 }
       
   544 Time 
       
   545 MacLow::GetPifs (void) const
       
   546 {
       
   547   return m_pifs;
       
   548 }
       
   549 Mac48Address 
       
   550 MacLow::GetBssid (void) const
       
   551 {
       
   552   return m_bssid;
       
   553 }
       
   554 
       
   555 void 
       
   556 MacLow::SetRxCallback (Callback<void,Ptr<Packet>,const WifiMacHeader *> callback)
       
   557 {
       
   558   m_rxCallback = callback;
       
   559 }
       
   560 void 
       
   561 MacLow::RegisterDcfListener (MacLowDcfListener *listener)
       
   562 {
       
   563   m_dcfListeners.push_back (listener);
       
   564 }
       
   565 
       
   566 
       
   567 void 
       
   568 MacLow::StartTransmission (Ptr<const Packet> packet, 
       
   569                            const WifiMacHeader* hdr, 
       
   570                            MacLowTransmissionParameters params,
       
   571                            MacLowTransmissionListener *listener)
       
   572 {
       
   573   NS_LOG_FUNCTION (this << packet << hdr << params << listener);
       
   574   /* m_currentPacket is not NULL because someone started
       
   575    * a transmission and was interrupted before one of:
       
   576    *   - ctsTimeout
       
   577    *   - sendDataAfterCTS
       
   578    * expired. This means that one of these timers is still
       
   579    * running. They are all cancelled below anyway by the 
       
   580    * call to CancelAllEvents (because of at least one
       
   581    * of these two timer) which will trigger a call to the
       
   582    * previous listener's cancel method.
       
   583    *
       
   584    * This typically happens because the high-priority 
       
   585    * QapScheduler has taken access to the channel from
       
   586    * one of the Edca of the QAP.
       
   587    */
       
   588   m_currentPacket = packet->Copy ();
       
   589   m_currentHdr = *hdr;
       
   590   CancelAllEvents ();
       
   591   m_listener = listener;
       
   592   m_txParams = params;
       
   593 
       
   594   //NS_ASSERT (m_phy->IsStateIdle ());
       
   595 
       
   596   NS_LOG_DEBUG ("startTx size="<< GetSize (m_currentPacket, &m_currentHdr) << 
       
   597                 ", to=" << m_currentHdr.GetAddr1()<<", listener="<<m_listener);
       
   598 
       
   599   if (m_txParams.MustSendRts ()) 
       
   600     {
       
   601       SendRtsForPacket ();
       
   602     } 
       
   603   else 
       
   604     {
       
   605       SendDataPacket ();
       
   606     }
       
   607 
       
   608   /* When this method completes, we have taken ownership of the medium. */
       
   609   NS_ASSERT (m_phy->IsStateTx ());
       
   610 }
       
   611 
       
   612 void
       
   613 MacLow::ReceiveError (Ptr<const Packet> packet, double rxSnr)
       
   614 {
       
   615   NS_LOG_FUNCTION (this << packet << rxSnr);
       
   616   NS_LOG_DEBUG ("rx failed ");
       
   617   if (m_txParams.MustWaitFastAck ()) 
       
   618     {
       
   619       NS_ASSERT (m_fastAckFailedTimeoutEvent.IsExpired ());
       
   620       m_fastAckFailedTimeoutEvent = Simulator::Schedule (GetSifs (), 
       
   621                                                          &MacLow::FastAckFailedTimeout, this);
       
   622     }
       
   623   return;
       
   624 }
       
   625 
       
   626 void 
       
   627 MacLow::NotifySwitchingStartNow (Time duration)
       
   628 {
       
   629   NS_LOG_DEBUG ("switching channel. Cancelling MAC pending events"); 
       
   630   m_stationManager->Reset();
       
   631   CancelAllEvents(); 
       
   632   if (m_navCounterResetCtsMissed.IsRunning ())
       
   633     {
       
   634       m_navCounterResetCtsMissed.Cancel();
       
   635     }
       
   636   m_lastNavStart = Simulator::Now (); 
       
   637   m_lastNavDuration = Seconds (0);
       
   638   m_currentPacket = 0;
       
   639   m_listener = 0;
       
   640 }
       
   641 
       
   642 void 
       
   643 MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamble preamble)
       
   644 {
       
   645   NS_LOG_FUNCTION (this << packet << rxSnr << txMode << preamble);
       
   646   /* A packet is received from the PHY.
       
   647    * When we have handled this packet,
       
   648    * we handle any packet present in the
       
   649    * packet queue.
       
   650    */
       
   651   WifiMacHeader hdr;
       
   652   packet->RemoveHeader (hdr);
       
   653 
       
   654   bool isPrevNavZero = IsNavZero ();
       
   655   NS_LOG_DEBUG ("duration/id=" << hdr.GetDuration ());
       
   656   NotifyNav (hdr, txMode, preamble);
       
   657   if (hdr.IsRts ()) 
       
   658     {
       
   659       /* see section 9.2.5.7 802.11-1999
       
   660        * A STA that is addressed by an RTS frame shall transmit a CTS frame after a SIFS 
       
   661        * period if the NAV at the STA receiving the RTS frame indicates that the medium is 
       
   662        * idle. If the NAV at the STA receiving the RTS indicates the medium is not idle, 
       
   663        * that STA shall not respond to the RTS frame.
       
   664        */
       
   665       if (isPrevNavZero &&
       
   666           hdr.GetAddr1 () == m_self) 
       
   667         {
       
   668           NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
       
   669           NS_ASSERT (m_sendCtsEvent.IsExpired ());
       
   670           m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr, 
       
   671                                         rxSnr, txMode);
       
   672           m_sendCtsEvent = Simulator::Schedule (GetSifs (),
       
   673                                                 &MacLow::SendCtsAfterRts, this,
       
   674                                                 hdr.GetAddr2 (), 
       
   675                                                 hdr.GetDuration (),
       
   676                                                 txMode,
       
   677                                                 rxSnr);
       
   678         } 
       
   679       else 
       
   680         {
       
   681           NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
       
   682         }
       
   683     } 
       
   684   else if (hdr.IsCts () &&
       
   685            hdr.GetAddr1 () == m_self &&
       
   686            m_ctsTimeoutEvent.IsRunning () &&
       
   687            m_currentPacket != 0) 
       
   688     {
       
   689       NS_LOG_DEBUG ("receive cts from="<<m_currentHdr.GetAddr1 ());
       
   690       SnrTag tag;
       
   691       packet->RemovePacketTag (tag);
       
   692       m_stationManager->ReportRxOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
       
   693                                     rxSnr, txMode);
       
   694       m_stationManager->ReportRtsOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
       
   695                                      rxSnr, txMode, tag.Get ());
       
   696 
       
   697       m_ctsTimeoutEvent.Cancel ();
       
   698       NotifyCtsTimeoutResetNow ();
       
   699       m_listener->GotCts (rxSnr, txMode);
       
   700       NS_ASSERT (m_sendDataEvent.IsExpired ());
       
   701       m_sendDataEvent = Simulator::Schedule (GetSifs (), 
       
   702                                              &MacLow::SendDataAfterCts, this, 
       
   703                                              hdr.GetAddr1 (),
       
   704                                              hdr.GetDuration (),
       
   705                                              txMode);
       
   706     } 
       
   707   else if (hdr.IsAck () &&
       
   708            hdr.GetAddr1 () == m_self &&
       
   709            (m_normalAckTimeoutEvent.IsRunning () || 
       
   710             m_fastAckTimeoutEvent.IsRunning () ||
       
   711             m_superFastAckTimeoutEvent.IsRunning ()) &&
       
   712            m_txParams.MustWaitAck ()) 
       
   713     {
       
   714       NS_LOG_DEBUG ("receive ack from="<<m_currentHdr.GetAddr1 ());
       
   715       SnrTag tag;
       
   716       packet->RemovePacketTag (tag);
       
   717       m_stationManager->ReportRxOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
       
   718                                     rxSnr, txMode);
       
   719       m_stationManager->ReportDataOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
       
   720                                       rxSnr, txMode, tag.Get ());
       
   721       bool gotAck = false;
       
   722       if (m_txParams.MustWaitNormalAck () &&
       
   723           m_normalAckTimeoutEvent.IsRunning ()) 
       
   724         {
       
   725           m_normalAckTimeoutEvent.Cancel ();
       
   726           NotifyAckTimeoutResetNow ();
       
   727           gotAck = true;
       
   728         }
       
   729       if (m_txParams.MustWaitFastAck () &&
       
   730           m_fastAckTimeoutEvent.IsRunning ()) 
       
   731         {
       
   732           m_fastAckTimeoutEvent.Cancel ();
       
   733           NotifyAckTimeoutResetNow ();
       
   734           gotAck = true;
       
   735         }
       
   736       if (gotAck) 
       
   737         {
       
   738           m_listener->GotAck (rxSnr, txMode);
       
   739         }
       
   740       if (m_txParams.HasNextPacket ()) 
       
   741         {
       
   742           m_waitSifsEvent = Simulator::Schedule (GetSifs (), 
       
   743                                                  &MacLow::WaitSifsAfterEndTx, this);
       
   744         }
       
   745     } 
       
   746   else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self &&
       
   747            (m_txParams.MustWaitBasicBlockAck () || m_txParams.MustWaitCompressedBlockAck ()) && 
       
   748            m_blockAckTimeoutEvent.IsRunning ())
       
   749     {
       
   750       NS_LOG_DEBUG ("got block ack from "<<hdr.GetAddr2 ());
       
   751       CtrlBAckResponseHeader blockAck;
       
   752       packet->RemoveHeader (blockAck);
       
   753       m_blockAckTimeoutEvent.Cancel ();
       
   754       m_listener->GotBlockAck (&blockAck, hdr.GetAddr2 ());
       
   755     }
       
   756   else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
       
   757     {
       
   758       CtrlBAckRequestHeader blockAckReq;
       
   759       packet->RemoveHeader (blockAckReq);
       
   760       if (!blockAckReq.IsMultiTid ())
       
   761         {
       
   762           uint8_t tid = blockAckReq.GetTidInfo ();
       
   763           AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), tid));
       
   764           if (it != m_bAckAgreements.end ())
       
   765             {
       
   766               //Update block ack cache
       
   767               BlockAckCachesI i = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), tid));
       
   768               NS_ASSERT (i != m_bAckCaches.end ());
       
   769               (*i).second.UpdateWithBlockAckReq (blockAckReq.GetStartingSequence ());
       
   770 
       
   771               NS_ASSERT (m_sendAckEvent.IsExpired ());
       
   772               /* See section 11.5.3 in IEEE802.11 for mean of this timer */
       
   773               ResetBlockAckInactivityTimerIfNeeded (it->second.first);
       
   774               if ((*it).second.first.IsImmediateBlockAck ())
       
   775                 {
       
   776                   NS_LOG_DEBUG ("rx blockAckRequest/sendImmediateBlockAck from="<< hdr.GetAddr2 ());
       
   777                   m_sendAckEvent = Simulator::Schedule (GetSifs (),
       
   778                                                         &MacLow::SendBlockAckAfterBlockAckRequest, this,
       
   779                                                         blockAckReq,
       
   780                                                         hdr.GetAddr2 (), 
       
   781                                                         hdr.GetDuration (),
       
   782                                                         txMode);
       
   783                 }
       
   784               else
       
   785                 {
       
   786                   NS_FATAL_ERROR ("Delayed block ack not supported.");
       
   787                 }
       
   788             }
       
   789           else
       
   790             {
       
   791               NS_LOG_DEBUG ("There's not a valid agreement for this block ack request.");
       
   792             }
       
   793         }
       
   794       else
       
   795         {
       
   796           NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
       
   797         }
       
   798     }
       
   799   else if (hdr.IsCtl ()) 
       
   800     {
       
   801       NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ());
       
   802     } 
       
   803   else if (hdr.GetAddr1 () == m_self) 
       
   804     {
       
   805       m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
       
   806                                     rxSnr, txMode);
       
   807 
       
   808       if (hdr.IsQosData () && StoreMpduIfNeeded (packet, hdr)) 
       
   809         {
       
   810           /* From section 9.10.4 in IEEE802.11:
       
   811              Upon the receipt of a QoS data frame from the originator for which
       
   812              the Block Ack agreement exists, the recipient shall buffer the MSDU
       
   813              regardless of the value of the Ack Policy subfield within the
       
   814              QoS Control field of the QoS data frame. */
       
   815           if (hdr.IsQosAck ())
       
   816             {
       
   817               AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
       
   818               RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (),
       
   819                                                             hdr.GetAddr2 (), hdr.GetQosTid ());
       
   820               RxCompleteBufferedPacketsUntilFirstLost (hdr.GetAddr2 (), hdr.GetQosTid ());
       
   821               NS_ASSERT (m_sendAckEvent.IsExpired ());
       
   822               m_sendAckEvent = Simulator::Schedule (GetSifs (),
       
   823                                                     &MacLow::SendAckAfterData, this,
       
   824                                                     hdr.GetAddr2 (), 
       
   825                                                     hdr.GetDuration (),
       
   826                                                     txMode,
       
   827                                                     rxSnr);
       
   828             }
       
   829           else if (hdr.IsQosBlockAck ())
       
   830             {
       
   831               AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
       
   832               /* See section 11.5.3 in IEEE802.11 for mean of this timer */
       
   833               ResetBlockAckInactivityTimerIfNeeded (it->second.first);
       
   834             }
       
   835           return;
       
   836         }
       
   837       else if (hdr.IsQosData () && hdr.IsQosBlockAck ())
       
   838         {
       
   839           /* This happens if a packet with ack policy Block Ack is received and a block ack
       
   840              agreement for that packet doesn't exist.
       
   841 
       
   842              From section 11.5.3 in IEEE802.11e:
       
   843              When a recipient does not have an active Block ack for a TID, but receives
       
   844              data MPDUs with the Ack Policy subfield set to Block Ack, it shall discard
       
   845              them and shall send a DELBA frame using the normal access 
       
   846              mechanisms. */
       
   847           AcIndex ac = QosUtilsMapTidToAc (hdr.GetQosTid ());
       
   848           m_edcaListeners[ac]->BlockAckInactivityTimeout (hdr.GetAddr2 (), hdr.GetQosTid ());
       
   849           return;
       
   850         }
       
   851       else if (hdr.IsQosData () && hdr.IsQosNoAck ()) 
       
   852         {
       
   853           NS_LOG_DEBUG ("rx unicast/noAck from="<<hdr.GetAddr2 ());
       
   854         } 
       
   855       else if (hdr.IsData () || hdr.IsMgt ()) 
       
   856         {
       
   857           NS_LOG_DEBUG ("rx unicast/sendAck from=" << hdr.GetAddr2 ());
       
   858           NS_ASSERT (m_sendAckEvent.IsExpired ());
       
   859           m_sendAckEvent = Simulator::Schedule (GetSifs (),
       
   860                                                 &MacLow::SendAckAfterData, this,
       
   861                                                 hdr.GetAddr2 (), 
       
   862                                                 hdr.GetDuration (),
       
   863                                                 txMode,
       
   864                                                 rxSnr);
       
   865         }
       
   866       goto rxPacket;
       
   867     } 
       
   868   else if (hdr.GetAddr1 ().IsGroup ())
       
   869     {
       
   870       if (hdr.IsData () || hdr.IsMgt ())
       
   871         {
       
   872           NS_LOG_DEBUG ("rx group from=" << hdr.GetAddr2 ());
       
   873           goto rxPacket;
       
   874         }
       
   875       else
       
   876         {
       
   877           // DROP
       
   878         }
       
   879     }
       
   880   else 
       
   881     {
       
   882       //NS_LOG_DEBUG_VERBOSE ("rx not-for-me from %d", GetSource (packet));
       
   883     }
       
   884   return;
       
   885 rxPacket:
       
   886   WifiMacTrailer fcs;
       
   887   packet->RemoveTrailer (fcs);
       
   888   m_rxCallback (packet, &hdr);
       
   889   return;
       
   890 }
       
   891 
       
   892 uint32_t 
       
   893 MacLow::GetAckSize (void) const
       
   894 {
       
   895   WifiMacHeader ack;
       
   896   ack.SetType (WIFI_MAC_CTL_ACK);
       
   897   return ack.GetSize () + 4;
       
   898 }
       
   899 uint32_t
       
   900 MacLow::GetBlockAckSize (enum BlockAckType type) const
       
   901 {
       
   902   WifiMacHeader hdr;
       
   903   hdr.SetType (WIFI_MAC_CTL_BACKRESP);
       
   904   CtrlBAckResponseHeader blockAck;
       
   905   if (type == BASIC_BLOCK_ACK)
       
   906     {
       
   907       blockAck.SetType (BASIC_BLOCK_ACK);
       
   908     }
       
   909   else if (type == COMPRESSED_BLOCK_ACK)
       
   910     {
       
   911       blockAck.SetType (COMPRESSED_BLOCK_ACK);
       
   912     }
       
   913   else if (type == MULTI_TID_BLOCK_ACK)
       
   914     {
       
   915       //Not implemented
       
   916       NS_ASSERT (false);
       
   917     }
       
   918   return hdr.GetSize () + blockAck.GetSerializedSize () + 4; 
       
   919 }
       
   920 uint32_t 
       
   921 MacLow::GetRtsSize (void) const
       
   922 {
       
   923   WifiMacHeader rts;
       
   924   rts.SetType (WIFI_MAC_CTL_RTS);
       
   925   return rts.GetSize () + 4;
       
   926 }
       
   927 Time
       
   928 MacLow::GetAckDuration (Mac48Address to, WifiMode dataTxMode) const
       
   929 {
       
   930   WifiMode ackMode = GetAckTxModeForData (to, dataTxMode);
       
   931   return m_phy->CalculateTxDuration (GetAckSize (), ackMode, WIFI_PREAMBLE_LONG);
       
   932 }
       
   933 Time
       
   934 MacLow::GetBlockAckDuration (Mac48Address to, WifiMode blockAckReqTxMode, enum BlockAckType type) const
       
   935 {
       
   936   /* 
       
   937    * For immediate BlockAck we should transmit the frame with the same WifiMode
       
   938    * as the BlockAckReq.
       
   939    *
       
   940    * from section 9.6 in IEEE802.11e:
       
   941    * The BlockAck control frame shall be sent at the same rate and modulation class as
       
   942    * the BlockAckReq frame if it is sent in response to a BlockAckReq frame.
       
   943    */
       
   944   return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxMode, WIFI_PREAMBLE_LONG);
       
   945 }
       
   946 Time
       
   947 MacLow::GetCtsDuration (Mac48Address to, WifiMode rtsTxMode) const
       
   948 {
       
   949   WifiMode ctsMode = GetCtsTxModeForRts (to, rtsTxMode);
       
   950   return m_phy->CalculateTxDuration (GetCtsSize (), ctsMode, WIFI_PREAMBLE_LONG);
       
   951 }
       
   952 uint32_t 
       
   953 MacLow::GetCtsSize (void) const
       
   954 {
       
   955   WifiMacHeader cts;
       
   956   cts.SetType (WIFI_MAC_CTL_CTS);
       
   957   return cts.GetSize () + 4;
       
   958 }
       
   959 uint32_t 
       
   960 MacLow::GetSize (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
       
   961 {
       
   962   WifiMacTrailer fcs;
       
   963   return packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
       
   964 }
       
   965 
       
   966 WifiMode
       
   967 MacLow::GetRtsTxMode (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
       
   968 {
       
   969   Mac48Address to = hdr->GetAddr1 ();
       
   970   return m_stationManager->GetRtsMode (to, hdr, packet);
       
   971 }
       
   972 WifiMode
       
   973 MacLow::GetDataTxMode (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
       
   974 {
       
   975   Mac48Address to = hdr->GetAddr1 ();
       
   976   WifiMacTrailer fcs;
       
   977   uint32_t size =  packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
       
   978   return m_stationManager->GetDataMode (to, hdr, packet, size);
       
   979 }
       
   980 
       
   981 WifiMode
       
   982 MacLow::GetCtsTxModeForRts (Mac48Address to, WifiMode rtsTxMode) const
       
   983 {
       
   984   return m_stationManager->GetCtsMode (to, rtsTxMode);
       
   985 }
       
   986 WifiMode
       
   987 MacLow::GetAckTxModeForData (Mac48Address to, WifiMode dataTxMode) const
       
   988 {
       
   989   return m_stationManager->GetAckMode (to, dataTxMode);
       
   990 }
       
   991 
       
   992 
       
   993 Time
       
   994 MacLow::CalculateOverallTxTime (Ptr<const Packet> packet,
       
   995                                 const WifiMacHeader* hdr, 
       
   996                                 const MacLowTransmissionParameters& params) const
       
   997 {
       
   998   Time txTime = Seconds (0);
       
   999   WifiMode rtsMode = GetRtsTxMode (packet, hdr);
       
  1000   WifiMode dataMode = GetDataTxMode (packet, hdr);
       
  1001   if (params.MustSendRts ()) 
       
  1002     {
       
  1003       txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsMode, WIFI_PREAMBLE_LONG);
       
  1004       txTime += GetCtsDuration (hdr->GetAddr1 (), rtsMode);
       
  1005       txTime += GetSifs () * Scalar (2);
       
  1006     }
       
  1007   uint32_t dataSize = GetSize (packet, hdr);
       
  1008   txTime += m_phy->CalculateTxDuration (dataSize, dataMode, WIFI_PREAMBLE_LONG);
       
  1009   if (params.MustWaitAck ())
       
  1010     {
       
  1011       txTime += GetSifs ();
       
  1012       txTime += GetAckDuration (hdr->GetAddr1 (), dataMode);
       
  1013     }
       
  1014   return txTime;
       
  1015 }
       
  1016 
       
  1017 Time
       
  1018 MacLow::CalculateTransmissionTime (Ptr<const Packet> packet,
       
  1019                                    const WifiMacHeader* hdr, 
       
  1020                                    const MacLowTransmissionParameters& params) const
       
  1021 {
       
  1022   Time txTime = CalculateOverallTxTime (packet, hdr, params);
       
  1023   if (params.HasNextPacket ()) 
       
  1024     {
       
  1025       WifiMode dataMode = GetDataTxMode (packet, hdr);
       
  1026       txTime += GetSifs ();
       
  1027       txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataMode, WIFI_PREAMBLE_LONG);
       
  1028     }
       
  1029   return txTime;
       
  1030 }
       
  1031 
       
  1032 void
       
  1033 MacLow::NotifyNav (const WifiMacHeader &hdr, WifiMode txMode, WifiPreamble preamble)
       
  1034 {
       
  1035   NS_ASSERT (m_lastNavStart <= Simulator::Now ());
       
  1036   Time duration = hdr.GetDuration ();
       
  1037 
       
  1038   if (hdr.IsCfpoll () &&
       
  1039       hdr.GetAddr2 () == m_bssid) 
       
  1040     {
       
  1041       // see section 9.3.2.2 802.11-1999
       
  1042       DoNavResetNow (duration);
       
  1043       return;
       
  1044     }
       
  1045   // XXX Note that we should also handle CF_END specially here
       
  1046   // but we don't for now because we do not generate them.
       
  1047   else if (hdr.GetAddr1 () != m_self)
       
  1048     {
       
  1049       // see section 9.2.5.4 802.11-1999
       
  1050       bool navUpdated = DoNavStartNow (duration);
       
  1051       if (hdr.IsRts () && navUpdated)
       
  1052         {
       
  1053           /**
       
  1054            * A STA that used information from an RTS frame as the most recent basis to update its NAV setting 
       
  1055            * is permitted to reset its NAV if no PHY-RXSTART.indication is detected from the PHY during a 
       
  1056            * period with a duration of (2 * aSIFSTime) + (CTS_Time) + (2 * aSlotTime) starting at the 
       
  1057            * PHY-RXEND.indication corresponding to the detection of the RTS frame. The “CTS_Time” shall 
       
  1058            * be calculated using the length of the CTS frame and the data rate at which the RTS frame 
       
  1059            * used for the most recent NAV update was received.
       
  1060            */
       
  1061           WifiMacHeader cts;
       
  1062           cts.SetType (WIFI_MAC_CTL_CTS);
       
  1063           Time navCounterResetCtsMissedDelay = 
       
  1064             m_phy->CalculateTxDuration (cts.GetSerializedSize (), txMode, preamble) +
       
  1065             Scalar (2) * GetSifs () + Scalar (2) * GetSlotTime ();
       
  1066           m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay,
       
  1067                                                             &MacLow::NavCounterResetCtsMissed, this,
       
  1068                                                             Simulator::Now ());
       
  1069         }
       
  1070     }
       
  1071 }
       
  1072 
       
  1073 void
       
  1074 MacLow::NavCounterResetCtsMissed (Time rtsEndRxTime)
       
  1075 {
       
  1076   if (m_phy->GetLastRxStartTime () > rtsEndRxTime)
       
  1077     {
       
  1078       DoNavResetNow (Seconds (0.0));
       
  1079     }
       
  1080 }
       
  1081 
       
  1082 void
       
  1083 MacLow::DoNavResetNow (Time duration)
       
  1084 {
       
  1085   for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++) 
       
  1086     {
       
  1087       (*i)->NavReset (duration);
       
  1088     }
       
  1089   m_lastNavStart = Simulator::Now ();
       
  1090   m_lastNavStart = duration;
       
  1091 }
       
  1092 bool
       
  1093 MacLow::DoNavStartNow (Time duration)
       
  1094 {
       
  1095   for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++) 
       
  1096     {
       
  1097       (*i)->NavStart (duration);
       
  1098     }
       
  1099   Time newNavEnd = Simulator::Now () + duration;
       
  1100   Time oldNavEnd = m_lastNavStart + m_lastNavDuration;
       
  1101   if (newNavEnd > oldNavEnd)
       
  1102     {
       
  1103       m_lastNavStart = Simulator::Now ();
       
  1104       m_lastNavDuration = duration;
       
  1105       return true;
       
  1106     }
       
  1107   return false;
       
  1108 }
       
  1109 void
       
  1110 MacLow::NotifyAckTimeoutStartNow (Time duration)
       
  1111 {
       
  1112   for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++) 
       
  1113     {
       
  1114       (*i)->AckTimeoutStart (duration);
       
  1115     }
       
  1116 }
       
  1117 void
       
  1118 MacLow::NotifyAckTimeoutResetNow ()
       
  1119 {
       
  1120   for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++) 
       
  1121     {
       
  1122       (*i)->AckTimeoutReset ();
       
  1123     }
       
  1124 }
       
  1125 void
       
  1126 MacLow::NotifyCtsTimeoutStartNow (Time duration)
       
  1127 {
       
  1128   for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++) 
       
  1129     {
       
  1130       (*i)->CtsTimeoutStart (duration);
       
  1131     }
       
  1132 }
       
  1133 void
       
  1134 MacLow::NotifyCtsTimeoutResetNow ()
       
  1135 {
       
  1136   for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++) 
       
  1137     {
       
  1138       (*i)->CtsTimeoutReset ();
       
  1139     }
       
  1140 }
       
  1141 
       
  1142 void
       
  1143 MacLow::ForwardDown (Ptr<const Packet> packet, const WifiMacHeader* hdr, 
       
  1144                      WifiMode txMode)
       
  1145 {
       
  1146   NS_LOG_FUNCTION (this << packet << hdr << txMode);
       
  1147   NS_LOG_DEBUG ("send " << hdr->GetTypeString () <<
       
  1148                 ", to=" << hdr->GetAddr1 () <<
       
  1149                 ", size=" << packet->GetSize () <<
       
  1150                 ", mode=" << txMode <<
       
  1151                 ", duration=" << hdr->GetDuration () <<
       
  1152                 ", seq=0x"<< std::hex << m_currentHdr.GetSequenceControl () << std::dec);
       
  1153   m_phy->SendPacket (packet, txMode, WIFI_PREAMBLE_LONG, 0);
       
  1154 }
       
  1155 
       
  1156 void
       
  1157 MacLow::CtsTimeout (void)
       
  1158 {
       
  1159   NS_LOG_FUNCTION (this);
       
  1160   NS_LOG_DEBUG ("cts timeout");
       
  1161   // XXX: should check that there was no rx start before now.
       
  1162   // we should restart a new cts timeout now until the expected
       
  1163   // end of rx if there was a rx start before now.
       
  1164   m_stationManager->ReportRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
       
  1165   m_currentPacket = 0;
       
  1166   MacLowTransmissionListener *listener = m_listener;
       
  1167   m_listener = 0;
       
  1168   listener->MissedCts ();
       
  1169 }
       
  1170 void
       
  1171 MacLow::NormalAckTimeout (void)
       
  1172 {
       
  1173   NS_LOG_FUNCTION (this);
       
  1174   NS_LOG_DEBUG ("normal ack timeout");
       
  1175   // XXX: should check that there was no rx start before now.
       
  1176   // we should restart a new ack timeout now until the expected
       
  1177   // end of rx if there was a rx start before now.
       
  1178   m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
       
  1179   MacLowTransmissionListener *listener = m_listener;
       
  1180   m_listener = 0;
       
  1181   listener->MissedAck ();
       
  1182 }
       
  1183 void
       
  1184 MacLow::FastAckTimeout (void)
       
  1185 {
       
  1186   NS_LOG_FUNCTION (this);
       
  1187   m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
       
  1188   MacLowTransmissionListener *listener = m_listener;
       
  1189   m_listener = 0;
       
  1190   if (m_phy->IsStateIdle ()) 
       
  1191     {
       
  1192       NS_LOG_DEBUG ("fast Ack idle missed");
       
  1193       listener->MissedAck ();
       
  1194     }
       
  1195   else
       
  1196     {
       
  1197       NS_LOG_DEBUG ("fast Ack ok");
       
  1198     }
       
  1199 }
       
  1200 void
       
  1201 MacLow::BlockAckTimeout (void)
       
  1202 {
       
  1203   NS_LOG_FUNCTION (this);
       
  1204   NS_LOG_DEBUG ("block ack timeout");
       
  1205 
       
  1206   m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
       
  1207   MacLowTransmissionListener *listener = m_listener;
       
  1208   m_listener = 0;
       
  1209   listener->MissedBlockAck ();
       
  1210 }
       
  1211 void
       
  1212 MacLow::SuperFastAckTimeout ()
       
  1213 {
       
  1214   NS_LOG_FUNCTION (this);
       
  1215   m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
       
  1216   MacLowTransmissionListener *listener = m_listener;
       
  1217   m_listener = 0;
       
  1218   if (m_phy->IsStateIdle ()) 
       
  1219     {
       
  1220       NS_LOG_DEBUG ("super fast Ack failed");
       
  1221       listener->MissedAck ();
       
  1222     } 
       
  1223   else 
       
  1224     {
       
  1225       NS_LOG_DEBUG ("super fast Ack ok");
       
  1226       listener->GotAck (0.0, WifiMode ());
       
  1227     }
       
  1228 }
       
  1229 
       
  1230 void
       
  1231 MacLow::SendRtsForPacket (void)
       
  1232 {
       
  1233   NS_LOG_FUNCTION (this);
       
  1234   /* send an RTS for this packet. */
       
  1235   WifiMacHeader rts;
       
  1236   rts.SetType (WIFI_MAC_CTL_RTS);
       
  1237   rts.SetDsNotFrom ();
       
  1238   rts.SetDsNotTo ();
       
  1239   rts.SetNoRetry ();
       
  1240   rts.SetNoMoreFragments ();
       
  1241   rts.SetAddr1 (m_currentHdr.GetAddr1 ());
       
  1242   rts.SetAddr2 (m_self);
       
  1243   WifiMode rtsTxMode = GetRtsTxMode (m_currentPacket, &m_currentHdr);
       
  1244   Time duration = Seconds (0);
       
  1245   if (m_txParams.HasDurationId ()) 
       
  1246     {
       
  1247       duration += m_txParams.GetDurationId ();
       
  1248     } 
       
  1249   else 
       
  1250     {
       
  1251       WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
       
  1252       duration += GetSifs ();
       
  1253       duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxMode);
       
  1254       duration += GetSifs ();
       
  1255       duration += m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), 
       
  1256                                               dataTxMode, WIFI_PREAMBLE_LONG);
       
  1257       duration += GetSifs ();
       
  1258       duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
       
  1259     }
       
  1260   rts.SetDuration (duration);
       
  1261 
       
  1262   Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxMode, WIFI_PREAMBLE_LONG);
       
  1263   Time timerDelay = txDuration + GetCtsTimeout ();
       
  1264 
       
  1265   NS_ASSERT (m_ctsTimeoutEvent.IsExpired ());
       
  1266   NotifyCtsTimeoutStartNow (timerDelay);
       
  1267   m_ctsTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::CtsTimeout, this);
       
  1268 
       
  1269   Ptr<Packet> packet = Create<Packet> ();
       
  1270   packet->AddHeader (rts);
       
  1271   WifiMacTrailer fcs;
       
  1272   packet->AddTrailer (fcs);
       
  1273 
       
  1274   ForwardDown (packet, &rts, rtsTxMode);
       
  1275 }
       
  1276 
       
  1277 void
       
  1278 MacLow::StartDataTxTimers (void)
       
  1279 {
       
  1280   WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
       
  1281   Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxMode, WIFI_PREAMBLE_LONG);
       
  1282   if (m_txParams.MustWaitNormalAck ()) 
       
  1283     {
       
  1284       Time timerDelay = txDuration + GetAckTimeout ();
       
  1285       NS_ASSERT (m_normalAckTimeoutEvent.IsExpired ());
       
  1286       NotifyAckTimeoutStartNow (timerDelay);
       
  1287       m_normalAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::NormalAckTimeout, this);
       
  1288     } 
       
  1289   else if (m_txParams.MustWaitFastAck ()) 
       
  1290     {
       
  1291       Time timerDelay = txDuration + GetPifs ();
       
  1292       NS_ASSERT (m_fastAckTimeoutEvent.IsExpired ());
       
  1293       NotifyAckTimeoutStartNow (timerDelay);
       
  1294       m_fastAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::FastAckTimeout, this);
       
  1295     } 
       
  1296   else if (m_txParams.MustWaitSuperFastAck ()) 
       
  1297     {
       
  1298       Time timerDelay = txDuration + GetPifs ();
       
  1299       NS_ASSERT (m_superFastAckTimeoutEvent.IsExpired ());
       
  1300       NotifyAckTimeoutStartNow (timerDelay);
       
  1301       m_superFastAckTimeoutEvent = Simulator::Schedule (timerDelay, 
       
  1302                                                         &MacLow::SuperFastAckTimeout, this);
       
  1303     }
       
  1304   else if (m_txParams.MustWaitBasicBlockAck ())
       
  1305     {
       
  1306       Time timerDelay = txDuration + GetBasicBlockAckTimeout ();
       
  1307       NS_ASSERT (m_blockAckTimeoutEvent.IsExpired ());
       
  1308       m_blockAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::BlockAckTimeout, this);
       
  1309     }
       
  1310   else if (m_txParams.MustWaitCompressedBlockAck ())
       
  1311     {
       
  1312       Time timerDelay = txDuration + GetCompressedBlockAckTimeout ();
       
  1313       NS_ASSERT (m_blockAckTimeoutEvent.IsExpired ());
       
  1314       m_blockAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::BlockAckTimeout, this);
       
  1315     }
       
  1316   else if (m_txParams.HasNextPacket ()) 
       
  1317     {
       
  1318       Time delay = txDuration + GetSifs ();
       
  1319       NS_ASSERT (m_waitSifsEvent.IsExpired ());
       
  1320       m_waitSifsEvent = Simulator::Schedule (delay, &MacLow::WaitSifsAfterEndTx, this);
       
  1321     } 
       
  1322   else 
       
  1323     {
       
  1324       // since we do not expect any timer to be triggered.
       
  1325       m_listener = 0;
       
  1326     }
       
  1327 }
       
  1328 
       
  1329 void
       
  1330 MacLow::SendDataPacket (void)
       
  1331 {
       
  1332   NS_LOG_FUNCTION (this);
       
  1333   /* send this packet directly. No RTS is needed. */
       
  1334   StartDataTxTimers ();
       
  1335 
       
  1336   WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
       
  1337   Time duration = Seconds (0.0);
       
  1338   if (m_txParams.HasDurationId ()) 
       
  1339     {
       
  1340       duration += m_txParams.GetDurationId ();
       
  1341     } 
       
  1342   else 
       
  1343     {
       
  1344       if (m_txParams.MustWaitBasicBlockAck ())
       
  1345         {
       
  1346           duration += GetSifs ();
       
  1347           duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxMode, BASIC_BLOCK_ACK);
       
  1348         }
       
  1349       else if (m_txParams.MustWaitCompressedBlockAck ())
       
  1350         {
       
  1351           duration += GetSifs ();
       
  1352           duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxMode, COMPRESSED_BLOCK_ACK);
       
  1353         }
       
  1354       else if (m_txParams.MustWaitAck ()) 
       
  1355         {
       
  1356           duration += GetSifs ();
       
  1357           duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
       
  1358         }
       
  1359       if (m_txParams.HasNextPacket ()) 
       
  1360         {
       
  1361           duration += GetSifs ();
       
  1362           duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (), 
       
  1363                                                   dataTxMode, WIFI_PREAMBLE_LONG);
       
  1364           if (m_txParams.MustWaitAck ()) 
       
  1365             {
       
  1366               duration += GetSifs ();
       
  1367               duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
       
  1368             }
       
  1369         }
       
  1370     }
       
  1371   m_currentHdr.SetDuration (duration);
       
  1372 
       
  1373   m_currentPacket->AddHeader (m_currentHdr);
       
  1374   WifiMacTrailer fcs;
       
  1375   m_currentPacket->AddTrailer (fcs);
       
  1376 
       
  1377   ForwardDown (m_currentPacket, &m_currentHdr, dataTxMode);
       
  1378   m_currentPacket = 0;
       
  1379 }
       
  1380 
       
  1381 bool 
       
  1382 MacLow::IsNavZero (void) const
       
  1383 {
       
  1384   if (m_lastNavStart + m_lastNavDuration < Simulator::Now ()) 
       
  1385     {
       
  1386       return true;
       
  1387     } 
       
  1388   else 
       
  1389     {
       
  1390       return false;
       
  1391     }
       
  1392 }
       
  1393 
       
  1394 void
       
  1395 MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode rtsTxMode, double rtsSnr)
       
  1396 {
       
  1397   NS_LOG_FUNCTION (this << source << duration << rtsTxMode << rtsSnr);
       
  1398   /* send a CTS when you receive a RTS 
       
  1399    * right after SIFS.
       
  1400    */
       
  1401   WifiMode ctsTxMode = GetCtsTxModeForRts (source, rtsTxMode);
       
  1402   WifiMacHeader cts;
       
  1403   cts.SetType (WIFI_MAC_CTL_CTS);
       
  1404   cts.SetDsNotFrom ();
       
  1405   cts.SetDsNotTo ();
       
  1406   cts.SetNoMoreFragments ();
       
  1407   cts.SetNoRetry ();
       
  1408   cts.SetAddr1 (source);
       
  1409   duration -= GetCtsDuration (source, rtsTxMode);
       
  1410   duration -= GetSifs ();
       
  1411   NS_ASSERT (duration >= MicroSeconds (0));
       
  1412   cts.SetDuration (duration);
       
  1413 
       
  1414   Ptr<Packet> packet = Create<Packet> ();
       
  1415   packet->AddHeader (cts);
       
  1416   WifiMacTrailer fcs;
       
  1417   packet->AddTrailer (fcs);
       
  1418 
       
  1419   SnrTag tag;
       
  1420   tag.Set (rtsSnr);
       
  1421   packet->AddPacketTag (tag);
       
  1422 
       
  1423   ForwardDown (packet, &cts, ctsTxMode);
       
  1424 }
       
  1425 
       
  1426 void
       
  1427 MacLow::SendDataAfterCts (Mac48Address source, Time duration, WifiMode txMode)
       
  1428 {
       
  1429   NS_LOG_FUNCTION (this);
       
  1430   /* send the third step in a 
       
  1431    * RTS/CTS/DATA/ACK hanshake 
       
  1432    */
       
  1433   NS_ASSERT (m_currentPacket != 0);
       
  1434   StartDataTxTimers ();
       
  1435 
       
  1436   WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
       
  1437   Time newDuration = Seconds (0);
       
  1438   newDuration += GetSifs ();
       
  1439   newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
       
  1440   Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), 
       
  1441                                                 dataTxMode, WIFI_PREAMBLE_LONG);
       
  1442   duration -= txDuration;
       
  1443   duration -= GetSifs ();
       
  1444 
       
  1445   duration = std::max (duration, newDuration);
       
  1446   NS_ASSERT (duration >= MicroSeconds (0));
       
  1447   m_currentHdr.SetDuration (duration);
       
  1448 
       
  1449   m_currentPacket->AddHeader (m_currentHdr);
       
  1450   WifiMacTrailer fcs;
       
  1451   m_currentPacket->AddTrailer (fcs);
       
  1452 
       
  1453   ForwardDown (m_currentPacket, &m_currentHdr, dataTxMode);
       
  1454   m_currentPacket = 0;
       
  1455 }
       
  1456 
       
  1457 void 
       
  1458 MacLow::WaitSifsAfterEndTx (void)
       
  1459 {
       
  1460   m_listener->StartNext ();
       
  1461 }
       
  1462 
       
  1463 void
       
  1464 MacLow::FastAckFailedTimeout (void)
       
  1465 {
       
  1466   NS_LOG_FUNCTION (this);
       
  1467   MacLowTransmissionListener *listener = m_listener;
       
  1468   m_listener = 0;
       
  1469   listener->MissedAck ();
       
  1470   NS_LOG_DEBUG ("fast Ack busy but missed");
       
  1471 }
       
  1472 
       
  1473 void
       
  1474 MacLow::SendAckAfterData (Mac48Address source, Time duration, WifiMode dataTxMode, double dataSnr)
       
  1475 {
       
  1476   NS_LOG_FUNCTION (this);
       
  1477   /* send an ACK when you receive 
       
  1478    * a packet after SIFS. 
       
  1479    */
       
  1480   WifiMode ackTxMode = GetAckTxModeForData (source, dataTxMode);
       
  1481   WifiMacHeader ack;
       
  1482   ack.SetType (WIFI_MAC_CTL_ACK);
       
  1483   ack.SetDsNotFrom ();
       
  1484   ack.SetDsNotTo ();
       
  1485   ack.SetNoRetry ();
       
  1486   ack.SetNoMoreFragments ();
       
  1487   ack.SetAddr1 (source);
       
  1488   duration -= GetAckDuration (source, dataTxMode);
       
  1489   duration -= GetSifs ();
       
  1490   NS_ASSERT (duration >= MicroSeconds (0));
       
  1491   ack.SetDuration (duration);
       
  1492 
       
  1493   Ptr<Packet> packet = Create<Packet> ();
       
  1494   packet->AddHeader (ack);
       
  1495   WifiMacTrailer fcs;
       
  1496   packet->AddTrailer (fcs);
       
  1497 
       
  1498   SnrTag tag;
       
  1499   tag.Set (dataSnr);
       
  1500   packet->AddPacketTag (tag);
       
  1501 
       
  1502   ForwardDown (packet, &ack, ackTxMode);
       
  1503 }
       
  1504 
       
  1505 bool
       
  1506 MacLow::StoreMpduIfNeeded (Ptr<Packet> packet, WifiMacHeader hdr)
       
  1507 {
       
  1508   AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
       
  1509   if (it != m_bAckAgreements.end ())
       
  1510     {
       
  1511       WifiMacTrailer fcs;
       
  1512       packet->RemoveTrailer (fcs);
       
  1513       BufferedPacket bufferedPacket (packet, hdr);
       
  1514 
       
  1515       uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
       
  1516       uint16_t mappedSeqControl = QosUtilsMapSeqControlToUniqueInteger (hdr.GetSequenceControl (), endSequence);
       
  1517 
       
  1518       BufferedPacketI i = (*it).second.second.begin ();
       
  1519       for (; i != (*it).second.second.end () &&
       
  1520            QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceControl (), endSequence) < mappedSeqControl; i++) ;
       
  1521       (*it).second.second.insert (i, bufferedPacket);
       
  1522 
       
  1523       //Update block ack cache
       
  1524       BlockAckCachesI j = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
       
  1525       NS_ASSERT (j != m_bAckCaches.end ());
       
  1526       (*j).second.UpdateWithMpdu (&hdr);
       
  1527       
       
  1528       return true;
       
  1529     }
       
  1530   return false;
       
  1531 }
       
  1532 
       
  1533 void
       
  1534 MacLow::CreateBlockAckAgreement (const MgtAddBaResponseHeader *respHdr, Mac48Address originator,
       
  1535                                  uint16_t startingSeq)
       
  1536 {
       
  1537   uint8_t tid = respHdr->GetTid ();
       
  1538   BlockAckAgreement agreement (originator, tid);
       
  1539   if (respHdr->IsImmediateBlockAck ())
       
  1540     {
       
  1541       agreement.SetImmediateBlockAck ();
       
  1542     }
       
  1543   else
       
  1544     {
       
  1545       agreement.SetDelayedBlockAck ();
       
  1546     }
       
  1547   agreement.SetAmsduSupport (respHdr->IsAmsduSupported ());
       
  1548   agreement.SetBufferSize (respHdr->GetBufferSize () + 1);
       
  1549   agreement.SetTimeout (respHdr->GetTimeout ());
       
  1550   agreement.SetStartingSequence (startingSeq);
       
  1551 
       
  1552   std::list<BufferedPacket> buffer (0);
       
  1553   AgreementKey key (originator, respHdr->GetTid ());
       
  1554   AgreementValue value (agreement, buffer);
       
  1555   m_bAckAgreements.insert (std::make_pair (key, value));
       
  1556 
       
  1557   BlockAckCache cache;
       
  1558   cache.Init (startingSeq, respHdr->GetBufferSize () + 1);
       
  1559   m_bAckCaches.insert (std::make_pair (key, cache));
       
  1560 
       
  1561   if (respHdr->GetTimeout () != 0)
       
  1562     {
       
  1563       AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, respHdr->GetTid ()));
       
  1564       Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
       
  1565 
       
  1566       AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
       
  1567 
       
  1568       it->second.first.m_inactivityEvent = Simulator::Schedule (timeout,
       
  1569                                                                 &MacLowBlockAckEventListener::BlockAckInactivityTimeout,
       
  1570                                                                 m_edcaListeners[ac],
       
  1571                                                                 originator, tid);
       
  1572     }
       
  1573 }
       
  1574 
       
  1575 void
       
  1576 MacLow::DestroyBlockAckAgreement (Mac48Address originator, uint8_t tid)
       
  1577 {
       
  1578   AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
       
  1579   if (it != m_bAckAgreements.end ())
       
  1580     {
       
  1581       RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (), originator, tid);
       
  1582       RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
       
  1583       m_bAckAgreements.erase (it);
       
  1584 
       
  1585       BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
       
  1586       NS_ASSERT (i != m_bAckCaches.end ());
       
  1587       m_bAckCaches.erase (i);
       
  1588     }
       
  1589 }
       
  1590 
       
  1591 void
       
  1592 MacLow::RxCompleteBufferedPacketsWithSmallerSequence (uint16_t seq, Mac48Address originator, uint8_t tid)
       
  1593 {
       
  1594   AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
       
  1595   if (it != m_bAckAgreements.end ())
       
  1596     {
       
  1597       uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
       
  1598       uint16_t mappedStart = QosUtilsMapSeqControlToUniqueInteger (seq, endSequence);
       
  1599       uint16_t guard = (*it).second.second.begin ()->second.GetSequenceControl() & 0xfff0;
       
  1600       BufferedPacketI last = (*it).second.second.begin ();
       
  1601 
       
  1602       BufferedPacketI i = (*it).second.second.begin ();
       
  1603       for (; i != (*it).second.second.end () &&
       
  1604            QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceNumber (), endSequence) < mappedStart;)
       
  1605         {
       
  1606           if (guard == (*i).second.GetSequenceControl ())
       
  1607             {
       
  1608               if (!(*i).second.IsMoreFragments ())
       
  1609                 {
       
  1610                   while (last != i)
       
  1611                     {
       
  1612                       m_rxCallback ((*last).first, &(*last).second);
       
  1613                       last++;
       
  1614                     }
       
  1615                   m_rxCallback ((*last).first, &(*last).second);
       
  1616                   last++;
       
  1617                   /* go to next packet */
       
  1618                   while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
       
  1619                     {
       
  1620                       i++;
       
  1621                     }
       
  1622                   if (i != (*it).second.second.end ())
       
  1623                     {
       
  1624                       guard = (*i).second.GetSequenceControl () & 0xfff0;
       
  1625                       last = i;
       
  1626                     }
       
  1627                 }
       
  1628               else
       
  1629                 {
       
  1630                   guard++;
       
  1631                 }
       
  1632             }
       
  1633           else
       
  1634             {
       
  1635               /* go to next packet */
       
  1636               while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
       
  1637                 {
       
  1638                   i++;
       
  1639                 }
       
  1640               if (i != (*it).second.second.end ())
       
  1641                 {
       
  1642                   guard = (*i).second.GetSequenceControl () & 0xfff0;
       
  1643                   last = i;
       
  1644                 }
       
  1645             }
       
  1646         }
       
  1647       (*it).second.second.erase ((*it).second.second.begin (), i);
       
  1648     }
       
  1649 }
       
  1650 
       
  1651 void
       
  1652 MacLow::RxCompleteBufferedPacketsUntilFirstLost (Mac48Address originator, uint8_t tid)
       
  1653 {
       
  1654   AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
       
  1655   if (it != m_bAckAgreements.end ())
       
  1656     {
       
  1657       uint16_t startingSeqCtrl = ((*it).second.first.GetStartingSequence ()<<4) & 0xfff0;
       
  1658       uint16_t guard = startingSeqCtrl;
       
  1659 
       
  1660       BufferedPacketI lastComplete = (*it).second.second.begin ();
       
  1661       BufferedPacketI i = (*it).second.second.begin ();
       
  1662       for (; i != (*it).second.second.end() && guard == (*i).second.GetSequenceControl (); i++)
       
  1663         {
       
  1664           if (!(*i).second.IsMoreFragments ())
       
  1665             {
       
  1666               while (lastComplete != i)
       
  1667                 {
       
  1668                   m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
       
  1669                   lastComplete++;
       
  1670                 }
       
  1671               m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
       
  1672               lastComplete++;
       
  1673             }
       
  1674           guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
       
  1675         }
       
  1676       (*it).second.first.SetStartingSequence ((guard>>4)&0x0fff);
       
  1677       /* All packets already forwarded to WifiMac must be removed from buffer: 
       
  1678       [begin (), lastComplete) */
       
  1679       (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
       
  1680     }
       
  1681 }
       
  1682 
       
  1683 void
       
  1684 MacLow::SendBlockAckResponse (const CtrlBAckResponseHeader* blockAck, Mac48Address originator, bool immediate,
       
  1685                               Time duration, WifiMode blockAckReqTxMode)
       
  1686 {
       
  1687   Ptr<Packet> packet = Create<Packet> ();
       
  1688   packet->AddHeader (*blockAck);
       
  1689 
       
  1690   WifiMacHeader hdr;
       
  1691   hdr.SetType (WIFI_MAC_CTL_BACKRESP);
       
  1692   hdr.SetAddr1 (originator);
       
  1693   hdr.SetAddr2 (GetAddress ());
       
  1694   hdr.SetDsNotFrom ();
       
  1695   hdr.SetDsNotTo ();
       
  1696   hdr.SetNoRetry ();
       
  1697   hdr.SetNoMoreFragments ();
       
  1698 
       
  1699   m_currentPacket = packet;
       
  1700   m_currentHdr = hdr;
       
  1701   if (immediate)
       
  1702     {
       
  1703       m_txParams.DisableAck ();
       
  1704       duration -= GetSifs ();
       
  1705       if (blockAck->IsBasic ())
       
  1706         {
       
  1707           duration -= GetBlockAckDuration (originator, blockAckReqTxMode, BASIC_BLOCK_ACK);
       
  1708         }
       
  1709       else if (blockAck->IsCompressed ())
       
  1710         {
       
  1711           duration -= GetBlockAckDuration (originator, blockAckReqTxMode, COMPRESSED_BLOCK_ACK);
       
  1712         }
       
  1713       else if (blockAck->IsMultiTid ())
       
  1714         {
       
  1715           NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
       
  1716         }
       
  1717     }
       
  1718   else
       
  1719     {
       
  1720       m_txParams.EnableAck ();
       
  1721       duration += GetSifs ();
       
  1722       duration += GetAckDuration (originator, blockAckReqTxMode);
       
  1723     }
       
  1724   m_txParams.DisableNextData ();
       
  1725 
       
  1726   StartDataTxTimers ();
       
  1727 
       
  1728   NS_ASSERT (duration >= MicroSeconds (0));
       
  1729   hdr.SetDuration (duration);
       
  1730   //here should be present a control about immediate or delayed block ack
       
  1731   //for now we assume immediate
       
  1732   packet->AddHeader (hdr);
       
  1733   WifiMacTrailer fcs;
       
  1734   packet->AddTrailer (fcs);
       
  1735   ForwardDown (packet, &hdr, blockAckReqTxMode);
       
  1736   m_currentPacket = 0;
       
  1737 }
       
  1738 
       
  1739 void
       
  1740 MacLow::SendBlockAckAfterBlockAckRequest (const CtrlBAckRequestHeader reqHdr, Mac48Address originator,
       
  1741                                           Time duration, WifiMode blockAckReqTxMode)
       
  1742 {
       
  1743   NS_LOG_FUNCTION (this);
       
  1744   CtrlBAckResponseHeader blockAck;
       
  1745   uint8_t tid;
       
  1746   bool immediate = false;
       
  1747   if (!reqHdr.IsMultiTid ())
       
  1748     {
       
  1749       tid = reqHdr.GetTidInfo ();
       
  1750       AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
       
  1751       if (it != m_bAckAgreements.end ())
       
  1752         {
       
  1753           blockAck.SetStartingSequence (reqHdr.GetStartingSequence ());
       
  1754           blockAck.SetTidInfo (tid);
       
  1755           immediate = (*it).second.first.IsImmediateBlockAck ();
       
  1756           if (reqHdr.IsBasic ())
       
  1757             {
       
  1758               blockAck.SetType (BASIC_BLOCK_ACK);
       
  1759             }
       
  1760           else if (reqHdr.IsCompressed ())
       
  1761             {
       
  1762               blockAck.SetType (COMPRESSED_BLOCK_ACK);
       
  1763             }
       
  1764           BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
       
  1765           NS_ASSERT (i != m_bAckCaches.end ());
       
  1766           (*i).second.FillBlockAckBitmap (&blockAck);
       
  1767 
       
  1768           /* All packets with smaller sequence than starting sequence control must be passed up to Wifimac 
       
  1769            * See 9.10.3 in IEEE8022.11e standard.
       
  1770            */
       
  1771           RxCompleteBufferedPacketsWithSmallerSequence (reqHdr.GetStartingSequence (), originator, tid);
       
  1772           RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
       
  1773         }
       
  1774       else
       
  1775         {
       
  1776           NS_LOG_DEBUG ("there's not a valid block ack agreement with "<<originator);
       
  1777         }
       
  1778     }
       
  1779   else
       
  1780     {
       
  1781       NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
       
  1782     }
       
  1783 
       
  1784   SendBlockAckResponse (&blockAck, originator, immediate, duration, blockAckReqTxMode);
       
  1785 }
       
  1786 
       
  1787 void
       
  1788 MacLow::ResetBlockAckInactivityTimerIfNeeded (BlockAckAgreement &agreement)
       
  1789 {
       
  1790   if (agreement.GetTimeout () != 0)
       
  1791     {
       
  1792       NS_ASSERT (agreement.m_inactivityEvent.IsRunning ());
       
  1793       agreement.m_inactivityEvent.Cancel ();
       
  1794       Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
       
  1795 
       
  1796       AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
       
  1797       //std::map<AcIndex, MacLowTransmissionListener*>::iterator it = m_edcaListeners.find (ac);
       
  1798       //NS_ASSERT (it != m_edcaListeners.end ());
       
  1799 
       
  1800       agreement.m_inactivityEvent = Simulator::Schedule (timeout, 
       
  1801                                                          &MacLowBlockAckEventListener::BlockAckInactivityTimeout, 
       
  1802                                                          m_edcaListeners[ac],
       
  1803                                                          agreement.GetPeer (),
       
  1804                                                          agreement.GetTid ());
       
  1805     }
       
  1806 }
       
  1807 
       
  1808 void
       
  1809 MacLow::RegisterBlockAckListenerForAc (enum AcIndex ac, MacLowBlockAckEventListener *listener)
       
  1810 {
       
  1811   m_edcaListeners.insert (std::make_pair (ac, listener));
       
  1812 }
       
  1813 
       
  1814 } // namespace ns3