src/wifi/model/mac-low.cc
changeset 10139 17a71cd49da3
parent 9894 ac4e52a91d5d
child 10201 8bdf35df4bf1
--- a/src/wifi/model/mac-low.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/mac-low.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -331,6 +331,7 @@
   m_sendDataEvent.Cancel ();
   m_waitSifsEvent.Cancel ();
   m_endTxNoAckEvent.Cancel ();
+   m_waitRifsEvent.Cancel();
   m_phy = 0;
   m_stationManager = 0;
   delete m_phyMacLowListener;
@@ -392,6 +393,11 @@
       m_waitSifsEvent.Cancel ();
       oneRunning = true;
     }
+  if (m_waitRifsEvent.IsRunning ())
+    {
+      m_waitRifsEvent.Cancel ();
+      oneRunning = true;
+    }
   if (m_endTxNoAckEvent.IsRunning ()) 
     {
       m_endTxNoAckEvent.Cancel ();
@@ -439,6 +445,16 @@
   m_compressedBlockAckTimeout = blockAckTimeout;
 }
 void
+MacLow::SetCtsToSelfSupported (bool enable)
+{
+  m_ctsToSelfSupported = enable;
+}
+bool
+MacLow::GetCtsToSelfSupported () const
+{
+  return m_ctsToSelfSupported;
+}
+void
 MacLow::SetCtsTimeout (Time ctsTimeout)
 {
   m_ctsTimeout = ctsTimeout;
@@ -459,6 +475,11 @@
   m_pifs = pifs;
 }
 void
+MacLow::SetRifs (Time rifs)
+{
+  m_rifs = rifs;
+}
+void
 MacLow::SetBssid (Mac48Address bssid)
 {
   m_bssid = bssid;
@@ -499,6 +520,11 @@
   return m_sifs;
 }
 Time
+MacLow::GetRifs (void) const
+{
+  return m_rifs;
+}
+Time
 MacLow::GetSlotTime (void) const
 {
   return m_slotTime;
@@ -564,13 +590,25 @@
     }
   else
     {
-      SendDataPacket ();
+     if (NeedCtsToSelf() && m_ctsToSelfSupported)
+        {
+          SendCtsToSelf();
+        }
+      else
+        {
+          SendDataPacket ();
+       }
     }
 
   /* When this method completes, we have taken ownership of the medium. */
   NS_ASSERT (m_phy->IsStateTx ());
 }
-
+bool
+MacLow::NeedCtsToSelf (void)
+{
+  WifiTxVector dataTxVector = GetDataTxVector (m_currentPacket, &m_currentHdr);
+  return m_stationManager->NeedCtsToSelf (dataTxVector);
+}
 void
 MacLow::ReceiveError (Ptr<const Packet> packet, double rxSnr)
 {
@@ -615,7 +653,7 @@
 
   bool isPrevNavZero = IsNavZero ();
   NS_LOG_DEBUG ("duration/id=" << hdr.GetDuration ());
-  NotifyNav (hdr, txMode, preamble);
+  NotifyNav (packet,hdr, txMode, preamble);
   if (hdr.IsRts ())
     {
       /* see section 9.2.5.7 802.11-1999
@@ -895,13 +933,23 @@
   return rts.GetSize () + 4;
 }
 Time
-MacLow::GetAckDuration (Mac48Address to, WifiMode dataTxMode) const
+MacLow::GetAckDuration (Mac48Address to, WifiTxVector dataTxVector) const
 {
-  WifiMode ackMode = GetAckTxModeForData (to, dataTxMode);
-  return m_phy->CalculateTxDuration (GetAckSize (), ackMode, WIFI_PREAMBLE_LONG);
+  WifiTxVector ackTxVector = GetAckTxVectorForData (to, dataTxVector.GetMode());
+  return GetAckDuration (ackTxVector);
 }
 Time
-MacLow::GetBlockAckDuration (Mac48Address to, WifiMode blockAckReqTxMode, enum BlockAckType type) const
+MacLow::GetAckDuration (WifiTxVector ackTxVector) const
+{
+  WifiPreamble preamble;
+  if (ackTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
+    preamble= WIFI_PREAMBLE_HT_MF;
+  else
+    preamble=WIFI_PREAMBLE_LONG;
+  return m_phy->CalculateTxDuration (GetAckSize (), ackTxVector, preamble);
+}
+Time
+MacLow::GetBlockAckDuration (Mac48Address to, WifiTxVector blockAckReqTxVector, enum BlockAckType type) const
 {
   /*
    * For immediate BlockAck we should transmit the frame with the same WifiMode
@@ -911,13 +959,29 @@
    * The BlockAck control frame shall be sent at the same rate and modulation class as
    * the BlockAckReq frame if it is sent in response to a BlockAckReq frame.
    */
-  return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxMode, WIFI_PREAMBLE_LONG);
+  WifiPreamble preamble;
+  if (blockAckReqTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
+    preamble= WIFI_PREAMBLE_HT_MF;
+  else
+    preamble=WIFI_PREAMBLE_LONG;
+  return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxVector, preamble);
 }
 Time
