src/devices/wifi/mac-low.cc
changeset 6068 a2127017ecb4
parent 6065 0f012e7d9128
parent 5964 8a59a619c30e
child 6304 645b4e644c12
equal deleted inserted replaced
6067:ccbdc2b19ea5 6068:a2127017ecb4
     1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     2 /*
     2 /*
     3  * Copyright (c) 2005,2006 INRIA
     3  * Copyright (c) 2005,2006 INRIA
       
     4  * Copyright (c) 2009 MIRKO BANCHI
     4  *
     5  *
     5  * This program is free software; you can redistribute it and/or modify
     6  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License version 2 as 
     7  * it under the terms of the GNU General Public License version 2 as 
     7  * published by the Free Software Foundation;
     8  * published by the Free Software Foundation;
     8  *
     9  *
    14  * You should have received a copy of the GNU General Public License
    15  * You should have received a copy of the GNU General Public License
    15  * along with this program; if not, write to the Free Software
    16  * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    17  *
    18  *
    18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
    19  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
       
    20  * Author: Mirko Banchi <mk.banchi@gmail.com>
    19  */
    21  */
    20 
    22 
    21 #include "ns3/assert.h"
    23 #include "ns3/assert.h"
    22 #include "ns3/packet.h"
    24 #include "ns3/packet.h"
    23 #include "ns3/simulator.h"
    25 #include "ns3/simulator.h"
    27 #include "ns3/double.h"
    29 #include "ns3/double.h"
    28 
    30 
    29 #include "mac-low.h"
    31 #include "mac-low.h"
    30 #include "wifi-phy.h"
    32 #include "wifi-phy.h"
    31 #include "wifi-mac-trailer.h"
    33 #include "wifi-mac-trailer.h"
       
    34 #include "qos-utils.h"
       
    35 #include "edca-txop-n.h"
    32 
    36 
    33 NS_LOG_COMPONENT_DEFINE ("MacLow");
    37 NS_LOG_COMPONENT_DEFINE ("MacLow");
    34 
    38 
    35 #undef NS_LOG_APPEND_CONTEXT
    39 #undef NS_LOG_APPEND_CONTEXT
    36 #define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] "
    40 #define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] "
   109 
   113 
   110 MacLowTransmissionListener::MacLowTransmissionListener ()
   114 MacLowTransmissionListener::MacLowTransmissionListener ()
   111 {}
   115 {}
   112 MacLowTransmissionListener::~MacLowTransmissionListener ()
   116 MacLowTransmissionListener::~MacLowTransmissionListener ()
   113 {}
   117 {}
       
   118 void
       
   119 MacLowTransmissionListener::GotBlockAck (const CtrlBAckResponseHeader *blockAck,
       
   120                                          Mac48Address source)
       
   121 {}
       
   122 void
       
   123 MacLowTransmissionListener::MissedBlockAck (void)
       
   124 {}
   114 MacLowDcfListener::MacLowDcfListener ()
   125 MacLowDcfListener::MacLowDcfListener ()
   115 {}
   126 {}
   116 MacLowDcfListener::~MacLowDcfListener ()
   127 MacLowDcfListener::~MacLowDcfListener ()
       
   128 {}
       
   129 
       
   130 MacLowBlockAckEventListener::MacLowBlockAckEventListener ()
       
   131 {}
       
   132 MacLowBlockAckEventListener::~MacLowBlockAckEventListener ()
   117 {}
   133 {}
   118 
   134 
   119 MacLowTransmissionParameters::MacLowTransmissionParameters ()
   135 MacLowTransmissionParameters::MacLowTransmissionParameters ()
   120   : m_nextSize (0),
   136   : m_nextSize (0),
   121     m_waitAck (ACK_NONE),
   137     m_waitAck (ACK_NONE),
   145 void 
   161 void 
   146 MacLowTransmissionParameters::EnableSuperFastAck (void)
   162 MacLowTransmissionParameters::EnableSuperFastAck (void)
   147 {
   163 {
   148   m_waitAck = ACK_SUPER_FAST;
   164   m_waitAck = ACK_SUPER_FAST;
   149 }
   165 }
       
   166 void
       
   167 MacLowTransmissionParameters::EnableBasicBlockAck (void)
       
   168 {
       
   169   m_waitAck = BLOCK_ACK_BASIC;
       
   170 }
       
   171 void
       
   172 MacLowTransmissionParameters::EnableCompressedBlockAck (void)
       
   173 {
       
   174   m_waitAck = BLOCK_ACK_COMPRESSED;
       
   175 }
       
   176 void
       
   177 MacLowTransmissionParameters::EnableMultiTidBlockAck (void)
       
   178 {
       
   179   m_waitAck = BLOCK_ACK_MULTI_TID;
       
   180 }
   150 void 
   181 void 
   151 MacLowTransmissionParameters::EnableFastAck (void)
   182 MacLowTransmissionParameters::EnableFastAck (void)
   152 {
   183 {
   153   m_waitAck = ACK_FAST;
   184   m_waitAck = ACK_FAST;
   154 }
   185 }
   189 }
   220 }
   190 bool 
   221 bool 
   191 MacLowTransmissionParameters::MustWaitSuperFastAck (void) const
   222 MacLowTransmissionParameters::MustWaitSuperFastAck (void) const
   192 {
   223 {
   193   return (m_waitAck == ACK_SUPER_FAST);
   224   return (m_waitAck == ACK_SUPER_FAST);
       
   225 }
       
   226 bool
       
   227 MacLowTransmissionParameters::MustWaitBasicBlockAck (void) const
       
   228 {
       
   229   return (m_waitAck == BLOCK_ACK_BASIC)?true:false;
       
   230 }
       
   231 bool
       
   232 MacLowTransmissionParameters::MustWaitCompressedBlockAck (void) const
       
   233 {
       
   234   return (m_waitAck == BLOCK_ACK_COMPRESSED)?true:false;
       
   235 }
       
   236 bool
       
   237 MacLowTransmissionParameters::MustWaitMultiTidBlockAck (void) const
       
   238 {
       
   239   return (m_waitAck == BLOCK_ACK_MULTI_TID)?true:false;
   194 }
   240 }
   195 bool 
   241 bool 
   196 MacLowTransmissionParameters::MustSendRts (void) const
   242 MacLowTransmissionParameters::MustSendRts (void) const
   197 {
   243 {
   198   return m_sendRts;
   244   return m_sendRts;
   238     os << "fast";
   284     os << "fast";
   239     break;
   285     break;
   240   case MacLowTransmissionParameters::ACK_SUPER_FAST:
   286   case MacLowTransmissionParameters::ACK_SUPER_FAST:
   241     os << "super-fast";
   287     os << "super-fast";
   242     break;
   288     break;
       
   289   case MacLowTransmissionParameters::BLOCK_ACK_BASIC:
       
   290     os << "basic-block-ack";
       
   291     break;
       
   292   case MacLowTransmissionParameters::BLOCK_ACK_COMPRESSED:
       
   293     os << "compressed-block-ack";
       
   294     break;
       
   295   case MacLowTransmissionParameters::BLOCK_ACK_MULTI_TID:
       
   296     os << "multi-tid-block-ack";
       
   297     break;
   243   }
   298   }
   244   os << "]";
   299   os << "]";
   245   return os;
   300   return os;
   246 }
   301 }
   247 
   302 
   272 MacLow::MacLow ()
   327 MacLow::MacLow ()
   273   : m_normalAckTimeoutEvent (),
   328   : m_normalAckTimeoutEvent (),
   274     m_fastAckTimeoutEvent (),
   329     m_fastAckTimeoutEvent (),
   275     m_superFastAckTimeoutEvent (),
   330     m_superFastAckTimeoutEvent (),
   276     m_fastAckFailedTimeoutEvent (),
   331     m_fastAckFailedTimeoutEvent (),
       
   332     m_blockAckTimeoutEvent (),
   277     m_ctsTimeoutEvent (),
   333     m_ctsTimeoutEvent (),
   278     m_sendCtsEvent (),
   334     m_sendCtsEvent (),
   279     m_sendAckEvent (),
   335     m_sendAckEvent (),
   280     m_sendDataEvent (),
   336     m_sendDataEvent (),
   281     m_waitSifsEvent (),
   337     m_waitSifsEvent (),
   306   NS_LOG_FUNCTION (this);
   362   NS_LOG_FUNCTION (this);
   307   m_normalAckTimeoutEvent.Cancel ();
   363   m_normalAckTimeoutEvent.Cancel ();
   308   m_fastAckTimeoutEvent.Cancel ();
   364   m_fastAckTimeoutEvent.Cancel ();
   309   m_superFastAckTimeoutEvent.Cancel ();
   365   m_superFastAckTimeoutEvent.Cancel ();
   310   m_fastAckFailedTimeoutEvent.Cancel ();
   366   m_fastAckFailedTimeoutEvent.Cancel ();
       
   367   m_blockAckTimeoutEvent.Cancel ();
   311   m_ctsTimeoutEvent.Cancel ();
   368   m_ctsTimeoutEvent.Cancel ();
   312   m_sendCtsEvent.Cancel ();
   369   m_sendCtsEvent.Cancel ();
   313   m_sendAckEvent.Cancel ();
   370   m_sendAckEvent.Cancel ();
   314   m_sendDataEvent.Cancel ();
   371   m_sendDataEvent.Cancel ();
   315   m_waitSifsEvent.Cancel ();
   372   m_waitSifsEvent.Cancel ();
   342   if (m_fastAckFailedTimeoutEvent.IsRunning ()) 
   399   if (m_fastAckFailedTimeoutEvent.IsRunning ()) 
   343     {
   400     {
   344       m_fastAckFailedTimeoutEvent.Cancel ();
   401       m_fastAckFailedTimeoutEvent.Cancel ();
   345       oneRunning = true;
   402       oneRunning = true;
   346     }
   403     }
       
   404   if (m_blockAckTimeoutEvent.IsRunning ())
       
   405     {
       
   406       m_blockAckTimeoutEvent.Cancel ();
       
   407       oneRunning = true;
       
   408     }
   347   if (m_ctsTimeoutEvent.IsRunning ()) 
   409   if (m_ctsTimeoutEvent.IsRunning ()) 
   348     {
   410     {
   349       m_ctsTimeoutEvent.Cancel ();
   411       m_ctsTimeoutEvent.Cancel ();
   350       oneRunning = true;
   412       oneRunning = true;
   351     }
   413     }
   398 void 
   460 void 
   399 MacLow::SetAckTimeout (Time ackTimeout)
   461 MacLow::SetAckTimeout (Time ackTimeout)
   400 {
   462 {
   401   m_ackTimeout = ackTimeout;
   463   m_ackTimeout = ackTimeout;
   402 }
   464 }
       
   465 void
       
   466 MacLow::SetBasicBlockAckTimeout (Time blockAckTimeout)
       
   467 {
       
   468   m_basicBlockAckTimeout = blockAckTimeout;
       
   469 }
       
   470 void
       
   471 MacLow::SetCompressedBlockAckTimeout (Time blockAckTimeout)
       
   472 {
       
   473   m_compressedBlockAckTimeout = blockAckTimeout;
       
   474 }
   403 void 
   475 void 
   404 MacLow::SetCtsTimeout (Time ctsTimeout)
   476 MacLow::SetCtsTimeout (Time ctsTimeout)
   405 {
   477 {
   406   m_ctsTimeout = ctsTimeout;
   478   m_ctsTimeout = ctsTimeout;
   407 }
   479 }
   432 }
   504 }
   433 Time 
   505 Time 
   434 MacLow::GetAckTimeout (void) const
   506 MacLow::GetAckTimeout (void) const
   435 {
   507 {
   436   return m_ackTimeout;
   508   return m_ackTimeout;
       
   509 }
       
   510 Time
       
   511 MacLow::GetBasicBlockAckTimeout () const
       
   512 {
       
   513   return m_basicBlockAckTimeout;
       
   514 }
       
   515 Time
       
   516 MacLow::GetCompressedBlockAckTimeout () const
       
   517 {
       
   518   return m_compressedBlockAckTimeout;
   437 }
   519 }
   438 Time 
   520 Time 
   439 MacLow::GetCtsTimeout (void) const
   521 MacLow::GetCtsTimeout (void) const
   440 {
   522 {
   441   return m_ctsTimeout;
   523   return m_ctsTimeout;
   650         {
   732         {
   651           m_waitSifsEvent = Simulator::Schedule (GetSifs (), 
   733           m_waitSifsEvent = Simulator::Schedule (GetSifs (), 
   652                                                  &MacLow::WaitSifsAfterEndTx, this);
   734                                                  &MacLow::WaitSifsAfterEndTx, this);
   653         }
   735         }
   654     } 
   736     } 
       
   737   else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self &&
       
   738           (m_txParams.MustWaitBasicBlockAck () || m_txParams.MustWaitCompressedBlockAck ()) && 
       
   739            m_blockAckTimeoutEvent.IsRunning ())
       
   740     {
       
   741       NS_LOG_DEBUG ("got block ack from "<<hdr.GetAddr2 ());
       
   742       CtrlBAckResponseHeader blockAck;
       
   743       packet->RemoveHeader (blockAck);
       
   744       m_blockAckTimeoutEvent.Cancel ();
       
   745       m_listener->GotBlockAck (&blockAck, hdr.GetAddr2 ());
       
   746     }
       
   747   else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
       
   748     {
       
   749       CtrlBAckRequestHeader blockAckReq;
       
   750       packet->RemoveHeader (blockAckReq);
       
   751       if (!blockAckReq.IsMultiTid ())
       
   752         {
       
   753           AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), blockAckReq.GetTidInfo ()));
       
   754           if (it != m_bAckAgreements.end ())
       
   755             {
       
   756               NS_ASSERT (m_sendAckEvent.IsExpired ());
       
   757               /* See section 11.5.3 in IEEE802.11 for mean of this timer */
       
   758               ResetBlockAckInactivityTimerIfNeeded (it->second.first);
       
   759               if ((*it).second.first.IsImmediateBlockAck ())
       
   760                 {
       
   761                   NS_LOG_DEBUG ("rx blockAckRequest/sendImmediateBlockAck from="<< hdr.GetAddr2 ());
       
   762                   m_sendAckEvent = Simulator::Schedule (GetSifs (),
       
   763                                                         &MacLow::SendBlockAckAfterBlockAckRequest, this,
       
   764                                                         blockAckReq,
       
   765                                                         hdr.GetAddr2 (), 
       
   766                                                         hdr.GetDuration (),
       
   767                                                         txMode);
       
   768                 }
       
   769               else
       
   770                 {
       
   771                   NS_FATAL_ERROR ("Delayed block ack not supported.");
       
   772                 }
       
   773             }
       
   774           else
       
   775             {
       
   776               NS_LOG_DEBUG ("There's not a valid agreement for this block ack request.");
       
   777             }
       
   778         }
       
   779       else
       
   780         {
       
   781           NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
       
   782         }
       
   783     }
   655   else if (hdr.IsCtl ()) 
   784   else if (hdr.IsCtl ()) 
   656     {
   785     {
   657       NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ());
   786       NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ());
   658     } 
   787     } 
   659   else if (hdr.GetAddr1 () == m_self) 
   788   else if (hdr.GetAddr1 () == m_self) 
   660     {
   789     {
   661       m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
   790       m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
   662                                     rxSnr, txMode);
   791                                     rxSnr, txMode);
   663       
   792       
   664       if (hdr.IsQosData () && hdr.IsQosNoAck ()) 
   793       if (hdr.IsQosData () && StoreMpduIfNeeded (packet, hdr)) 
       
   794         {
       
   795           /* From section 9.10.4 in IEEE802.11:
       
   796              Upon the receipt of a QoS data frame from the originator for which
       
   797              the Block Ack agreement exists, the recipient shall buffer the MSDU
       
   798              regardless of the value of the Ack Policy subfield within the 
       
   799              QoS Control field of the QoS data frame. */
       
   800           if (hdr.IsQosAck ())
       
   801             {
       
   802               AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
       
   803               RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (),
       
   804                                                             hdr.GetAddr2 (), hdr.GetQosTid ());
       
   805               RxCompleteBufferedPackets (hdr.GetAddr2 (), hdr.GetQosTid ());
       
   806               NS_ASSERT (m_sendAckEvent.IsExpired ());
       
   807               m_sendAckEvent = Simulator::Schedule (GetSifs (),
       
   808                                                     &MacLow::SendAckAfterData, this,
       
   809                                                     hdr.GetAddr2 (), 
       
   810                                                     hdr.GetDuration (),
       
   811                                                     txMode,
       
   812                                                     rxSnr);
       
   813             }
       
   814           else if (hdr.IsQosBlockAck ())
       
   815             {
       
   816               AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
       
   817               /* See section 11.5.3 in IEEE802.11 for mean of this timer */
       
   818               ResetBlockAckInactivityTimerIfNeeded (it->second.first);
       
   819             }
       
   820           return;  
       
   821         }
       
   822       else if (hdr.IsQosData () && hdr.IsQosBlockAck ())
       
   823         {
       
   824           /* This happens if a packet with ack policy Block Ack is received and a block ack
       
   825              agreement for that packet doesn't exist.
       
   826 
       
   827              From section 11.5.3 in IEEE802.11e:
       
   828              When a recipient does not have an active Block ack for a TID, but receives
       
   829              data MPDUs with the Ack Policy subfield set to Block Ack, it shall discard
       
   830              them and shall send a DELBA frame using the normal access 
       
   831              mechanisms. */
       
   832           AccessClass ac = QosUtilsMapTidToAc (hdr.GetQosTid ());
       
   833           m_edcaListeners[ac]->BlockAckInactivityTimeout (hdr.GetAddr2 (), hdr.GetQosTid ());
       
   834           return;
       
   835         }
       
   836       else if (hdr.IsQosData () && hdr.IsQosNoAck ()) 
   665         {
   837         {
   666           NS_LOG_DEBUG ("rx unicast/noAck from="<<hdr.GetAddr2 ());
   838           NS_LOG_DEBUG ("rx unicast/noAck from="<<hdr.GetAddr2 ());
   667         } 
   839         } 
   668       else if (hdr.IsData () || hdr.IsMgt ()) 
   840       else if (hdr.IsData () || hdr.IsMgt ()) 
   669         {
   841         {
   707 {
   879 {
   708   WifiMacHeader ack;
   880   WifiMacHeader ack;
   709   ack.SetType (WIFI_MAC_CTL_ACK);
   881   ack.SetType (WIFI_MAC_CTL_ACK);
   710   return ack.GetSize () + 4;
   882   return ack.GetSize () + 4;
   711 }
   883 }
       
   884 uint32_t
       
   885 MacLow::GetBlockAckSize (enum BlockAckType type) const
       
   886 {
       
   887   WifiMacHeader hdr;
       
   888   hdr.SetType (WIFI_MAC_CTL_BACKRESP);
       
   889   CtrlBAckResponseHeader blockAck;
       
   890   if (type == BASIC_BLOCK_ACK)
       
   891     {
       
   892       blockAck.SetType (BASIC_BLOCK_ACK);
       
   893     }
       
   894   else if (type == COMPRESSED_BLOCK_ACK)
       
   895     {
       
   896       blockAck.SetType (COMPRESSED_BLOCK_ACK);
       
   897     }
       
   898   else if (type == MULTI_TID_BLOCK_ACK)
       
   899     {
       
   900       //Not implemented
       
   901       NS_ASSERT (false);  
       
   902     }
       
   903   return hdr.GetSize () + blockAck.GetSerializedSize () + 4; 
       
   904 }
   712 uint32_t 
   905 uint32_t 
   713 MacLow::GetRtsSize (void) const
   906 MacLow::GetRtsSize (void) const
   714 {
   907 {
   715   WifiMacHeader rts;
   908   WifiMacHeader rts;
   716   rts.SetType (WIFI_MAC_CTL_RTS);
   909   rts.SetType (WIFI_MAC_CTL_RTS);
   719 Time
   912 Time
   720 MacLow::GetAckDuration (Mac48Address to, WifiMode dataTxMode) const
   913 MacLow::GetAckDuration (Mac48Address to, WifiMode dataTxMode) const
   721 {
   914 {
   722   WifiMode ackMode = GetAckTxModeForData (to, dataTxMode);
   915   WifiMode ackMode = GetAckTxModeForData (to, dataTxMode);
   723   return m_phy->CalculateTxDuration (GetAckSize (), ackMode, WIFI_PREAMBLE_LONG);
   916   return m_phy->CalculateTxDuration (GetAckSize (), ackMode, WIFI_PREAMBLE_LONG);
       
   917 }
       
   918 Time
       
   919 MacLow::GetBlockAckDuration (Mac48Address to, WifiMode blockAckReqTxMode, enum BlockAckType type) const
       
   920 {
       
   921   /* 
       
   922    * For immediate BlockAck we should transmit the frame with the same WifiMode
       
   923    * as the BlockAckReq.
       
   924    *
       
   925    * from section 9.6 in IEEE802.11e:
       
   926    * The BlockAck control frame shall be sent at the same rate and modulation class as
       
   927    * the BlockAckReq frame if it is sent in response to a BlockAckReq frame.
       
   928    */
       
   929   return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxMode, WIFI_PREAMBLE_LONG);
   724 }
   930 }
   725 Time
   931 Time
   726 MacLow::GetCtsDuration (Mac48Address to, WifiMode rtsTxMode) const
   932 MacLow::GetCtsDuration (Mac48Address to, WifiMode rtsTxMode) const
   727 {
   933 {
   728   WifiMode ctsMode = GetCtsTxModeForRts (to, rtsTxMode);
   934   WifiMode ctsMode = GetCtsTxModeForRts (to, rtsTxMode);
   975     {
  1181     {
   976       NS_LOG_DEBUG ("fast Ack ok");
  1182       NS_LOG_DEBUG ("fast Ack ok");
   977     }
  1183     }
   978 }
  1184 }
   979 void
  1185 void
       
  1186 MacLow::BlockAckTimeout (void)
       
  1187 {
       
  1188   NS_LOG_FUNCTION (this);
       
  1189   NS_LOG_DEBUG ("block ack timeout");
       
  1190   
       
  1191   m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
       
  1192   MacLowTransmissionListener *listener = m_listener;
       
  1193   m_listener = 0;
       
  1194   listener->MissedBlockAck ();
       
  1195 }
       
  1196 void
   980 MacLow::SuperFastAckTimeout ()
  1197 MacLow::SuperFastAckTimeout ()
   981 {
  1198 {
   982   NS_LOG_FUNCTION (this);
  1199   NS_LOG_FUNCTION (this);
   983   m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
  1200   m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
   984   MacLowTransmissionListener *listener = m_listener;
  1201   MacLowTransmissionListener *listener = m_listener;
  1066       Time timerDelay = txDuration + GetPifs ();
  1283       Time timerDelay = txDuration + GetPifs ();
  1067       NS_ASSERT (m_superFastAckTimeoutEvent.IsExpired ());
  1284       NS_ASSERT (m_superFastAckTimeoutEvent.IsExpired ());
  1068       NotifyAckTimeoutStartNow (timerDelay);
  1285       NotifyAckTimeoutStartNow (timerDelay);
  1069       m_superFastAckTimeoutEvent = Simulator::Schedule (timerDelay, 
  1286       m_superFastAckTimeoutEvent = Simulator::Schedule (timerDelay, 
  1070                                                         &MacLow::SuperFastAckTimeout, this);
  1287                                                         &MacLow::SuperFastAckTimeout, this);
  1071     } 
  1288     }
       
  1289   else if (m_txParams.MustWaitBasicBlockAck ())
       
  1290     {
       
  1291       Time timerDelay = txDuration + GetBasicBlockAckTimeout ();
       
  1292       NS_ASSERT (m_blockAckTimeoutEvent.IsExpired ());
       
  1293       m_blockAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::BlockAckTimeout, this);
       
  1294     }
       
  1295   else if (m_txParams.MustWaitCompressedBlockAck ())
       
  1296     {
       
  1297       Time timerDelay = txDuration + GetCompressedBlockAckTimeout ();
       
  1298       NS_ASSERT (m_blockAckTimeoutEvent.IsExpired ());
       
  1299       m_blockAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::BlockAckTimeout, this);
       
  1300     }
  1072   else if (m_txParams.HasNextPacket ()) 
  1301   else if (m_txParams.HasNextPacket ()) 
  1073     {
  1302     {
  1074       Time delay = txDuration + GetSifs ();
  1303       Time delay = txDuration + GetSifs ();
  1075       NS_ASSERT (m_waitSifsEvent.IsExpired ());
  1304       NS_ASSERT (m_waitSifsEvent.IsExpired ());
  1076       m_waitSifsEvent = Simulator::Schedule (delay, &MacLow::WaitSifsAfterEndTx, this);
  1305       m_waitSifsEvent = Simulator::Schedule (delay, &MacLow::WaitSifsAfterEndTx, this);
  1095     {
  1324     {
  1096       duration += m_txParams.GetDurationId ();
  1325       duration += m_txParams.GetDurationId ();
  1097     } 
  1326     } 
  1098   else 
  1327   else 
  1099     {
  1328     {
  1100       if (m_txParams.MustWaitAck ()) 
  1329       if (m_txParams.MustWaitBasicBlockAck ())
       
  1330         {
       
  1331           duration += GetSifs ();
       
  1332           duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxMode, BASIC_BLOCK_ACK);
       
  1333         }
       
  1334       else if (m_txParams.MustWaitCompressedBlockAck ())
       
  1335         {
       
  1336           duration += GetSifs ();
       
  1337           duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxMode, COMPRESSED_BLOCK_ACK);
       
  1338         }
       
  1339       else if (m_txParams.MustWaitAck ()) 
  1101         {
  1340         {
  1102           duration += GetSifs ();
  1341           duration += GetSifs ();
  1103           duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
  1342           duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
  1104         }
  1343         }
  1105       if (m_txParams.HasNextPacket ()) 
  1344       if (m_txParams.HasNextPacket ()) 
  1246   packet->AddPacketTag (tag);
  1485   packet->AddPacketTag (tag);
  1247 
  1486 
  1248   ForwardDown (packet, &ack, ackTxMode);
  1487   ForwardDown (packet, &ack, ackTxMode);
  1249 }
  1488 }
  1250 
  1489 
       
  1490 bool
       
  1491 MacLow::StoreMpduIfNeeded (Ptr<Packet> packet, WifiMacHeader hdr)
       
  1492 {
       
  1493   AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
       
  1494   if (it != m_bAckAgreements.end ())
       
  1495    {
       
  1496      WifiMacTrailer fcs;
       
  1497      packet->RemoveTrailer (fcs);
       
  1498      BufferedPacket bufferedPacket (packet, hdr);
       
  1499 
       
  1500      uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
       
  1501      uint16_t mappedSeqControl = QosUtilsMapSeqControlToUniqueInteger (hdr.GetSequenceControl () ,endSequence);
       
  1502 
       
  1503      BufferedPacketI i = (*it).second.second.begin ();
       
  1504      for (; i != (*it).second.second.end () &&
       
  1505             QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceControl (), endSequence) < mappedSeqControl; i++);
       
  1506      (*it).second.second.insert (i, bufferedPacket);
       
  1507      return true;
       
  1508    }
       
  1509   return false;
       
  1510 }
       
  1511 
       
  1512 void
       
  1513 MacLow::CreateBlockAckAgreement (const MgtAddBaResponseHeader *respHdr, Mac48Address originator,
       
  1514                                  uint16_t startingSeq)
       
  1515 {
       
  1516   uint8_t tid = respHdr->GetTid ();
       
  1517   BlockAckAgreement agreement (originator, tid);
       
  1518   if (respHdr->IsImmediateBlockAck ())
       
  1519     {
       
  1520       agreement.SetImmediateBlockAck ();
       
  1521     }
       
  1522   else
       
  1523     {
       
  1524       agreement.SetDelayedBlockAck ();
       
  1525     }
       
  1526   agreement.SetAmsduSupport (respHdr->IsAmsduSupported ());
       
  1527   agreement.SetBufferSize (respHdr->GetBufferSize ());
       
  1528   agreement.SetTimeout (respHdr->GetTimeout ());
       
  1529   agreement.SetStartingSequence (startingSeq);
       
  1530   
       
  1531   std::list<BufferedPacket> buffer (0);
       
  1532   AgreementKey key (originator, respHdr->GetTid ());
       
  1533   AgreementValue value (agreement, buffer);
       
  1534   m_bAckAgreements.insert (std::make_pair (key, value));
       
  1535   
       
  1536   if (respHdr->GetTimeout () != 0)
       
  1537     {
       
  1538       AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, respHdr->GetTid ()));
       
  1539       Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
       
  1540  
       
  1541       AccessClass ac = QosUtilsMapTidToAc (agreement.GetTid ());
       
  1542       
       
  1543       it->second.first.m_inactivityEvent = Simulator::Schedule (timeout,
       
  1544                                                                 &MacLowBlockAckEventListener::BlockAckInactivityTimeout,
       
  1545                                                                 m_edcaListeners[ac],
       
  1546                                                                 originator, tid);
       
  1547     }
       
  1548 }
       
  1549 
       
  1550 void
       
  1551 MacLow::DestroyBlockAckAgreement (Mac48Address originator, uint8_t tid)
       
  1552 {
       
  1553   AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
       
  1554   if (it != m_bAckAgreements.end ())
       
  1555     {
       
  1556       RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (), originator, tid);
       
  1557       RxCompleteBufferedPackets (originator, tid);
       
  1558       m_bAckAgreements.erase (it);
       
  1559     }
       
  1560 }
       
  1561 
       
  1562 void
       
  1563 MacLow::RxCompleteBufferedPacketsWithSmallerSequence (uint16_t seq, Mac48Address originator, uint8_t tid)
       
  1564 {
       
  1565   AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
       
  1566   if (it != m_bAckAgreements.end ())
       
  1567     {
       
  1568       BufferedPacketI i = (*it).second.second.begin ();
       
  1569       uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
       
  1570       uint16_t mappedStart = QosUtilsMapSeqControlToUniqueInteger (seq, endSequence);
       
  1571       uint16_t guard = (*it).second.first.GetStartingSequence ();
       
  1572       BufferedPacketI last = (*it).second.second.begin ();
       
  1573 
       
  1574       for (; i != (*it).second.second.end () &&
       
  1575              QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceNumber (), endSequence) < mappedStart;)
       
  1576         {
       
  1577           while (i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl ())
       
  1578             {
       
  1579               if (!(*i).second.IsMoreFragments ())
       
  1580                 {
       
  1581                   while (last != i)
       
  1582                     {
       
  1583                       m_rxCallback ((*last).first, &(*last).second);
       
  1584                       last++;
       
  1585                     }
       
  1586                   m_rxCallback ((*last).first, &(*last).second);
       
  1587                   last++;
       
  1588                 }
       
  1589               guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
       
  1590             }
       
  1591           /* go to next packet */
       
  1592           while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
       
  1593             {
       
  1594               i++;
       
  1595             }
       
  1596           if (i != (*it).second.second.end ())
       
  1597             {
       
  1598               guard = (*i).second.GetSequenceControl () & 0xfff0;
       
  1599               last = i;
       
  1600             }
       
  1601         }
       
  1602       (*it).second.second.erase ((*it).second.second.begin (), i);
       
  1603     }
       
  1604 }
       
  1605 
       
  1606 void
       
  1607 MacLow::RxCompleteBufferedPackets (Mac48Address originator, uint8_t tid)
       
  1608 {
       
  1609   AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
       
  1610   if (it != m_bAckAgreements.end ())
       
  1611     {
       
  1612       uint16_t startingSeqCtrl = ((*it).second.first.GetStartingSequence ()<<4) & 0xfff0;
       
  1613       uint16_t guard = startingSeqCtrl;
       
  1614 
       
  1615       BufferedPacketI lastComplete = (*it).second.second.begin ();
       
  1616       BufferedPacketI i = (*it).second.second.begin ();
       
  1617       for (;i != (*it).second.second.end() && guard == (*i).second.GetSequenceControl (); i++)
       
  1618         {
       
  1619           if (!(*i).second.IsMoreFragments ())
       
  1620             {
       
  1621               while (lastComplete != i)
       
  1622                 {
       
  1623                   m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
       
  1624                   lastComplete++;
       
  1625                 }
       
  1626                m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
       
  1627                lastComplete++;
       
  1628             }
       
  1629           guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
       
  1630         }
       
  1631       (*it).second.first.SetStartingSequence ((guard>>4)&0x0fff);
       
  1632       /* All packets already forwarded to WifiMac must be removed from buffer: 
       
  1633       [begin (), lastComplete) */
       
  1634       (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
       
  1635     }
       
  1636 }
       
  1637 
       
  1638 void
       
  1639 MacLow::SendBlockAckResponse (const CtrlBAckResponseHeader* blockAck, Mac48Address originator, bool immediate,
       
  1640                               Time duration, WifiMode blockAckReqTxMode)
       
  1641 {
       
  1642   Ptr<Packet> packet = Create<Packet> ();
       
  1643   packet->AddHeader (*blockAck);
       
  1644 
       
  1645   WifiMacHeader hdr;
       
  1646   hdr.SetType (WIFI_MAC_CTL_BACKRESP);
       
  1647   hdr.SetAddr1 (originator);
       
  1648   hdr.SetAddr2 (GetAddress ());
       
  1649   hdr.SetDsNotFrom ();
       
  1650   hdr.SetDsNotTo ();
       
  1651   hdr.SetNoRetry ();
       
  1652   hdr.SetNoMoreFragments ();
       
  1653 
       
  1654   m_currentPacket = packet;
       
  1655   m_currentHdr = hdr;
       
  1656   if (immediate)
       
  1657     {
       
  1658       m_txParams.DisableAck ();
       
  1659       duration -= GetSifs ();
       
  1660       if (blockAck->IsBasic ())
       
  1661         {
       
  1662           duration -= GetBlockAckDuration (originator, blockAckReqTxMode, BASIC_BLOCK_ACK);
       
  1663         }
       
  1664       else if (blockAck->IsCompressed ())
       
  1665         {
       
  1666           duration -= GetBlockAckDuration (originator, blockAckReqTxMode, COMPRESSED_BLOCK_ACK);
       
  1667         }
       
  1668       else if (blockAck->IsMultiTid ())
       
  1669         {
       
  1670           NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
       
  1671         }
       
  1672     }
       
  1673   else
       
  1674     {
       
  1675       m_txParams.EnableAck ();
       
  1676       duration += GetSifs ();
       
  1677       duration += GetAckDuration (originator, blockAckReqTxMode);
       
  1678     }
       
  1679   m_txParams.DisableNextData ();
       
  1680 
       
  1681   StartDataTxTimers ();
       
  1682 
       
  1683   NS_ASSERT (duration >= MicroSeconds (0));
       
  1684   hdr.SetDuration (duration);
       
  1685   //here should be present a control about immediate or delayed block ack
       
  1686   //for now we assume immediate
       
  1687   packet->AddHeader (hdr);
       
  1688   WifiMacTrailer fcs;
       
  1689   packet->AddTrailer (fcs);
       
  1690   ForwardDown (packet, &hdr, blockAckReqTxMode);
       
  1691   m_currentPacket = 0;
       
  1692 }
       
  1693 
       
  1694 void
       
  1695 MacLow::SendBlockAckAfterBlockAckRequest (const CtrlBAckRequestHeader reqHdr, Mac48Address originator,
       
  1696                                           Time duration, WifiMode blockAckReqTxMode)
       
  1697 {
       
  1698   NS_LOG_FUNCTION (this);
       
  1699   CtrlBAckResponseHeader blockAck;
       
  1700   uint8_t tid;
       
  1701   bool immediate = false;
       
  1702   if (!reqHdr.IsMultiTid ())
       
  1703     {
       
  1704       blockAck.SetStartingSequence (reqHdr.GetStartingSequence ());
       
  1705       blockAck.SetTidInfo (reqHdr.GetTidInfo ());
       
  1706       
       
  1707       tid = reqHdr.GetTidInfo ();
       
  1708       AgreementsI it;
       
  1709       it = m_bAckAgreements.find (std::make_pair (originator, tid));
       
  1710       if (it != m_bAckAgreements.end ())
       
  1711         {
       
  1712           immediate = (*it).second.first.IsImmediateBlockAck ();
       
  1713           uint16_t startingSeqCtrl = reqHdr.GetStartingSequenceControl ();
       
  1714 
       
  1715           /* All packets with smaller sequence than starting sequence control must be passed up to Wifimac 
       
  1716            * See 9.10.3 in IEEE8022.11e standard.
       
  1717            */
       
  1718           RxCompleteBufferedPacketsWithSmallerSequence ((startingSeqCtrl>>4)&0xfff0, originator, tid);
       
  1719 
       
  1720           std::list<BufferedPacket>::iterator i = (*it).second.second.begin ();
       
  1721 
       
  1722           /* For more details about next operations see section 9.10.4 of IEEE802.11e standard */
       
  1723           if (reqHdr.IsBasic ())
       
  1724             {
       
  1725               blockAck.SetType (BASIC_BLOCK_ACK);
       
  1726               uint16_t guard = startingSeqCtrl;
       
  1727               std::list<BufferedPacket>::iterator lastComplete = (*it).second.second.begin ();
       
  1728               for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
       
  1729                 {
       
  1730                   blockAck.SetReceivedFragment ((*i).second.GetSequenceNumber (),
       
  1731                                                 (*i).second.GetFragmentNumber ());
       
  1732                    /* Section 9.10.4 in IEEE802.11n: the recipient shall pass up to WifiMac the 
       
  1733                     * MSDUs and A-MSDUs starting with the starting sequence number 
       
  1734                     * sequentially until there is an incomplete MSDU or A-MSDU in the buffer */
       
  1735                   if (!(*i).second.IsMoreFragments ())
       
  1736                     {
       
  1737                       while (lastComplete != i)
       
  1738                         {
       
  1739                           m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
       
  1740                           lastComplete++;
       
  1741                         }
       
  1742                       m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
       
  1743                       lastComplete++;
       
  1744                     }
       
  1745                   guard = (*i).second.IsMoreFragments () ? (guard + 1) : (guard + 16) & 0xfff0;
       
  1746                 }
       
  1747               (*it).second.first.SetStartingSequence ((guard>>4)&0x0fff);
       
  1748               /* All packets already forwarded to WifiMac must be removed from buffer: 
       
  1749                  [begin (), lastComplete) */
       
  1750               (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
       
  1751               for (i = lastComplete; i != (*it).second.second.end (); i++)
       
  1752                 { 
       
  1753                   blockAck.SetReceivedFragment ((*i).second.GetSequenceNumber (),
       
  1754                                                 (*i).second.GetFragmentNumber ());  
       
  1755                 }
       
  1756             }
       
  1757           else if (reqHdr.IsCompressed ())
       
  1758             {
       
  1759               blockAck.SetType (COMPRESSED_BLOCK_ACK);
       
  1760               uint16_t guard = startingSeqCtrl;
       
  1761               std::list<BufferedPacket>::iterator lastComplete = (*it).second.second.begin ();
       
  1762               for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
       
  1763                 {
       
  1764                   if (!(*i).second.IsMoreFragments ())
       
  1765                     {
       
  1766                       blockAck.SetReceivedPacket ((*i).second.GetSequenceNumber ());
       
  1767                       while (lastComplete != i)
       
  1768                         {
       
  1769                           m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
       
  1770                           lastComplete++;
       
  1771                         }
       
  1772                       m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
       
  1773                       lastComplete++;
       
  1774                     }
       
  1775                   guard = (*i).second.IsMoreFragments () ? (guard + 1) : (guard + 16) & 0xfff0;
       
  1776                 }
       
  1777               (*it).second.first.SetStartingSequence ((guard>>4)&0x0fff);
       
  1778               /* All packets already forwarded to WifiMac must be removed from buffer:
       
  1779                  [begin (), lastcomplete) */
       
  1780               (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
       
  1781               i = lastComplete;
       
  1782               if (i != (*it).second.second.end ())
       
  1783                 {
       
  1784                   guard = (*i).second.GetSequenceControl () & 0xfff0;
       
  1785                 }
       
  1786               for (; i != (*it).second.second.end ();)
       
  1787                 {
       
  1788                   for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
       
  1789                     {
       
  1790                       if (!(*i).second.IsMoreFragments ())
       
  1791                         {
       
  1792                           guard = (guard + 16) & 0xfff0;
       
  1793                           blockAck.SetReceivedPacket ((*i).second.GetSequenceNumber ());
       
  1794                         }
       
  1795                       else
       
  1796                         {
       
  1797                           guard += 1;
       
  1798                         }
       
  1799                     }
       
  1800                   while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
       
  1801                     {
       
  1802                       i++;
       
  1803                     }
       
  1804                   if (i != (*it).second.second.end ())
       
  1805                     {
       
  1806                       guard = (*i).second.GetSequenceControl () & 0xfff0;
       
  1807                     }
       
  1808                 }
       
  1809             }
       
  1810         }
       
  1811       else
       
  1812         {
       
  1813           NS_LOG_DEBUG ("there's not a valid block ack agreement with "<<originator);
       
  1814         }
       
  1815     }
       
  1816   else
       
  1817     {
       
  1818       NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
       
  1819     }
       
  1820 
       
  1821   SendBlockAckResponse (&blockAck, originator, immediate, duration, blockAckReqTxMode);
       
  1822 }
       
  1823 
       
  1824 void
       
  1825 MacLow::ResetBlockAckInactivityTimerIfNeeded (BlockAckAgreement &agreement)
       
  1826 {
       
  1827   if (agreement.GetTimeout () != 0)
       
  1828     {
       
  1829       NS_ASSERT (agreement.m_inactivityEvent.IsRunning ());
       
  1830       agreement.m_inactivityEvent.Cancel ();
       
  1831       Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
       
  1832 
       
  1833       AccessClass ac = QosUtilsMapTidToAc (agreement.GetTid ());
       
  1834       //std::map<AccessClass, MacLowTransmissionListener*>::iterator it = m_edcaListeners.find (ac);
       
  1835       //NS_ASSERT (it != m_edcaListeners.end ());
       
  1836 
       
  1837       agreement.m_inactivityEvent = Simulator::Schedule (timeout, 
       
  1838                                                          &MacLowBlockAckEventListener::BlockAckInactivityTimeout, 
       
  1839                                                          m_edcaListeners[ac],
       
  1840                                                          agreement.GetPeer (),
       
  1841                                                          agreement.GetTid ());
       
  1842     }
       
  1843 }
       
  1844 
       
  1845 void
       
  1846 MacLow::RegisterBlockAckListenerForAc (enum AccessClass ac, MacLowBlockAckEventListener *listener)
       
  1847 {
       
  1848   m_edcaListeners.insert (std::make_pair (ac, listener));
       
  1849 }
       
  1850 
  1251 } // namespace ns3
  1851 } // namespace ns3