-MacLow::GetCtsDuration (Mac48Address to, WifiMode rtsTxMode) const
+MacLow::GetCtsDuration (Mac48Address to, WifiTxVector rtsTxVector) const
 {
-  WifiMode ctsMode = GetCtsTxModeForRts (to, rtsTxMode);
-  return m_phy->CalculateTxDuration (GetCtsSize (), ctsMode, WIFI_PREAMBLE_LONG);
+  WifiTxVector ctsTxVector = GetCtsTxVectorForRts (to, rtsTxVector.GetMode());
+  return GetCtsDuration (ctsTxVector);
+}
+
+Time
+MacLow::GetCtsDuration (WifiTxVector ctsTxVector) const
+{
+  WifiPreamble preamble;
+  if (ctsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
+    preamble= WIFI_PREAMBLE_HT_MF;
+  else
+    preamble=WIFI_PREAMBLE_LONG;
+  return m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble);
 }
 uint32_t
 MacLow::GetCtsSize (void) const
@@ -933,30 +997,52 @@
   return packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
 }
 
-WifiMode
-MacLow::GetRtsTxMode (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
+WifiTxVector
+MacLow::GetCtsToSelfTxVector (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
+{
+  return m_stationManager->GetCtsToSelfTxVector (hdr, packet);
+}
+
+WifiTxVector
+MacLow::GetRtsTxVector (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
 {
   Mac48Address to = hdr->GetAddr1 ();
-  return m_stationManager->GetRtsMode (to, hdr, packet);
+  return m_stationManager->GetRtsTxVector (to, hdr, packet);
 }
-WifiMode
-MacLow::GetDataTxMode (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
+WifiTxVector
+MacLow::GetDataTxVector (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
 {
   Mac48Address to = hdr->GetAddr1 ();
   WifiMacTrailer fcs;
-  uint32_t size =  packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
-  return m_stationManager->GetDataMode (to, hdr, packet, size);
+  uint32_t size =  packet->GetSize ()+ hdr->GetSize () + fcs.GetSerializedSize ();
+  //size is not used in anything!! will not worry about aggregation
+  return m_stationManager->GetDataTxVector (to, hdr, packet, size);
+}
+WifiTxVector
+MacLow::GetCtsTxVector (Mac48Address to, WifiMode rtsTxMode) const
+{
+  return m_stationManager->GetCtsTxVector (to, rtsTxMode);
+}
+WifiTxVector
+MacLow::GetAckTxVector (Mac48Address to, WifiMode dataTxMode) const
+{
+  return m_stationManager->GetAckTxVector (to, dataTxMode);
+}
+WifiTxVector
+MacLow::GetBlockAckTxVector (Mac48Address to, WifiMode dataTxMode) const
+{
+  return m_stationManager->GetBlockAckTxVector (to, dataTxMode);
 }
 
-WifiMode
-MacLow::GetCtsTxModeForRts (Mac48Address to, WifiMode rtsTxMode) const
+WifiTxVector
+MacLow::GetCtsTxVectorForRts (Mac48Address to, WifiMode rtsTxMode) const
 {
-  return m_stationManager->GetCtsMode (to, rtsTxMode);
+  return GetCtsTxVector (to, rtsTxMode);
 }
-WifiMode
-MacLow::GetAckTxModeForData (Mac48Address to, WifiMode dataTxMode) const
+WifiTxVector
+MacLow::GetAckTxVectorForData (Mac48Address to, WifiMode dataTxMode) const
 {
-  return m_stationManager->GetAckMode (to, dataTxMode);
+  return GetAckTxVector (to, dataTxMode);
 }
 
 
@@ -965,21 +1051,36 @@
                                 const WifiMacHeader* hdr,
                                 const MacLowTransmissionParameters& params) const
 {
+  WifiPreamble preamble;
   Time txTime = Seconds (0);
-  WifiMode rtsMode = GetRtsTxMode (packet, hdr);
-  WifiMode dataMode = GetDataTxMode (packet, hdr);
+  WifiTxVector rtsTxVector = GetRtsTxVector (packet, hdr);
+  WifiTxVector dataTxVector = GetDataTxVector (packet, hdr);
+   //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
+  if ( m_phy->GetGreenfield()&& m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
+    preamble= WIFI_PREAMBLE_HT_GF;
+  else if (rtsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
+    preamble= WIFI_PREAMBLE_HT_MF;
+  else
+    preamble=WIFI_PREAMBLE_LONG;
   if (params.MustSendRts ())
     {
-      txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsMode, WIFI_PREAMBLE_LONG);
-      txTime += GetCtsDuration (hdr->GetAddr1 (), rtsMode);
+      txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble);
+      txTime += GetCtsDuration (hdr->GetAddr1 (), rtsTxVector);
       txTime += Time (GetSifs () * 2);
     }
+  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
+  if ( m_phy->GetGreenfield()&& m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
+    preamble= WIFI_PREAMBLE_HT_GF;
+  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
+    preamble= WIFI_PREAMBLE_HT_MF;
+  else
+    preamble=WIFI_PREAMBLE_LONG;
   uint32_t dataSize = GetSize (packet, hdr);
-  txTime += m_phy->CalculateTxDuration (dataSize, dataMode, WIFI_PREAMBLE_LONG);
+  txTime += m_phy->CalculateTxDuration (dataSize, dataTxVector, preamble);
   if (params.MustWaitAck ())
     {
       txTime += GetSifs ();
-      txTime += GetAckDuration (hdr->GetAddr1 (), dataMode);
+      txTime += GetAckDuration (hdr->GetAddr1 (), dataTxVector);
     }
   return txTime;
 }
@@ -992,15 +1093,23 @@
   Time txTime = CalculateOverallTxTime (packet, hdr, params);
   if (params.HasNextPacket ())
     {
-      WifiMode dataMode = GetDataTxMode (packet, hdr);
+      WifiTxVector dataTxVector = GetDataTxVector (packet, hdr);
+      WifiPreamble preamble;
+        //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
+      if ( m_phy->GetGreenfield()&& m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
+         preamble= WIFI_PREAMBLE_HT_GF;
+      else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
+        preamble= WIFI_PREAMBLE_HT_MF;
+      else
+        preamble=WIFI_PREAMBLE_LONG;
       txTime += GetSifs ();
-      txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataMode, WIFI_PREAMBLE_LONG);
+      txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataTxVector, preamble);
     }
   return txTime;
 }
 
 void
-MacLow::NotifyNav (const WifiMacHeader &hdr, WifiMode txMode, WifiPreamble preamble)
+MacLow::NotifyNav (Ptr<const Packet> packet,const WifiMacHeader &hdr, WifiMode txMode, WifiPreamble preamble)
 {
   NS_ASSERT (m_lastNavStart <= Simulator::Now ());
   Time duration = hdr.GetDuration ();
@@ -1030,8 +1139,9 @@
            */
           WifiMacHeader cts;
           cts.SetType (WIFI_MAC_CTL_CTS);
+          WifiTxVector txVector=GetRtsTxVector (packet, &hdr);
           Time navCounterResetCtsMissedDelay =
-            m_phy->CalculateTxDuration (cts.GetSerializedSize (), txMode, preamble) +
+            m_phy->CalculateTxDuration (cts.GetSerializedSize (), txVector, preamble) +
             Time (2 * GetSifs ()) + Time (2 * GetSlotTime ());
           m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay,
                                                             &MacLow::NavCounterResetCtsMissed, this,
@@ -1111,16 +1221,16 @@
 
 void
 MacLow::ForwardDown (Ptr<const Packet> packet, const WifiMacHeader* hdr,
-                     WifiMode txMode)
+                     WifiTxVector txVector, WifiPreamble preamble)
 {
-  NS_LOG_FUNCTION (this << packet << hdr << txMode);
+  NS_LOG_FUNCTION (this << packet << hdr << txVector);
   NS_LOG_DEBUG ("send " << hdr->GetTypeString () <<
                 ", to=" << hdr->GetAddr1 () <<
                 ", size=" << packet->GetSize () <<
-                ", mode=" << txMode <<
+                ", mode=" << txVector.GetMode() <<
                 ", duration=" << hdr->GetDuration () <<
                 ", seq=0x" << std::hex << m_currentHdr.GetSequenceControl () << std::dec);
-  m_phy->SendPacket (packet, txMode, WIFI_PREAMBLE_LONG, 0);
+  m_phy->SendPacket (packet, txVector.GetMode(), preamble, txVector);
 }
 
 void
@@ -1210,26 +1320,36 @@
   rts.SetNoMoreFragments ();
   rts.SetAddr1 (m_currentHdr.GetAddr1 ());
   rts.SetAddr2 (m_self);
-  WifiMode rtsTxMode = GetRtsTxMode (m_currentPacket, &m_currentHdr);
+  WifiTxVector rtsTxVector = GetRtsTxVector (m_currentPacket, &m_currentHdr);
   Time duration = Seconds (0);
+
+  WifiPreamble preamble;
+  //standard says RTS packets can have GF format sec 9.6.0e.1 page 110 bullet b 2
+  if ( m_phy->GetGreenfield()&& m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
+    preamble= WIFI_PREAMBLE_HT_GF;
+  else if (rtsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
+    preamble= WIFI_PREAMBLE_HT_MF;
+  else
+    preamble=WIFI_PREAMBLE_LONG;
+
   if (m_txParams.HasDurationId ())
     {
       duration += m_txParams.GetDurationId ();
     }
   else
     {
-      WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
+      WifiTxVector dataTxVector = GetDataTxVector (m_currentPacket, &m_currentHdr);
       duration += GetSifs ();
-      duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxMode);
+      duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxVector);
       duration += GetSifs ();
       duration += m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr),
-                                              dataTxMode, WIFI_PREAMBLE_LONG);
+                                              dataTxVector, preamble);
       duration += GetSifs ();
-      duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
+      duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
     }
   rts.SetDuration (duration);
 
-  Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxMode, WIFI_PREAMBLE_LONG);
+  Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble);
   Time timerDelay = txDuration + GetCtsTimeout ();
 
   NS_ASSERT (m_ctsTimeoutEvent.IsExpired ());
@@ -1241,14 +1361,23 @@
   WifiMacTrailer fcs;
   packet->AddTrailer (fcs);
 
-  ForwardDown (packet, &rts, rtsTxMode);
+  ForwardDown (packet, &rts, rtsTxVector,preamble);
 }
 
 void
-MacLow::StartDataTxTimers (void)
+MacLow::StartDataTxTimers (WifiTxVector dataTxVector)
 {
-  WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
-  Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxMode, WIFI_PREAMBLE_LONG);
+  WifiPreamble preamble;
+ 
+  //Since it is data then it can have format = GF
+  if (m_phy->GetGreenfield() && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
+    preamble= WIFI_PREAMBLE_HT_GF;
+  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
+    preamble= WIFI_PREAMBLE_HT_MF;
+  else
+    preamble=WIFI_PREAMBLE_LONG;
+ 
+  Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxVector, preamble);
   if (m_txParams.MustWaitNormalAck ())
     {
       Time timerDelay = txDuration + GetAckTimeout ();
@@ -1285,9 +1414,18 @@
     }
   else if (m_txParams.HasNextPacket ())
     {
-      Time delay = txDuration + GetSifs ();
-      NS_ASSERT (m_waitSifsEvent.IsExpired ());
-      m_waitSifsEvent = Simulator::Schedule (delay, &MacLow::WaitSifsAfterEndTx, this);
+     if (m_stationManager->HasHtSupported())
+       {
+          Time delay = txDuration + GetRifs ();
+          NS_ASSERT (m_waitRifsEvent.IsExpired ());
+          m_waitRifsEvent = Simulator::Schedule (delay, &MacLow::WaitSifsAfterEndTx, this); 
+       }
+     else
+       {
+          Time delay = txDuration + GetSifs ();
+          NS_ASSERT (m_waitSifsEvent.IsExpired ());
+          m_waitSifsEvent = Simulator::Schedule (delay, &MacLow::WaitSifsAfterEndTx, this);
+       }
     }
   else
     {
@@ -1301,9 +1439,19 @@
 {
   NS_LOG_FUNCTION (this);
   /* send this packet directly. No RTS is needed. */
-  StartDataTxTimers ();
+  WifiTxVector dataTxVector = GetDataTxVector (m_currentPacket, &m_currentHdr);
+  WifiPreamble preamble;
+          
+  if (m_phy->GetGreenfield() && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
+     //In the future has to make sure that receiver has greenfield enabled
+     preamble= WIFI_PREAMBLE_HT_GF;
+  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
+    preamble= WIFI_PREAMBLE_HT_MF;
+  else
+     preamble=WIFI_PREAMBLE_LONG;
+  
+  StartDataTxTimers (dataTxVector);
 
-  WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
   Time duration = Seconds (0.0);
   if (m_txParams.HasDurationId ())
     {
@@ -1314,27 +1462,27 @@
       if (m_txParams.MustWaitBasicBlockAck ())
         {
           duration += GetSifs ();
-          duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxMode, BASIC_BLOCK_ACK);
+          duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, BASIC_BLOCK_ACK);
         }
       else if (m_txParams.MustWaitCompressedBlockAck ())
         {
           duration += GetSifs ();
-          duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxMode, COMPRESSED_BLOCK_ACK);
+          duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, COMPRESSED_BLOCK_ACK);
         }
       else if (m_txParams.MustWaitAck ())
         {
           duration += GetSifs ();
-          duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
+          duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
         }
       if (m_txParams.HasNextPacket ())
         {
           duration += GetSifs ();
           duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (),
-                                                  dataTxMode, WIFI_PREAMBLE_LONG);
+                                                  dataTxVector, preamble);
           if (m_txParams.MustWaitAck ())
             {
               duration += GetSifs ();
-              duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
+              duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
             }
         }
     }
@@ -1344,7 +1492,7 @@
   WifiMacTrailer fcs;
   m_currentPacket->AddTrailer (fcs);
 
-  ForwardDown (m_currentPacket, &m_currentHdr, dataTxMode);
+  ForwardDown (m_currentPacket, &m_currentHdr, dataTxVector,preamble);
   m_currentPacket = 0;
 }
 
@@ -1360,7 +1508,90 @@
       return false;
     }
 }
+void
+MacLow::SendCtsToSelf (void)
+{
+  WifiMacHeader cts;
+  cts.SetType (WIFI_MAC_CTL_CTS);
+  cts.SetDsNotFrom ();
+  cts.SetDsNotTo ();
+  cts.SetNoMoreFragments ();
+  cts.SetNoRetry ();
+  cts.SetAddr1 (m_self);
+ 
+  WifiTxVector ctsTxVector = GetCtsToSelfTxVector (m_currentPacket, &m_currentHdr);
 
+  WifiPreamble preamble;
+  if (ctsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
+    preamble= WIFI_PREAMBLE_HT_MF;
+  else
+    preamble=WIFI_PREAMBLE_LONG;
+  
+  Time duration = Seconds (0);
+
+  if (m_txParams.HasDurationId ())
+    {
+      duration += m_txParams.GetDurationId ();
+    }
+  else
+    {
+      WifiTxVector dataTxVector = GetDataTxVector (m_currentPacket, &m_currentHdr);
+      duration += GetSifs ();
+      duration += m_phy->CalculateTxDuration (GetSize (m_currentPacket,&m_currentHdr),
+                                              dataTxVector, preamble);
+      if (m_txParams.MustWaitBasicBlockAck ())
+        {
+          
+          duration += GetSifs ();
+          duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, BASIC_BLOCK_ACK);
+        }
+      else if (m_txParams.MustWaitCompressedBlockAck ())
+        {
+          duration += GetSifs ();
+          duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, COMPRESSED_BLOCK_ACK);
+        }
+      else if (m_txParams.MustWaitAck ())
+        {
+          duration += GetSifs ();
+          duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
+        }
+      if (m_txParams.HasNextPacket ())
+        {
+          duration += GetSifs ();
+          duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (),
+                                                  dataTxVector, preamble);
+          if (m_txParams.MustWaitCompressedBlockAck ())
+            {
+              duration += GetSifs ();
+              duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, COMPRESSED_BLOCK_ACK);
+            }
+          else if (m_txParams.MustWaitAck ())
+            {
+              duration += GetSifs ();
+              duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
+            }
+        }
+    }
+
+  cts.SetDuration (duration);
+
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->AddHeader (cts);
+  WifiMacTrailer fcs;
+  packet->AddTrailer (fcs);
+
+  ForwardDown (packet, &cts, ctsTxVector,preamble);
+
+  Time txDuration = m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble);
+  txDuration += GetSifs ();
+  NS_ASSERT (m_sendDataEvent.IsExpired ());
+  
+  m_sendDataEvent = Simulator::Schedule (txDuration,
+                                         &MacLow::SendDataAfterCts, this,
+                                         cts.GetAddr1 (),
+                                         duration,
+                                         ctsTxVector.GetMode());
+}
 void
 MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode rtsTxMode, double rtsSnr)
 {
@@ -1368,7 +1599,7 @@
   /* send a CTS when you receive a RTS
    * right after SIFS.
    */
-  WifiMode ctsTxMode = GetCtsTxModeForRts (source, rtsTxMode);
+ WifiTxVector ctsTxVector = GetCtsTxVector (source, rtsTxMode);
   WifiMacHeader cts;
   cts.SetType (WIFI_MAC_CTL_CTS);
   cts.SetDsNotFrom ();
@@ -1376,7 +1607,7 @@
   cts.SetNoMoreFragments ();
   cts.SetNoRetry ();
   cts.SetAddr1 (source);
-  duration -= GetCtsDuration (source, rtsTxMode);
+  duration -= GetCtsDuration (source, ctsTxVector);
   duration -= GetSifs ();
   NS_ASSERT (duration >= MicroSeconds (0));
   cts.SetDuration (duration);
@@ -1390,7 +1621,12 @@
   tag.Set (rtsSnr);
   packet->AddPacketTag (tag);
 
-  ForwardDown (packet, &cts, ctsTxMode);
+  WifiPreamble preamble;
+  if (ctsTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
+    preamble= WIFI_PREAMBLE_HT_MF;
+  else
+    preamble=WIFI_PREAMBLE_LONG;
+  ForwardDown (packet, &cts, ctsTxVector,preamble);
 }
 
 void
@@ -1401,14 +1637,23 @@
    * RTS/CTS/DATA/ACK hanshake
    */
   NS_ASSERT (m_currentPacket != 0);
-  StartDataTxTimers ();
-
-  WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
+  WifiTxVector dataTxVector = GetDataTxVector (m_currentPacket, &m_currentHdr);
+  
+  WifiPreamble preamble;       
+  if (m_phy->GetGreenfield() && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
+     //In the future has to make sure that receiver has greenfield enabled
+     preamble= WIFI_PREAMBLE_HT_GF;
+  else if (dataTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
+    preamble= WIFI_PREAMBLE_HT_MF;
+  else
+     preamble=WIFI_PREAMBLE_LONG;
+  
+  StartDataTxTimers (dataTxVector);
   Time newDuration = Seconds (0);
   newDuration += GetSifs ();
-  newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
+  newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
   Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr),
-                                                dataTxMode, WIFI_PREAMBLE_LONG);
+                                                dataTxVector, preamble);
   duration -= txDuration;
   duration -= GetSifs ();
 
@@ -1420,7 +1665,7 @@
   WifiMacTrailer fcs;
   m_currentPacket->AddTrailer (fcs);
 
-  ForwardDown (m_currentPacket, &m_currentHdr, dataTxMode);
+  ForwardDown (m_currentPacket, &m_currentHdr, dataTxVector,preamble);
   m_currentPacket = 0;
 }
 
@@ -1455,7 +1700,7 @@
   /* send an ACK when you receive
    * a packet after SIFS.
    */
-  WifiMode ackTxMode = GetAckTxModeForData (source, dataTxMode);
+  WifiTxVector ackTxVector = GetAckTxVector (source, dataTxMode);
   WifiMacHeader ack;
   ack.SetType (WIFI_MAC_CTL_ACK);
   ack.SetDsNotFrom ();
@@ -1463,7 +1708,7 @@
   ack.SetNoRetry ();
   ack.SetNoMoreFragments ();
   ack.SetAddr1 (source);
-  duration -= GetAckDuration (source, dataTxMode);
+  duration -= GetAckDuration (ackTxVector);
   duration -= GetSifs ();
   NS_ASSERT (duration >= MicroSeconds (0));
   ack.SetDuration (duration);
@@ -1477,7 +1722,13 @@
   tag.Set (dataSnr);
   packet->AddPacketTag (tag);
 
-  ForwardDown (packet, &ack, ackTxMode);
+   //since ACK is a control response it can't have Fomat =GF
+  WifiPreamble preamble;
+  if (ackTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
+    preamble= WIFI_PREAMBLE_HT_MF;
+  else
+    preamble=WIFI_PREAMBLE_LONG;
+  ForwardDown (packet, &ack, ackTxVector, preamble);
 }
 
 bool
@@ -1677,6 +1928,12 @@
   hdr.SetNoRetry ();
   hdr.SetNoMoreFragments ();
 
+  WifiTxVector blockAckTxVector = GetBlockAckTxVector (originator, blockAckReqTxMode);
+  WifiTxVector blockAckReqTxVector;
+  blockAckReqTxVector.SetMode(blockAckReqTxMode);
+  blockAckReqTxVector.SetNss(1);
+  blockAckReqTxVector.SetStbc(false);
+
   m_currentPacket = packet;
   m_currentHdr = hdr;
   if (immediate)
@@ -1685,11 +1942,11 @@
       duration -= GetSifs ();
       if (blockAck->IsBasic ())
         {
-          duration -= GetBlockAckDuration (originator, blockAckReqTxMode, BASIC_BLOCK_ACK);
+          duration -= GetBlockAckDuration (originator, blockAckReqTxVector, BASIC_BLOCK_ACK);
         }
       else if (blockAck->IsCompressed ())
         {
-          duration -= GetBlockAckDuration (originator, blockAckReqTxMode, COMPRESSED_BLOCK_ACK);
+          duration -= GetBlockAckDuration (originator, blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
         }
       else if (blockAck->IsMultiTid ())
         {
@@ -1700,13 +1957,13 @@
     {
       m_txParams.EnableAck ();
       duration += GetSifs ();
-      duration += GetAckDuration (originator, blockAckReqTxMode);
+      duration += GetAckDuration (originator, blockAckReqTxVector);
     }
   m_txParams.DisableNextData ();
 
   if (!immediate)
     {
-      StartDataTxTimers ();
+      StartDataTxTimers (blockAckTxVector);
     }
 
   NS_ASSERT (duration >= MicroSeconds (0));
@@ -1716,7 +1973,12 @@
   packet->AddHeader (hdr);
   WifiMacTrailer fcs;
   packet->AddTrailer (fcs);
-  ForwardDown (packet, &hdr, blockAckReqTxMode);
+   WifiPreamble preamble;
+  if (blockAckTxVector.GetMode().GetModulationClass () == WIFI_MOD_CLASS_HT)
+    preamble= WIFI_PREAMBLE_HT_MF;
+  else
+    preamble=WIFI_PREAMBLE_LONG;
+  ForwardDown (packet, &hdr, blockAckTxVector,preamble);
   m_currentPacket = 0;
 }