partial 802.11n support
authorGhada Badawy <gbadawy@gmail.com>
Tue, 13 Aug 2013 22:05:25 -0700
changeset 10139 17a71cd49da3
parent 10138 2f8e35b43d11
child 10140 7e83801e8734
partial 802.11n support
AUTHORS
CHANGES.html
RELEASE_NOTES
examples/wireless/ht-wifi-network.cc
examples/wireless/wscript
src/mesh/model/dot11s/airtime-metric.cc
src/test/ns3wifi/wifi-interference-test-suite.cc
src/wifi/doc/wifi.rst
src/wifi/examples/wifi-phy-test.cc
src/wifi/helper/ht-wifi-mac-helper.cc
src/wifi/helper/ht-wifi-mac-helper.h
src/wifi/helper/yans-wifi-helper.cc
src/wifi/model/aarf-wifi-manager.cc
src/wifi/model/aarf-wifi-manager.h
src/wifi/model/aarfcd-wifi-manager.cc
src/wifi/model/aarfcd-wifi-manager.h
src/wifi/model/amrr-wifi-manager.cc
src/wifi/model/amrr-wifi-manager.h
src/wifi/model/ap-wifi-mac.cc
src/wifi/model/ap-wifi-mac.h
src/wifi/model/arf-wifi-manager.cc
src/wifi/model/arf-wifi-manager.h
src/wifi/model/cara-wifi-manager.cc
src/wifi/model/cara-wifi-manager.h
src/wifi/model/constant-rate-wifi-manager.cc
src/wifi/model/constant-rate-wifi-manager.h
src/wifi/model/edca-txop-n.h
src/wifi/model/ht-capabilities.cc
src/wifi/model/ht-capabilities.h
src/wifi/model/ideal-wifi-manager.cc
src/wifi/model/ideal-wifi-manager.h
src/wifi/model/interference-helper.cc
src/wifi/model/interference-helper.h
src/wifi/model/mac-low.cc
src/wifi/model/mac-low.h
src/wifi/model/mgt-headers.cc
src/wifi/model/mgt-headers.h
src/wifi/model/minstrel-wifi-manager.cc
src/wifi/model/minstrel-wifi-manager.h
src/wifi/model/nist-error-rate-model.cc
src/wifi/model/onoe-wifi-manager.cc
src/wifi/model/onoe-wifi-manager.h
src/wifi/model/regular-wifi-mac.cc
src/wifi/model/regular-wifi-mac.h
src/wifi/model/rraa-wifi-manager.cc
src/wifi/model/rraa-wifi-manager.h
src/wifi/model/sta-wifi-mac.cc
src/wifi/model/sta-wifi-mac.h
src/wifi/model/supported-rates.h
src/wifi/model/wifi-information-element.h
src/wifi/model/wifi-mac-header.cc
src/wifi/model/wifi-mac-header.h
src/wifi/model/wifi-mac.cc
src/wifi/model/wifi-mac.h
src/wifi/model/wifi-mode.cc
src/wifi/model/wifi-mode.h
src/wifi/model/wifi-phy-standard.h
src/wifi/model/wifi-phy.cc
src/wifi/model/wifi-phy.h
src/wifi/model/wifi-preamble.h
src/wifi/model/wifi-remote-station-manager.cc
src/wifi/model/wifi-remote-station-manager.h
src/wifi/model/wifi-tx-vector.cc
src/wifi/model/wifi-tx-vector.h
src/wifi/model/yans-wifi-channel.cc
src/wifi/model/yans-wifi-channel.h
src/wifi/model/yans-wifi-phy.cc
src/wifi/model/yans-wifi-phy.h
src/wifi/test/tx-duration-test.cc
src/wifi/test/wifi-test.cc
src/wifi/wscript
--- a/AUTHORS	Tue Aug 13 10:37:49 2013 -0700
+++ b/AUTHORS	Tue Aug 13 22:05:25 2013 -0700
@@ -2,6 +2,7 @@
 Rohit Agarwal (mindprince@gmail.com)
 Kirill Andreev (andreev@iitp.ru)
 Dean Armstrong (deanarm@gmail.com)
+Ghada Badawy (gbadawy@gmail.com)
 Nicola Baldo (nbaldo@cttc.es)
 Mirko Banchi (mk.banchi@gmail.com)
 Peter D. Barnes, Jr. (barnes26@llnl.gov)
--- a/CHANGES.html	Tue Aug 13 10:37:49 2013 -0700
+++ b/CHANGES.html	Tue Aug 13 22:05:25 2013 -0700
@@ -116,6 +116,28 @@
 </ul>
 
 <hr>
+<h1>Changes from ns-3.17 to ns-3.18</h1>
+<h2>New API:</h2>
+<ul>
+  <li>In Wifi:
+    <ul>
+      <li>A new helper (HtWifiMacHelper) was added. The user can use this helper to set up a high throughput (HT) MAC entity</li>
+    </ul>
+  </li>
+    <ul>
+      <li>New attributes are added to help the use setup a high throughpt (HT) PHY entity. These attributes can be set using the YansWifiPhyHelper</li>
+      <li>A new standard has been added that uses the new 11n data rates.</li>
+    </ul>
+    <ul>
+      <li>New 11n preambles has been added (Mixed format and greenfiled). To be able to change Tx duration according to the preamble used a new class txVector has been added to carry the transmission parameters (mode, preamle, stbc,..).Several functions have been updated to allow the passage of TxVector instead of WifiMode in MacLow, WifiRemoteStationManager, WifiPhy, YansWifiPhy,.. </li>
+    </ul>
+    <ul>
+      <li>All functions in WifiRemoteStationManager named GetXxxMode has been changed to GetXxxTxVector </li>
+    </ul>
+    <ul>
+      <li>New Information element has been added HTCapabilities. This information element is add to the MAC frame header if the node is an HT node. This HTCapabilites information element is used to advertise the HT capabilites of the node to other nodes in the network</li>
+    </ul>
+<hr>
 <h1>Changes from ns-3.16 to ns-3.17</h1>
 
 <h2>New API:</h2>
--- a/RELEASE_NOTES	Tue Aug 13 10:37:49 2013 -0700
+++ b/RELEASE_NOTES	Tue Aug 13 22:05:25 2013 -0700
@@ -43,6 +43,7 @@
   examples/ipv6/fragmentation-ipv6-two-MTU.cc for an example.
 - Radvd application have a new Helper. See the updated 
   examples/ipv6/radvd.cc for an example.
+- 11n- It is now possible to create a high throughput (HT) node that used the new 11n data rates and preambles.
 
 Bugs fixed
 ----------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/wireless/ht-wifi-network.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -0,0 +1,244 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as 
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/applications-module.h"
+#include "ns3/wifi-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/internet-module.h"
+
+//This is a simple example in order to show how 802.11n frame aggregation feature (A-MSDU) works.
+//
+//Network topology:
+// 
+//  Wifi 192.168.1.0
+// 
+//             AP
+//   *    *    *
+//   |    |    |
+//   n1   n2   n3 
+//
+//Packets in this simulation aren't marked with a QosTag so they are considered
+//belonging to BestEffort Access Class (AC_BE).
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("DataRates");
+
+double rxBytessum=0;
+double throughput=0;
+
+
+//===========================================================================
+//Set position of the nodes
+//===========================================================================
+static void
+SetPosition (Ptr<Node> node, Vector position)
+{
+  Ptr<MobilityModel> mobility = node->GetObject<MobilityModel> ();
+  mobility->SetPosition (position);
+}
+
+//==========================================================================
+//==========================================================================
+
+int main (int argc, char *argv[])
+{
+  std::cout << "DataRate" <<"  " << "Throughput" << '\n';
+  bool udp = true;
+  int i=2;
+  for (;i <= 2; i++)
+  {
+    uint32_t nWifi = 1;
+    CommandLine cmd;
+    cmd.AddValue ("nWifi", "Number of wifi STA devices", nWifi);
+    cmd.Parse (argc,argv);
+    Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("990000"));
+    // disable rts cts all the time.
+    Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("99000"));
+    NodeContainer wifiNodes;
+    wifiNodes.Create (1);
+    NodeContainer wifiApNode;
+    wifiApNode.Create (1);
+ 
+    YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
+    YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
+    phy.SetChannel (channel.Create ());
+    if (i ==3 || i == 4)
+      phy.Set ("ShortGuardEnabled",BooleanValue(true));
+      //phy.Set ("GreenfieldEnabled",BooleanValue(true));
+
+    WifiHelper wifi = WifiHelper::Default ();
+    wifi.SetStandard (WIFI_PHY_STANDARD_80211n_2_4GHZ);
+    HtWifiMacHelper mac = HtWifiMacHelper::Default ();
+ 
+
+    Ssid ssid = Ssid ("ns380211n");
+    double datarate;
+    StringValue DataRate;
+    if (i==0)
+      {
+        DataRate = StringValue("OfdmRate6_5MbpsBW20MHz");
+        datarate = 6.5;
+      }
+    else if (i==1)
+      {
+        DataRate = StringValue("OfdmRate58_5MbpsBW20MHz");
+        datarate = 58.5;
+      }
+    else if (i == 2)
+      {
+        DataRate = StringValue("OfdmRate65MbpsBW20MHz");
+        datarate = 65;
+      }
+    else if (i == 3)
+      {
+        DataRate = StringValue("OfdmRate57_8MbpsBW20MHz");
+        datarate = 57.8;
+      }
+    else if (i == 4)
+      {
+        DataRate = StringValue("OfdmRate72_2MbpsBW20MHz");
+        datarate = 72.2;
+      }
+
+    wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager","DataMode", DataRate,
+                                   "ControlMode", DataRate);
+    mac.SetType ("ns3::StaWifiMac",
+                 "Ssid", SsidValue (ssid),
+                 "ActiveProbing", BooleanValue (false));
+    
+    NetDeviceContainer staDevices;
+    staDevices = wifi.Install (phy, mac, wifiNodes);
+
+    mac.SetType ("ns3::ApWifiMac",
+                 "Ssid", SsidValue (ssid));
+   
+    NetDeviceContainer apDevice;
+    apDevice = wifi.Install (phy, mac, wifiApNode);
+   /* Ptr<WifiRemoteStationManager> apStationManager =
+              DynamicCast<WifiNetDevice>(apDevice.Get (0))->GetRemoteStationManager ();
+    apStationManager->AddBasicMode (WifiMode ("OfdmRate13MbpsBW20MHz"));
+    apStationManager->AddBasicMode (WifiMode ("OfdmRate19_5MbpsBW20MHz"));
+    apStationManager->AddBasicMode (WifiMode ("OfdmRate26MbpsBW20MHz"));
+    apStationManager->AddBasicMode (WifiMode ("OfdmRate39MbpsBW20MHz"));
+    Ptr<WifiRemoteStationManager> staStationManager =
+              DynamicCast<WifiNetDevice> (staDevices.Get (0))->GetRemoteStationManager ();
+    staStationManager->AddBasicMode (WifiMode ("OfdmRate13MbpsBW20MHz"));
+    staStationManager->AddBasicMode (WifiMode ("OfdmRate19_5MbpsBW20MHz"));
+    staStationManager->AddBasicMode (WifiMode ("OfdmRate26MbpsBW20MHz"));
+    staStationManager->AddBasicMode (WifiMode ("OfdmRate39MbpsBW20MHz"));*/
+              
+   // mobility.
+   MobilityHelper mobility;
+   mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+   mobility.Install (wifiNodes);
+   mobility.Install (wifiApNode);
+    
+   SetPosition (wifiNodes.Get(0), Vector (1.0,0.0,0.0));
+   SetPosition (wifiApNode.Get(0), Vector (0.0,0.0,0.0));
+ 
+
+   /* Internet stack*/
+   InternetStackHelper stack;
+   stack.Install (wifiApNode);
+   stack.Install (wifiNodes);
+
+   Ipv4AddressHelper address;
+
+   address.SetBase ("10.1.3.0", "255.255.255.0");
+   Ipv4InterfaceContainer wifiNodesInterfaces;
+   Ipv4InterfaceContainer apNodeInterface;
+
+   wifiNodesInterfaces = address.Assign (staDevices);
+   apNodeInterface = address.Assign (apDevice);
+
+   ApplicationContainer serverApps,sink1App;
+
+   double t=10;
+
+   /* Setting applications */
+   if (udp)
+     {
+       UdpServerHelper myServer (9);
+       serverApps = myServer.Install (wifiNodes.Get (0));
+       serverApps.Start (Seconds (0.0));
+       serverApps.Stop (Seconds (t));
+
+       UdpClientHelper myClient (wifiNodesInterfaces.GetAddress (0), 9);
+       myClient.SetAttribute ("MaxPackets", UintegerValue (64707202));
+       myClient.SetAttribute ("Interval", TimeValue (Time ("0.00002")));
+       myClient.SetAttribute ("PacketSize", UintegerValue (1500));
+ 
+       ApplicationContainer clientApps = myClient.Install (wifiApNode.Get (0));
+       clientApps.Start (Seconds (0.0));
+       clientApps.Stop (Seconds (t));
+     }
+   else
+     {
+
+       //TCP flow
+       uint16_t port = 50000;
+       Address apLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
+       PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", apLocalAddress);
+       sink1App = packetSinkHelper.Install (wifiNodes.Get (0));
+
+       sink1App.Start (Seconds (0.0));
+       sink1App.Stop (Seconds (t));
+            
+       OnOffHelper onoff ("ns3::TcpSocketFactory",Ipv4Address::GetAny ());
+       onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable(30)));//in seconds
+       onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable(0)));
+       onoff.SetAttribute ("PacketSize", UintegerValue (1500-30));//1024
+       onoff.SetAttribute ("DataRate", DataRateValue (100000000));//51200
+       ApplicationContainer apps;
+
+       AddressValue remoteAddress (InetSocketAddress (wifiNodesInterfaces.GetAddress(0), port));
+       onoff.SetAttribute ("Remote", remoteAddress);
+       apps.Add (onoff.Install (wifiApNode.Get (0)));
+       apps.Start (Seconds (0.0));
+       apps.Stop (Seconds (t));
+     }
+
+  
+   Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+
+   Simulator::Stop (Seconds (t));
+   Simulator::Run ();
+   Simulator::Destroy ();
+
+   //UDP
+   if (udp)
+     {
+       uint32_t totalPacketsThrough = DynamicCast<UdpServer>(serverApps.Get (0))->GetReceived ();
+       throughput=totalPacketsThrough*1500*8/(t*1000000.0);
+     }
+   else
+     {
+       //TCP
+       uint32_t totalPacketsThrough = DynamicCast<PacketSink>(sink1App.Get (0))->GetTotalRx ();
+       throughput=totalPacketsThrough*8/((t-3)*1000000.0);
+     }
+  
+   std::cout << datarate <<"  " << throughput << '\n';
+   }
+  return 0;
+} 
--- a/examples/wireless/wscript	Tue Aug 13 10:37:49 2013 -0700
+++ b/examples/wireless/wscript	Tue Aug 13 22:05:25 2013 -0700
@@ -48,3 +48,6 @@
 
     obj = bld.create_ns3_program('wifi-hidden-terminal', ['internet', 'mobility', 'wifi', 'applications', 'propagation', 'flow-monitor'])
     obj.source = 'wifi-hidden-terminal.cc'
+
+    obj = bld.create_ns3_program('ht-wifi-network', ['core','internet', 'mobility', 'wifi', 'applications', 'propagation'])
+    obj.source = 'ht-wifi-network.cc'
--- a/src/mesh/model/dot11s/airtime-metric.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/mesh/model/dot11s/airtime-metric.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -21,6 +21,8 @@
 #include "airtime-metric.h"
 #include "ns3/wifi-remote-station-manager.h"
 #include "ns3/wifi-mode.h"
+#include "ns3/wifi-tx-vector.h"
+
 namespace ns3 {
 namespace dot11s {
 NS_OBJECT_ENSURE_REGISTERED (AirtimeLinkMetricCalculator);
@@ -86,7 +88,7 @@
    */
   NS_ASSERT (!peerAddress.IsGroup ());
   //obtain current rate:
-  WifiMode mode = mac->GetWifiRemoteStationManager ()->GetDataMode (peerAddress, &m_testHeader, m_testFrame, m_testFrame->GetSize ());
+  WifiMode mode = mac->GetWifiRemoteStationManager ()->GetDataTxVector (peerAddress, &m_testHeader, m_testFrame, m_testFrame->GetSize ()).GetMode();
   //obtain frame error rate:
   double failAvg = mac->GetWifiRemoteStationManager ()->GetInfo (peerAddress).GetFrameErrorRate ();
   if (failAvg == 1)
@@ -95,10 +97,12 @@
       return (uint32_t)0xffffffff;
     }
   NS_ASSERT (failAvg < 1.0);
+  WifiTxVector txVector;
+  txVector.SetMode (mode);
   //calculate metric
   uint32_t metric = (uint32_t)((double)( /*Overhead + payload*/
                                  mac->GetPifs () + mac->GetSlot () + mac->GetEifsNoDifs () + //DIFS + SIFS + AckTxTime = PIFS + SLOT + EifsNoDifs
-                                 mac->GetWifiPhy ()->CalculateTxDuration (m_testFrame->GetSize (), mode, WIFI_PREAMBLE_LONG)
+                                 mac->GetWifiPhy ()->CalculateTxDuration (m_testFrame->GetSize (), txVector, WIFI_PREAMBLE_LONG)
                                  ).GetMicroSeconds () / (10.24 * (1.0 - failAvg)));
   return metric;
 }
--- a/src/test/ns3wifi/wifi-interference-test-suite.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/test/ns3wifi/wifi-interference-test-suite.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -61,7 +61,7 @@
   static void GenerateTraffic (Ptr<Socket> socket, uint32_t pktSize, uint32_t pktCount, Time pktInterval);
   void PrintEndSync (std::string context, uint32_t dataRate, double snr, double per);
   double WifiSimpleInterference (std::string phyMode, double Prss, double Irss, double delta, uint32_t PpacketSize, 
-                                 uint32_t IpacketSize, bool verbose, InternetStackHelper internet);
+                                 uint32_t IpacketSize, bool verbose, InternetStackHelper internet, WifiPhyStandard wifiStandard);
   double m_PER;
   double m_SNR;
   uint32_t m_DataRate;
@@ -120,7 +120,7 @@
 }
 
 double 
-WifiInterferenceTestCase::WifiSimpleInterference (std::string phyMode,double Prss, double Irss, double delta, uint32_t PpacketSize, uint32_t IpacketSize, bool verbose, InternetStackHelper internet)
+WifiInterferenceTestCase::WifiSimpleInterference (std::string phyMode,double Prss, double Irss, double delta, uint32_t PpacketSize, uint32_t IpacketSize, bool verbose, InternetStackHelper internet, WifiPhyStandard wifiStandard)
 {
 
   uint32_t numPackets = 1;
@@ -151,7 +151,7 @@
 
   // The below set of helpers will help us to put together the wifi NICs we want
   WifiHelper wifi;
-  wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
+  wifi.SetStandard (wifiStandard);
 
   YansWifiPhyHelper wifiPhy =  YansWifiPhyHelper::Default ();
   // This is one parameter that matters when using FixedRssLossModel
@@ -241,6 +241,7 @@
 {
 
   std::string phyMode ("DsssRate1Mbps");
+  WifiPhyStandard wifiStandard=WIFI_PHY_STANDARD_80211b;
   double Prss = -90;  // -dBm
   double Irss = -90;  // -dBm
   double delta = 0;  // microseconds
@@ -253,17 +254,17 @@
   // Compute the packet error rate (PER) when delta=0 microseconds.  This
   // means that the interferer arrives at exactly the same time as the
   // intended packet
-  PER = WifiSimpleInterference (phyMode,Prss,Irss,delta,PpacketSize,IpacketSize,verbose,internet);
+  PER = WifiSimpleInterference (phyMode,Prss,Irss,delta,PpacketSize,IpacketSize,verbose,internet,wifiStandard);
 
   // Now rerun this test case and compute the PER when the delta time between
   // arrival of the intended frame and interferer is 1 microsecond.
   delta = 1;
-  PER1 = WifiSimpleInterference (phyMode,Prss,Irss,delta,PpacketSize,IpacketSize,verbose,internet);
+  PER1 = WifiSimpleInterference (phyMode,Prss,Irss,delta,PpacketSize,IpacketSize,verbose,internet,wifiStandard);
 
   // Now rerun this test case and compute the PER when the delta time between
   // arrival of the intended frame and interferer is 2 microseconds.
   delta = 2;
-  PER2 = WifiSimpleInterference (phyMode,Prss,Irss,delta,PpacketSize,IpacketSize,verbose,internet);
+  PER2 = WifiSimpleInterference (phyMode,Prss,Irss,delta,PpacketSize,IpacketSize,verbose,internet,wifiStandard);
 
   double PERDiff1 = PER - PER1;
 
@@ -271,6 +272,30 @@
 
   NS_TEST_ASSERT_MSG_EQ (PERDiff1, PERDiff2, 
                          "The PER difference due to 1 microsecond difference in arrival shouldn't depend on absolute arrival");
+  //Now rerun for 11n
+  wifiStandard=WIFI_PHY_STANDARD_80211n_2_4GHZ;
+  // Compute the packet error rate (PER) when delta=0 microseconds.  This
+  // means that the interferer arrives at exactly the same time as the
+  // intended packet
+  PER = WifiSimpleInterference (phyMode,Prss,Irss,delta,PpacketSize,IpacketSize,verbose,internet,wifiStandard);
+
+  // Now rerun this test case and compute the PER when the delta time between
+  // arrival of the intended frame and interferer is 1 microsecond.
+  delta = 1;
+  PER1 = WifiSimpleInterference (phyMode,Prss,Irss,delta,PpacketSize,IpacketSize,verbose,internet,wifiStandard);
+
+  // Now rerun this test case and compute the PER when the delta time between
+  // arrival of the intended frame and interferer is 2 microseconds.
+  delta = 2;
+  PER2 = WifiSimpleInterference (phyMode,Prss,Irss,delta,PpacketSize,IpacketSize,verbose,internet,wifiStandard);
+
+  PERDiff1 = PER - PER1;
+
+  PERDiff2 = PER1 - PER2;
+
+  NS_TEST_ASSERT_MSG_EQ (PERDiff1, PERDiff2, 
+                         "The PER difference due to 1 microsecond difference in arrival shouldn't depend on absolute arrival");
+
 }
 
 class WifiInterferenceTestSuite : public TestSuite
--- a/src/wifi/doc/wifi.rst	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/doc/wifi.rst	Tue Aug 13 22:05:25 2013 -0700
@@ -57,7 +57,7 @@
 These three MAC high models share a common parent in
 ``ns3::RegularWifiMac``, which exposes, among other MAC
 configuration, an attribute ``QosSupported`` that allows
-configuration of 802.11e/WMM-style QoS support. With QoS-enabled MAC
+configuration of 802.11e/WMM-style QoS support and an attribute "HtSupported" that allows configuration og 802.11n High Throughput style support. With QoS-enabled MAC
 models it is possible to work with traffic belonging to four different
 Access Categories (ACs): **AC_VO** for voice traffic,
 **AC_VI** for video traffic, **AC_BE** for best-effort
@@ -183,6 +183,10 @@
 prepared the YansWifiPhyHelper by telling it which channel it is connected to.
 The phy objects are created in the next step.
 
+To enable 802.11n High Throughput style parameters the following line of code could be used
+ wifiPhyHelper.Set ("ShortGuardEnabled",BooleanValue(true));
+ wifiPhyHelper.Set ("GreenfieldEnabled",BooleanValue(true));
+
 NqosWifiMacHelper and QosWifiMacHelper
 ++++++++++++++++++++++++++++++++++++++
 
@@ -225,6 +229,25 @@
   wifiMacHelper.SetBlockAckThresholdForAc (AC_BE, 10);
   wifiMacHelper.SetBlockAckInactivityTimeoutForAc (AC_BE, 5);
 
+HtWifiMacHelper
++++++++++++++++
+
+The ``ns3::HtWifiMacHelper``configures an
+object factory to create instances of a ``ns3::WifiMac``. It is used to
+supports creation of MAC instances that have 802.11n-style High throughput (Ht) and QoS support enabled.  
+
+For example the following user code configures a HT MAC that
+will be a non-AP STA in an infrastructure network where the AP has
+SSID ``ns-3-ssid``:::
+
+    HtWifiMacHelper wifiMacHelper = HtWifiMacHelper::Default ();
+    Ssid ssid = Ssid ("ns-3-ssid");
+    wifiMacHelper.SetType ("ns3::StaWifiMac",
+                          "Ssid", SsidValue (ssid),
+                          "ActiveProbing", BooleanValue (false));
+
+This object can be also used to set in the same way as ``ns3::QosWifiMacHelper``
+
 WifiHelper
 ++++++++++
 
--- a/src/wifi/examples/wifi-phy-test.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/examples/wifi-phy-test.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -33,6 +33,7 @@
 #include "ns3/nstime.h"
 #include "ns3/command-line.h"
 #include "ns3/flow-id-tag.h"
+#include "ns3/wifi-tx-vector.h"
 
 using namespace ns3;
 
@@ -69,7 +70,10 @@
 {
   Ptr<Packet> p = Create<Packet> (m_input.packetSize);
   WifiMode mode = WifiMode (m_input.txMode);
-  m_tx->SendPacket (p, mode, WIFI_PREAMBLE_SHORT, m_input.txPowerLevel);
+  WifiTxVector txVector;
+  txVector.SetTxPowerLevel (m_input.txPowerLevel);
+  txVector.SetMode (mode);
+  m_tx->SendPacket (p, mode, WIFI_PREAMBLE_SHORT, txVector);
 }
 
 void
@@ -171,8 +175,11 @@
 {
   Ptr<Packet> p = Create<Packet> (m_input.packetSizeA);
   p->AddByteTag (FlowIdTag (m_flowIdA));
+  WifiTxVector txVector;
+  txVector.SetTxPowerLevel (m_input.txPowerLevelA);
+  txVector.SetMode (WifiMode (m_input.txModeA));
   m_txA->SendPacket (p, WifiMode (m_input.txModeA),
-                     WIFI_PREAMBLE_SHORT, m_input.txPowerLevelA);
+                     WIFI_PREAMBLE_SHORT, txVector);
 }
 
 void
@@ -180,8 +187,11 @@
 {
   Ptr<Packet> p = Create<Packet> (m_input.packetSizeB);
   p->AddByteTag (FlowIdTag (m_flowIdB));
+  WifiTxVector txVector;
+  txVector.SetTxPowerLevel (m_input.txPowerLevelB);
+  txVector.SetMode (WifiMode (m_input.txModeB));
   m_txB->SendPacket (p, WifiMode (m_input.txModeB),
-                     WIFI_PREAMBLE_SHORT, m_input.txPowerLevelB);
+                     WIFI_PREAMBLE_SHORT, txVector);
 }
 
 void
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wifi/helper/ht-wifi-mac-helper.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -0,0 +1,55 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Ghada Badawy <gbadawy@gmail.com>
+ */
+#include "ht-wifi-mac-helper.h"
+#include "ns3/wifi-mac.h"
+#include "ns3/edca-txop-n.h"
+#include "ns3/pointer.h"
+#include "ns3/boolean.h"
+#include "ns3/uinteger.h"
+
+namespace ns3 {
+
+HtWifiMacHelper::HtWifiMacHelper ()
+{
+}
+
+HtWifiMacHelper::~HtWifiMacHelper ()
+{
+}
+
+HtWifiMacHelper
+HtWifiMacHelper::Default (void)
+{
+  HtWifiMacHelper helper;
+
+  // We're making Ht-enabled Wi-Fi MACs here, so we set the necessary
+  // attribute. I've carefully positioned this here so that someone
+  // who knows what they're doing can override with explicit
+  // attributes.
+  helper.SetType ("ns3::StaWifiMac",
+                  "QosSupported", BooleanValue (true),
+                  "HtSupported", BooleanValue (true));
+
+  return helper;
+}
+
+
+} // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wifi/helper/ht-wifi-mac-helper.h	Tue Aug 13 22:05:25 2013 -0700
@@ -0,0 +1,60 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Ghada Badawy <gbadawy@gmail.com>
+ */
+#ifndef HT_WIFI_MAC_HELPER_H
+#define HT_WIFI_MAC_HELPER_H
+
+#include "wifi-helper.h"
+#include "ns3/qos-utils.h"
+#include "qos-wifi-mac-helper.h"
+#include <map>
+
+namespace ns3 {
+
+/**
+ * \brief create HT-enabled MAC layers for a ns3::WifiNetDevice.
+ *
+ * This class can create MACs of type ns3::ApWifiMac, ns3::StaWifiMac,
+ * and, ns3::AdhocWifiMac, with QosSupported and HTSupported attributes set to True.
+ */
+class HtWifiMacHelper : public QosWifiMacHelper
+{
+public:
+  /**
+   * Create a QosWifiMacHelper that is used to make life easier when working
+   * with Wifi devices using a QOS MAC layer.
+   */
+  HtWifiMacHelper ();
+
+  /**
+   * \internal
+   * Destroy a HtWifiMacHelper
+   */
+  virtual ~HtWifiMacHelper ();
+
+  /**
+   * Create a mac helper in a default working state.
+   */
+  static HtWifiMacHelper Default (void);
+
+ };
+
+} // namespace ns3
+
+#endif /* HT_WIFI_MAC_HELPER_H */
--- a/src/wifi/helper/yans-wifi-helper.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/helper/yans-wifi-helper.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -252,7 +252,8 @@
   uint16_t            channelFreqMhz,
   uint16_t            channelNumber,
   uint32_t            rate,
-  bool                isShortPreamble)
+  bool                isShortPreamble,
+  uint8_t             txPower)
 {
   uint32_t dlt = file->GetDataLinkType ();
 
@@ -309,6 +310,7 @@
           }
 
         header.SetChannelFrequencyAndFlags (channelFreqMhz, channelFlags);
+        
 
         p->AddHeader (header);
         file->Write (Simulator::Now (), p);
--- a/src/wifi/model/aarf-wifi-manager.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/aarf-wifi-manager.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -216,21 +216,21 @@
   NS_LOG_FUNCTION (this << station);
 }
 
-WifiMode
-AarfWifiManager::DoGetDataMode (WifiRemoteStation *st, uint32_t size)
+WifiTxVector
+AarfWifiManager::DoGetDataTxVector (WifiRemoteStation *st, uint32_t size)
 {
   NS_LOG_FUNCTION (this << st << size);
   AarfWifiRemoteStation *station = (AarfWifiRemoteStation *) st;
-  return GetSupported (station, station->m_rate);
+  return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (station), GetStbc (station));
 }
-WifiMode
-AarfWifiManager::DoGetRtsMode (WifiRemoteStation *st)
+WifiTxVector
+AarfWifiManager::DoGetRtsTxVector (WifiRemoteStation *st)
 {
   NS_LOG_FUNCTION (this << st);
   /// \todo we could/should implement the Aarf algorithm for
   /// RTS only by picking a single rate within the BasicRateSet.
   AarfWifiRemoteStation *station = (AarfWifiRemoteStation *) st;
-  return GetSupported (station, 0);
+  return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (station), GetStbc (station));
 }
 
 bool
--- a/src/wifi/model/aarf-wifi-manager.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/aarf-wifi-manager.h	Tue Aug 13 22:05:25 2013 -0700
@@ -52,8 +52,8 @@
                                double ackSnr, WifiMode ackMode, double dataSnr);
   virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
   virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
-  virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
-  virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
+  virtual WifiTxVector DoGetDataTxVector (WifiRemoteStation *station, uint32_t size);
+  virtual WifiTxVector DoGetRtsTxVector (WifiRemoteStation *station);
   virtual bool IsLowLatency (void) const;
 
   uint32_t m_minTimerThreshold;
--- a/src/wifi/model/aarfcd-wifi-manager.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/aarfcd-wifi-manager.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -294,21 +294,21 @@
   NS_LOG_FUNCTION (this << station);
 }
 
-WifiMode
-AarfcdWifiManager::DoGetDataMode (WifiRemoteStation *st, uint32_t size)
+WifiTxVector
+AarfcdWifiManager::DoGetDataTxVector (WifiRemoteStation *st, uint32_t size)
 {
   NS_LOG_FUNCTION (this << st << size);
   AarfcdWifiRemoteStation *station = (AarfcdWifiRemoteStation *) st;
-  return GetSupported (station, station->m_rate);
+  return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (station), GetStbc (station));
 }
-WifiMode
-AarfcdWifiManager::DoGetRtsMode (WifiRemoteStation *st)
+WifiTxVector
+AarfcdWifiManager::DoGetRtsTxVector (WifiRemoteStation *st)
 {
   NS_LOG_FUNCTION (this << st);
   /// \todo we could/should implement the Aarf algorithm for
   /// RTS only by picking a single rate within the BasicRateSet.
   AarfcdWifiRemoteStation *station = (AarfcdWifiRemoteStation *) st;
-  return GetSupported (station, 0);
+  return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (station), GetStbc (station));
 }
 
 bool
--- a/src/wifi/model/aarfcd-wifi-manager.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/aarfcd-wifi-manager.h	Tue Aug 13 22:05:25 2013 -0700
@@ -55,8 +55,8 @@
                                double ackSnr, WifiMode ackMode, double dataSnr);
   virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
   virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
-  virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
-  virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
+  virtual WifiTxVector DoGetDataTxVector (WifiRemoteStation *station, uint32_t size);
+  virtual WifiTxVector DoGetRtsTxVector (WifiRemoteStation *station);
   virtual bool DoNeedRts (WifiRemoteStation *station,
                           Ptr<const Packet> packet, bool normally);
   virtual bool IsLowLatency (void) const;
--- a/src/wifi/model/amrr-wifi-manager.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/amrr-wifi-manager.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -24,6 +24,8 @@
 #include "ns3/uinteger.h"
 #include "ns3/double.h"
 
+#define Min(a,b) ((a < b) ? a : b)
+
 NS_LOG_COMPONENT_DEFINE ("AmrrWifiRemoteStation");
 
 namespace ns3 {
@@ -267,8 +269,8 @@
       ResetCnt (station);
     }
 }
-WifiMode
-AmrrWifiManager::DoGetDataMode (WifiRemoteStation *st, uint32_t size)
+WifiTxVector
+AmrrWifiManager::DoGetDataTxVector (WifiRemoteStation *st, uint32_t size)
 {
   NS_LOG_FUNCTION (this << st << size);
   AmrrWifiRemoteStation *station = (AmrrWifiRemoteStation *)st;
@@ -313,16 +315,16 @@
         }
     }
 
-  return GetSupported (station, rateIndex);
+  return WifiTxVector (GetSupported (station, rateIndex), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (station), GetStbc (station));
 }
-WifiMode
-AmrrWifiManager::DoGetRtsMode (WifiRemoteStation *st)
+WifiTxVector
+AmrrWifiManager::DoGetRtsTxVector (WifiRemoteStation *st)
 {
   NS_LOG_FUNCTION (this << st);
   AmrrWifiRemoteStation *station = (AmrrWifiRemoteStation *)st;
   UpdateMode (station);
   /// \todo can we implement something smarter ?
-  return GetSupported (station, 0);
+  return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (station), GetStbc (station));
 }
 
 
--- a/src/wifi/model/amrr-wifi-manager.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/amrr-wifi-manager.h	Tue Aug 13 22:05:25 2013 -0700
@@ -56,8 +56,8 @@
                                double ackSnr, WifiMode ackMode, double dataSnr);
   virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
   virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
-  virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
-  virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
+  virtual WifiTxVector DoGetDataTxVector (WifiRemoteStation *station, uint32_t size);
+  virtual WifiTxVector DoGetRtsTxVector (WifiRemoteStation *station);
   virtual bool IsLowLatency (void) const;
 
   void UpdateRetry (AmrrWifiRemoteStation *station);
--- a/src/wifi/model/ap-wifi-mac.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/ap-wifi-mac.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -227,6 +227,8 @@
       hdr.SetTypeData ();
     }
 
+  if (m_htSupported)
+   hdr.SetNoOrder();
   hdr.SetAddr1 (to);
   hdr.SetAddr2 (GetAddress ());
   hdr.SetAddr3 (from);
@@ -276,9 +278,20 @@
 ApWifiMac::GetSupportedRates (void) const
 {
   NS_LOG_FUNCTION (this);
+  SupportedRates rates;
+  // If it is an HT-AP then add the BSSMembershipSelectorSet 
+  // which only includes 127 for HT now. The standard says that the BSSMembershipSelectorSet
+  // must have its MSB set to 1 (must be treated as a Basic Rate)
+  // Also the standard mentioned that at leat 1 element should be included in the SupportedRates the rest can be in the ExtendedSupportedRates
+  if (m_htSupported)
+    {
+      for (uint32_t i = 0; i < m_phy->GetNBssMembershipSelectors(); i++)
+        {
+          rates.SetBasicRate(m_phy->GetBssMembershipSelector(i));
+        }
+    }
   // send the set of supported rates and make sure that we indicate
   // the Basic Rate set in this set of supported rates.
-  SupportedRates rates;
   for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
     {
       WifiMode mode = m_phy->GetMode (i);
@@ -290,9 +303,23 @@
       WifiMode mode = m_stationManager->GetBasicMode (j);
       rates.SetBasicRate (mode.GetDataRate ());
     }
+  
   return rates;
 }
-
+HtCapabilities
+ApWifiMac::GetHtCapabilities (void) const
+{
+ HtCapabilities capabilities;
+ capabilities.SetHtSupported(1);
+ capabilities.SetLdpc (m_phy->GetLdpc());
+ capabilities.SetShortGuardInterval20 (m_phy->GetGuardInterval());
+ capabilities.SetGreenfield (m_phy->GetGreenfield());
+ for (uint8_t i =0 ; i < m_phy->GetNMcs();i++)
+  {
+     capabilities.SetRxMcsBitmask(m_phy->GetMcs(i));
+  }
+ return capabilities;
+}
 void
 ApWifiMac::SendProbeResp (Mac48Address to)
 {
@@ -309,6 +336,11 @@
   probe.SetSsid (GetSsid ());
   probe.SetSupportedRates (GetSupportedRates ());
   probe.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
+if (m_htSupported)
+    {
+      probe.SetHtCapabilities (GetHtCapabilities());
+      hdr.SetNoOrder();
+    }
   packet->AddHeader (probe);
 
   // The standard is not clear on the correct queue for management
@@ -342,6 +374,12 @@
     }
   assoc.SetSupportedRates (GetSupportedRates ());
   assoc.SetStatusCode (code);
+
+ if (m_htSupported)
+    {
+      assoc.SetHtCapabilities (GetHtCapabilities());
+      hdr.SetNoOrder();
+    }
   packet->AddHeader (assoc);
 
   // The standard is not clear on the correct queue for management
@@ -367,7 +405,11 @@
   beacon.SetSsid (GetSsid ());
   beacon.SetSupportedRates (GetSupportedRates ());
   beacon.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
-
+  if (m_htSupported)
+    {
+      beacon.SetHtCapabilities (GetHtCapabilities());
+      hdr.SetNoOrder();
+    }
   packet->AddHeader (beacon);
 
   // The beacon has it's own special queue, so we load it in there
@@ -506,6 +548,20 @@
                       break;
                     }
                 }
+               if (m_htSupported)
+                    {//check that the STA supports all MCSs in Basic MCS Set
+                      HtCapabilities htcapabilities = assocReq.GetHtCapabilities ();
+                      for (uint32_t i = 0; i < m_stationManager->GetNBasicMcs (); i++)
+                        {
+                          uint8_t mcs = m_stationManager->GetBasicMcs (i);
+                          if (!htcapabilities.IsSupportedMcs (mcs))
+                            {
+                              problem = true;
+                              break;
+                            }
+                         }
+                      
+                     }
               if (problem)
                 {
                   // one of the Basic Rate set mode is not
@@ -525,6 +581,19 @@
                           m_stationManager->AddSupportedMode (from, mode);
                         }
                     }
+                   if (m_htSupported)
+                    {
+                      HtCapabilities htcapabilities = assocReq.GetHtCapabilities ();
+                      m_stationManager->AddStationHtCapabilities (from,htcapabilities);
+                      for (uint32_t j = 0; j < m_phy->GetNMcs (); j++)
+                       {
+                         uint8_t mcs = m_phy->GetMcs (j);
+                         if (htcapabilities.IsSupportedMcs (mcs))
+                           {
+                             m_stationManager->AddSupportedMcs (from, mcs);
+                           }
+                        }
+                     }
                   m_stationManager->RecordWaitAssocTxOk (from);
                   // send assoc response with success status.
                   SendAssocResp (hdr->GetAddr2 (), true);
--- a/src/wifi/model/ap-wifi-mac.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/ap-wifi-mac.h	Tue Aug 13 22:05:25 2013 -0700
@@ -23,7 +23,7 @@
 #define AP_WIFI_MAC_H
 
 #include "regular-wifi-mac.h"
-
+#include "ht-capabilities.h"
 #include "amsdu-subframe-header.h"
 #include "supported-rates.h"
 
@@ -117,6 +117,7 @@
   void SendProbeResp (Mac48Address to);
   void SendAssocResp (Mac48Address to, bool success);
   void SendOneBeacon (void);
+  HtCapabilities GetHtCapabilities (void) const;
   SupportedRates GetSupportedRates (void) const;
   void SetBeaconGeneration (bool enable);
   bool GetBeaconGeneration (void) const;
--- a/src/wifi/model/arf-wifi-manager.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/arf-wifi-manager.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -23,6 +23,8 @@
 #include "ns3/log.h"
 #include "ns3/uinteger.h"
 
+#define Min(a,b) ((a < b) ? a : b)
+
 NS_LOG_COMPONENT_DEFINE ("ns3::ArfWifiManager");
 
 
@@ -188,21 +190,21 @@
   NS_LOG_FUNCTION (this << station);
 }
 
-WifiMode
-ArfWifiManager::DoGetDataMode (WifiRemoteStation *st, uint32_t size)
+WifiTxVector
+ArfWifiManager::DoGetDataTxVector (WifiRemoteStation *st, uint32_t size)
 {
   NS_LOG_FUNCTION (this << st << size);
   ArfWifiRemoteStation *station = (ArfWifiRemoteStation *) st;
-  return GetSupported (station, station->m_rate);
+  return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (station), GetStbc (station));
 }
-WifiMode
-ArfWifiManager::DoGetRtsMode (WifiRemoteStation *st)
+WifiTxVector
+ArfWifiManager::DoGetRtsTxVector (WifiRemoteStation *st)
 {
   NS_LOG_FUNCTION (this << st);
   /// \todo we could/should implement the Arf algorithm for
   /// RTS only by picking a single rate within the BasicRateSet.
   ArfWifiRemoteStation *station = (ArfWifiRemoteStation *) st;
-  return GetSupported (station, 0);
+  return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (station), GetStbc (station));
 }
 
 bool
--- a/src/wifi/model/arf-wifi-manager.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/arf-wifi-manager.h	Tue Aug 13 22:05:25 2013 -0700
@@ -59,8 +59,8 @@
                                double ackSnr, WifiMode ackMode, double dataSnr);
   virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
   virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
-  virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
-  virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
+  virtual WifiTxVector DoGetDataTxVector (WifiRemoteStation *station, uint32_t size);
+  virtual WifiTxVector DoGetRtsTxVector (WifiRemoteStation *station);
   virtual bool IsLowLatency (void) const;
 
   uint32_t m_timerThreshold;
--- a/src/wifi/model/cara-wifi-manager.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/cara-wifi-manager.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -25,6 +25,8 @@
 #include "ns3/uinteger.h"
 #include "ns3/simulator.h"
 
+#define Min(a,b) ((a < b) ? a : b)
+
 NS_LOG_COMPONENT_DEFINE ("Cara");
 
 
@@ -163,21 +165,21 @@
   NS_LOG_FUNCTION (this << st);
 }
 
-WifiMode
-CaraWifiManager::DoGetDataMode (WifiRemoteStation *st,
-                                uint32_t size)
+WifiTxVector
+CaraWifiManager::DoGetDataTxVector (WifiRemoteStation *st,
+                                    uint32_t size)
 {
   NS_LOG_FUNCTION (this << st << size);
   CaraWifiRemoteStation *station = (CaraWifiRemoteStation *) st;
-  return GetSupported (station, station->m_rate);
+  return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (station), GetStbc (station));
 }
-WifiMode
-CaraWifiManager::DoGetRtsMode (WifiRemoteStation *st)
+WifiTxVector
+CaraWifiManager::DoGetRtsTxVector (WifiRemoteStation *st)
 {
   NS_LOG_FUNCTION (this << st);
   /// \todo we could/should implement the Arf algorithm for
   /// RTS only by picking a single rate within the BasicRateSet.
-  return GetSupported (st, 0);
+  return WifiTxVector (GetSupported (st, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (st), GetShortGuardInterval (st), Min (GetNumberOfReceiveAntennas (st),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (st), GetStbc (st));
 }
 
 bool
--- a/src/wifi/model/cara-wifi-manager.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/cara-wifi-manager.h	Tue Aug 13 22:05:25 2013 -0700
@@ -55,8 +55,8 @@
                                double ackSnr, WifiMode ackMode, double dataSnr);
   virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
   virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
-  virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
-  virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
+  virtual WifiTxVector DoGetDataTxVector (WifiRemoteStation *station, uint32_t size);
+  virtual WifiTxVector DoGetRtsTxVector (WifiRemoteStation *station);
   virtual bool DoNeedRts (WifiRemoteStation *station,
                           Ptr<const Packet> packet, bool normally);
   virtual bool IsLowLatency (void) const;
--- a/src/wifi/model/constant-rate-wifi-manager.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/constant-rate-wifi-manager.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -26,6 +26,8 @@
 
 NS_LOG_COMPONENT_DEFINE ("ConstantRateWifiManager");
 
+#define Min(a,b) ((a < b) ? a : b)
+
 namespace ns3 {
 
 NS_OBJECT_ENSURE_REGISTERED (ConstantRateWifiManager);
@@ -106,17 +108,17 @@
   NS_LOG_FUNCTION (this << station);
 }
 
-WifiMode
-ConstantRateWifiManager::DoGetDataMode (WifiRemoteStation *st, uint32_t size)
+WifiTxVector
+ConstantRateWifiManager::DoGetDataTxVector (WifiRemoteStation *st, uint32_t size)
 {
   NS_LOG_FUNCTION (this << st << size);
-  return m_dataMode;
+  return WifiTxVector (m_dataMode, GetDefaultTxPowerLevel (), GetLongRetryCount (st), GetShortGuardInterval (st), Min (GetNumberOfReceiveAntennas (st),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (st), GetStbc (st));
 }
-WifiMode
-ConstantRateWifiManager::DoGetRtsMode (WifiRemoteStation *st)
+WifiTxVector
+ConstantRateWifiManager::DoGetRtsTxVector (WifiRemoteStation *st)
 {
   NS_LOG_FUNCTION (this << st);
-  return m_ctlMode;
+  return WifiTxVector (m_ctlMode, GetDefaultTxPowerLevel (), GetShortRetryCount (st), GetShortGuardInterval (st), Min (GetNumberOfReceiveAntennas (st),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (st), GetStbc (st));
 }
 
 bool
--- a/src/wifi/model/constant-rate-wifi-manager.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/constant-rate-wifi-manager.h	Tue Aug 13 22:05:25 2013 -0700
@@ -53,8 +53,8 @@
                                double ackSnr, WifiMode ackMode, double dataSnr);
   virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
   virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
-  virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
-  virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
+  virtual WifiTxVector DoGetDataTxVector (WifiRemoteStation *station, uint32_t size);
+  virtual WifiTxVector DoGetRtsTxVector (WifiRemoteStation *station);
   virtual bool IsLowLatency (void) const;
 
   WifiMode m_dataMode;
--- a/src/wifi/model/edca-txop-n.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/edca-txop-n.h	Tue Aug 13 22:05:25 2013 -0700
@@ -58,7 +58,10 @@
   STA,
   AP,
   ADHOC_STA,
-  MESH
+  MESH,
+  HT_STA,
+  HT_AP,
+  HT_ADHOC_STA
 };
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wifi/model/ht-capabilities.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -0,0 +1,336 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as 
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Ghada Badawy <gbadawy@rim.com>
+ */
+
+#include "ht-capabilities.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+
+
+NS_LOG_COMPONENT_DEFINE ("HtCapabilities");
+
+namespace ns3 {
+
+
+HtCapabilities::HtCapabilities ()
+   :  m_ldpc(0),
+      m_supportedChannelWidth(0),
+      m_smPowerSave(0),
+      m_greenField(0),
+      m_shortGuardInterval20(0),
+      m_shortGuardInterval40(0),
+      m_txStbc(0),
+      m_rxStbc(0),
+      m_htDelayedBlockAck(0),
+      m_maxAmsduLength(0),
+      m_dssMode40(0),
+      m_reserved(0),
+      m_fortyMhzIntolerant(0),
+      m_lsigProtectionSupport(0),
+      m_maxAmpduLength(0),
+      m_minMpduStartSpace(0),
+      m_ampduReserved(0),
+      m_reservedMcsSet1(0),
+      m_rxHighestSupportedDataRate(0),
+      m_reservedMcsSet2(0),
+      m_txMcsSetDefined(0),
+      m_txRxMcsSetUnequal(0),
+      m_txMaxNSpatialStreams(0),
+      m_txUnequalModulation(0),
+      m_reservedMcsSet3(7),
+      m_htSupported(0)
+{
+  for (uint32_t k=0; k < MAX_SUPPORTED_MCS ;k++)
+   {
+     m_rxMcsBitmask[k]=0;
+   }
+}
+
+
+WifiInformationElementId
+HtCapabilities::ElementId () const
+{
+  return IE_HT_CAPABILITIES;
+}
+
+void 
+HtCapabilities::SetHtSupported(uint8_t htsupported)
+{
+  m_htSupported = htsupported;
+}
+void
+HtCapabilities::SetLdpc (uint8_t ldpc)
+{
+ m_ldpc=ldpc;
+}
+
+void
+HtCapabilities::SetSupportedChannelWidth (uint8_t supportedchannelwidth)
+{
+ m_supportedChannelWidth=supportedchannelwidth;
+}
+
+void
+HtCapabilities::SetGreenfield (uint8_t greenfield)
+{
+ m_greenField=greenfield;
+}
+
+void
+HtCapabilities::SetShortGuardInterval20 (uint8_t shortguardinterval)
+{
+ m_shortGuardInterval20=shortguardinterval;
+}
+void
+HtCapabilities::SetRxMcsBitmask(uint8_t index)
+{
+   m_rxMcsBitmask[index]=1;
+}
+
+uint8_t*
+HtCapabilities::GetRxMcsBitmask()
+{
+  uint8_t* p;
+  p= m_rxMcsBitmask;
+  return p;
+}
+
+bool 
+HtCapabilities::IsSupportedMcs (uint8_t mcs)
+{
+  if (m_rxMcsBitmask[mcs] == 1)
+   {
+      return true;
+   }
+  return false;
+  
+}
+uint8_t
+HtCapabilities::GetLdpc (void) const
+{
+  return m_ldpc;
+}
+
+uint8_t
+HtCapabilities::GetSupportedChannelWidth (void) const
+{
+  return m_supportedChannelWidth;
+}
+
+uint8_t
+HtCapabilities::GetGreenfield (void) const
+{
+  return m_greenField;
+}
+uint8_t
+HtCapabilities::GetShortGuardInterval20(void) const
+{
+  return m_shortGuardInterval20;
+}
+
+uint8_t
+HtCapabilities::GetInformationFieldSize () const
+{
+  // we should not be here if ht is not supported
+  NS_ASSERT (m_htSupported > 0);
+  return 19;
+}
+Buffer::Iterator
+HtCapabilities::Serialize (Buffer::Iterator i) const
+{
+  if (m_htSupported< 1)
+    {
+       return i;
+    }
+  return WifiInformationElement::Serialize (i);
+}
+uint16_t
+HtCapabilities::GetSerializedSize () const
+{
+  if (m_htSupported < 1)
+    {
+      return 0;
+    }
+  return WifiInformationElement::GetSerializedSize ();
+}
+
+uint16_t
+HtCapabilities::GetHtCapabilitiesInfo (void) const
+{
+  uint16_t val = 0;
+  val |= m_ldpc;
+  val |= (m_supportedChannelWidth << 1)& (0x1 << 1);
+  val |= (m_smPowerSave << 2)& (0x3 << 2) ;
+  val |= (m_greenField << 4)& (0x1 << 4) ;
+  val |= (m_shortGuardInterval20 << 5)& (0x1 << 5);
+  val |= (m_shortGuardInterval40 << 6)& (0x1 << 6);
+  val |= (m_txStbc << 7)& (0x1 << 7);
+  val |= (m_rxStbc << 8)& (0x3 << 8);
+  val |= (m_htDelayedBlockAck << 10)& (0x1 << 10);
+  val |= (m_maxAmsduLength << 11)& (0x1 << 11);
+  val |= (m_dssMode40 << 12)& (0x1 << 12);
+  val |= (m_reserved<< 13)& (0x1 << 13);
+  val |= (m_fortyMhzIntolerant << 14)& (0x1 << 14);
+  val |= (m_lsigProtectionSupport << 15)& (0x1 << 15);
+  return val;
+}
+
+void
+HtCapabilities::SetHtCapabilitiesInfo(uint16_t ctrl)
+{
+  m_ldpc = ctrl & 0x01;
+  m_supportedChannelWidth = (ctrl >> 1) & 0x01;
+  m_smPowerSave = (ctrl >> 2) & 0x03;
+  m_greenField = (ctrl >> 4) & 0x01;
+  m_shortGuardInterval20  = (ctrl >> 5) & 0x01;
+  m_shortGuardInterval40  = (ctrl >> 6) & 0x01;
+  m_txStbc = (ctrl >> 7) & 0x01;
+  m_rxStbc = (ctrl >> 8) & 0x03;
+  m_htDelayedBlockAck = (ctrl >> 10) & 0x01;
+  m_maxAmsduLength = (ctrl >> 11) & 0x01;
+  m_dssMode40= (ctrl >> 12) & 0x01;
+  m_reserved= (ctrl >> 13) & 0x01;
+  m_fortyMhzIntolerant= (ctrl >> 14) & 0x01;
+  m_lsigProtectionSupport= (ctrl >> 15) & 0x01;
+}
+uint8_t
+HtCapabilities::GetAmpduParameters (void) const
+{
+  uint8_t val = 0;
+  val |=  m_maxAmpduLength & 0x3;
+  val |= ( m_minMpduStartSpace << 2)& (0x7 << 2);
+  val |= (m_ampduReserved << 5)& (0x7 << 5) ;
+  return val;
+}
+
+void
+HtCapabilities::SetAmpduParameters (uint8_t ctrl)
+{
+  m_maxAmpduLength = ctrl & 0x03;
+  m_minMpduStartSpace = (ctrl >> 2) & 0x07;
+  m_ampduReserved =(ctrl >> 5) & 0x07;
+}
+
+void
+HtCapabilities::SetSupportedMcsSet (uint64_t ctrl2, uint64_t ctrl1)
+{
+  for(uint64_t i=0 ; i < 77;i++)
+    {
+      if (i < 64)
+        {
+          m_rxMcsBitmask[i]=(ctrl1 >> i) & 0x01; 
+        }
+      else
+        {
+           m_rxMcsBitmask[i]=( ctrl2 >> (i-64))& 0x01 ;
+        }
+    }
+  m_reservedMcsSet1 = (ctrl2 >> 12) & 0x07;
+  m_rxHighestSupportedDataRate = (ctrl2 >> 15) & 0x03ff;
+  m_reservedMcsSet2 = (ctrl2 >> 25) & 0x3f;
+  m_txMcsSetDefined  = (ctrl2 >> 31) & 0x01;
+  m_txRxMcsSetUnequal  = (ctrl2 >> 32) & 0x01;
+  m_txMaxNSpatialStreams = (ctrl2 >> 33) & 0x03;
+  m_txUnequalModulation = (ctrl2 >> 35) & 0x01;
+  m_reservedMcsSet3 = (ctrl2 >> 36) & 0x07ffffff;
+}
+uint64_t
+HtCapabilities::GetSupportedMcsSet1 (void) const
+{
+  uint64_t val=0;
+  for(uint64_t i=63 ; i >0 ;i--)
+    {
+          val = (val << 1) | (m_rxMcsBitmask[i] & 0x01);
+    }
+  val = (val << 1) | (m_rxMcsBitmask[0] & 0x01);
+  return val;
+}
+uint64_t
+HtCapabilities::GetSupportedMcsSet2 (void) const
+{
+  uint64_t val=0; 
+  val = val | (m_reservedMcsSet3 & 0x07ffffff);
+  val = (val << 1) | (m_txUnequalModulation & 0x01);
+  val = (val << 2) | (m_txMaxNSpatialStreams & 0x03);
+  val = (val << 1) | (m_txRxMcsSetUnequal & 0x01);
+  val = (val << 1) | (m_txMcsSetDefined & 0x01);
+  val = (val << 6) | (m_reservedMcsSet2 & 0x3f);
+  val = (val << 10) |(m_rxHighestSupportedDataRate & 0x3ff);
+  val = (val << 3) |(m_reservedMcsSet1 & 0x07);
+
+  for (uint64_t i=12; i>0;i--)
+    {
+       val = (val << 1)|( m_rxMcsBitmask[i+64] & 0x01);
+    }
+  return val;
+}
+
+void
+HtCapabilities::SerializeInformationField (Buffer::Iterator start) const
+{
+   if (m_htSupported == 1)
+    {
+       // write the corresponding value for each bit
+       start. WriteHtolsbU16 (GetHtCapabilitiesInfo());
+       start. WriteU8 (GetAmpduParameters());
+       start. WriteHtolsbU64 (GetSupportedMcsSet2());
+       start. WriteHtolsbU64 (GetSupportedMcsSet1());
+    }
+}
+
+uint8_t
+HtCapabilities::DeserializeInformationField (Buffer::Iterator start,
+                                             uint8_t length)
+{ 
+  Buffer::Iterator i = start;
+  uint16_t htinfo = i.ReadLsbtohU16 ();
+  uint8_t ampduparam = i.ReadU8 ();
+  uint64_t mcsset1=i.ReadLsbtohU64 ();
+  uint64_t mcsset2 = i.ReadLsbtohU64 ();
+  SetHtCapabilitiesInfo(htinfo);
+  SetAmpduParameters(ampduparam);
+  SetSupportedMcsSet(mcsset1,mcsset2);
+  return length;
+}
+
+ATTRIBUTE_HELPER_CPP (HtCapabilities);
+
+std::ostream &
+operator << (std::ostream &os, const HtCapabilities &htcapabilities)
+{
+  os <<  htcapabilities.GetLdpc () << "|" << htcapabilities.GetSupportedChannelWidth ()
+  << "|" << htcapabilities.GetGreenfield ()
+  << "|" << htcapabilities.GetShortGuardInterval20 ();
+
+  return os;
+}
+
+std::istream &operator >> (std::istream &is,HtCapabilities &htcapabilities)
+{
+  bool c1, c2, c3,c4;
+  is >>  c1 >> c2 >> c3 >>c4;
+  htcapabilities.SetLdpc (c1);
+  htcapabilities.SetSupportedChannelWidth (c2);
+  htcapabilities.SetGreenfield (c3);
+  htcapabilities.SetShortGuardInterval20 (c4);
+
+  return is;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wifi/model/ht-capabilities.h	Tue Aug 13 22:05:25 2013 -0700
@@ -0,0 +1,123 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as 
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Ghada Badawy <gbadawy@gmail.com>
+ */
+#ifndef HT_CAPABILITIES_H
+#define HT_CAPABILITIES_H
+
+#include <stdint.h>
+#include "ns3/buffer.h"
+#include "ns3/attribute-helper.h"
+#include "ns3/wifi-information-element.h"
+
+/**
+ * This defines the maximum number of supported MCSs that a STA is
+ * allowed to have. Currently this number is set for IEEE 802.11n
+ */
+#define MAX_SUPPORTED_MCS  (77)
+
+namespace ns3 {
+
+/**
+ * \brief The Ht Capabilities Information Element
+ * \ingroup wifi
+ *
+ * This class knows how to serialise and deserialise the Ht Capabilities Information Element
+ */
+class HtCapabilities: public WifiInformationElement
+{
+public:
+   HtCapabilities ();
+  void SetLdpc (uint8_t ldpc);
+  void SetSupportedChannelWidth (uint8_t supportedchannelwidth);
+  void SetGreenfield (uint8_t greenfield);
+  void SetShortGuardInterval20(uint8_t shortguardinterval);
+  void SetHtCapabilitiesInfo(uint16_t ctrl);
+  void SetAmpduParameters (uint8_t ctrl);
+  void SetSupportedMcsSet (uint64_t ctrl1, uint64_t ctrl2);
+  void SetHtSupported(uint8_t htsupported);
+  void SetRxMcsBitmask(uint8_t index);
+  bool IsSupportedMcs (uint8_t mcs);
+  //returns the HT Capabilties info field in the HT Capabilities information element
+  uint16_t GetHtCapabilitiesInfo (void) const;
+  //returns the Ampdu parameters field in the HT Capabilities information element
+  uint8_t GetAmpduParameters (void) const;
+  //returns the first 64bytes of the Supported MCS field in the HT Capabilities information element
+  uint64_t GetSupportedMcsSet1 (void) const;
+  //returns the first 64bytes of the Supported MCS field in the HT Capabilities information element
+  uint64_t GetSupportedMcsSet2 (void) const;
+  uint8_t GetLdpc (void) const;
+  uint8_t GetGreenfield (void) const;
+  uint8_t GetShortGuardInterval20 (void) const;
+  uint8_t GetSupportedChannelWidth (void) const; //2040 supported or not
+  uint8_t ConvertToUint8 () const;
+  uint8_t* GetRxMcsBitmask();
+  
+  WifiInformationElementId ElementId () const;
+  uint8_t GetInformationFieldSize () const;
+  void SerializeInformationField (Buffer::Iterator start) const;
+  uint8_t DeserializeInformationField (Buffer::Iterator start,
+                                       uint8_t length);
+ /*
+   * This information element is a bit special in that it is only
+   * included if the STA is an HT STA. To support this we
+   * override the Serialize and GetSerializedSize methods of
+   * WifiInformationElement.
+   */
+  Buffer::Iterator Serialize (Buffer::Iterator start) const;
+  uint16_t GetSerializedSize () const;
+ 
+private:
+  uint8_t m_ldpc;
+  uint8_t m_supportedChannelWidth;
+  uint8_t m_smPowerSave;
+  uint8_t m_greenField;
+  uint8_t m_shortGuardInterval20; 
+  uint8_t m_shortGuardInterval40;
+  uint8_t m_txStbc;
+  uint8_t m_rxStbc;
+  uint8_t m_htDelayedBlockAck;
+  uint8_t m_maxAmsduLength;
+  uint8_t m_dssMode40;
+  uint8_t m_reserved;
+  uint8_t m_fortyMhzIntolerant;
+  uint8_t m_lsigProtectionSupport;
+  uint8_t m_maxAmpduLength;
+  uint8_t m_minMpduStartSpace;
+  uint8_t m_ampduReserved;
+  uint8_t m_reservedMcsSet1;
+  uint16_t m_rxHighestSupportedDataRate;
+  uint8_t m_reservedMcsSet2;
+  uint8_t m_txMcsSetDefined;
+  uint8_t m_txRxMcsSetUnequal;
+  uint8_t m_txMaxNSpatialStreams;
+  uint8_t m_txUnequalModulation;
+  uint32_t m_reservedMcsSet3; 
+  uint8_t m_rxMcsBitmask[MAX_SUPPORTED_MCS];
+  //this is used to decide if this element should be added to the frame or not
+  uint8_t m_htSupported;
+};
+
+std::ostream &operator << (std::ostream &os, const HtCapabilities &htcapabilities);
+std::istream &operator >> (std::istream &is, HtCapabilities &htcapabilities);
+
+ATTRIBUTE_HELPER_HEADER (HtCapabilities)
+
+} // namespace ns3
+
+#endif /* HT_CAPABILITY_H */
--- a/src/wifi/model/ideal-wifi-manager.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/ideal-wifi-manager.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -17,13 +17,14 @@
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
-
 #include "ideal-wifi-manager.h"
 #include "wifi-phy.h"
 #include "ns3/assert.h"
 #include "ns3/double.h"
 #include <cmath>
 
+#define Min(a,b) ((a < b) ? a : b)
+
 namespace ns3 {
 
 struct IdealWifiRemoteStation : public WifiRemoteStation
@@ -133,8 +134,8 @@
 {
 }
 
-WifiMode
-IdealWifiManager::DoGetDataMode (WifiRemoteStation *st, uint32_t size)
+WifiTxVector
+IdealWifiManager::DoGetDataTxVector (WifiRemoteStation *st, uint32_t size)
 {
   IdealWifiRemoteStation *station = (IdealWifiRemoteStation *)st;
   // We search within the Supported rate set the mode with the
@@ -153,10 +154,10 @@
           maxMode = mode;
         }
     }
-  return maxMode;
+  return WifiTxVector (maxMode, GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (station), GetStbc (station));
 }
-WifiMode
-IdealWifiManager::DoGetRtsMode (WifiRemoteStation *st)
+WifiTxVector
+IdealWifiManager::DoGetRtsTxVector (WifiRemoteStation *st)
 {
   IdealWifiRemoteStation *station = (IdealWifiRemoteStation *)st;
   // We search within the Basic rate set the mode with the highest
@@ -175,7 +176,7 @@
           maxMode = mode;
         }
     }
-  return maxMode;
+  return WifiTxVector (maxMode, GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (station), GetStbc (station));
 }
 
 bool
--- a/src/wifi/model/ideal-wifi-manager.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/ideal-wifi-manager.h	Tue Aug 13 22:05:25 2013 -0700
@@ -64,8 +64,8 @@
                                double ackSnr, WifiMode ackMode, double dataSnr);
   virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
   virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
-  virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
-  virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
+  virtual WifiTxVector DoGetDataTxVector (WifiRemoteStation *station, uint32_t size);
+  virtual WifiTxVector DoGetRtsTxVector (WifiRemoteStation *station);
   virtual bool IsLowLatency (void) const;
 
   // return the min snr needed to successfully transmit
--- a/src/wifi/model/interference-helper.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/interference-helper.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -34,13 +34,14 @@
 
 InterferenceHelper::Event::Event (uint32_t size, WifiMode payloadMode,
                                   enum WifiPreamble preamble,
-                                  Time duration, double rxPower)
+                                  Time duration, double rxPower, WifiTxVector txVector)
   : m_size (size),
     m_payloadMode (payloadMode),
     m_preamble (preamble),
     m_startTime (Simulator::Now ()),
     m_endTime (m_startTime + duration),
-    m_rxPowerW (rxPower)
+    m_rxPowerW (rxPower),
+    m_txVector (txVector)
 {
 }
 InterferenceHelper::Event::~Event ()
@@ -83,6 +84,13 @@
   return m_preamble;
 }
 
+WifiTxVector
+InterferenceHelper::Event::GetTxVector (void) const
+{
+  return m_txVector;
+}
+
+
 /****************************************************************
  *       Class which records SNIR change events for a
  *       short period of time.
@@ -128,7 +136,7 @@
 Ptr<InterferenceHelper::Event>
 InterferenceHelper::Add (uint32_t size, WifiMode payloadMode,
                          enum WifiPreamble preamble,
-                         Time duration, double rxPowerW)
+                         Time duration, double rxPowerW, WifiTxVector txVector)
 {
   Ptr<InterferenceHelper::Event> event;
 
@@ -136,7 +144,8 @@
                                              payloadMode,
                                              preamble,
                                              duration,
-                                             rxPowerW);
+                                             rxPowerW,
+                                             txVector);
   AppendEvent (event);
   return event;
 }
@@ -265,18 +274,25 @@
   Time previous = (*j).GetTime ();
   WifiMode payloadMode = event->GetPayloadMode ();
   WifiPreamble preamble = event->GetPreambleType ();
+ WifiMode MfHeaderMode ;
+ if (preamble==WIFI_PREAMBLE_HT_MF)
+   {
+    MfHeaderMode = WifiPhy::GetMFPlcpHeaderMode (payloadMode, preamble); //return L-SIG mode
+
+   }
   WifiMode headerMode = WifiPhy::GetPlcpHeaderMode (payloadMode, preamble);
-  Time plcpHeaderStart = (*j).GetTime () + MicroSeconds (WifiPhy::GetPlcpPreambleDurationMicroSeconds (payloadMode, preamble));
-  Time plcpPayloadStart = plcpHeaderStart + MicroSeconds (WifiPhy::GetPlcpHeaderDurationMicroSeconds (payloadMode, preamble));
+  Time plcpHeaderStart = (*j).GetTime () + MicroSeconds (WifiPhy::GetPlcpPreambleDurationMicroSeconds (payloadMode, preamble)); //packet start time+ preamble
+  Time plcpHsigHeaderStart=plcpHeaderStart+ MicroSeconds (WifiPhy::GetPlcpHeaderDurationMicroSeconds (payloadMode, preamble));//packet start time+ preamble+L SIG
+  Time plcpHtTrainingSymbolsStart = plcpHsigHeaderStart + MicroSeconds (WifiPhy::GetPlcpHtSigHeaderDurationMicroSeconds (payloadMode, preamble));//packet start time+ preamble+L SIG+HT SIG
+  Time plcpPayloadStart =plcpHtTrainingSymbolsStart + MicroSeconds (WifiPhy::GetPlcpHtTrainingSymbolDurationMicroSeconds (payloadMode, preamble,event->GetTxVector())); //packet start time+ preamble+L SIG+HT SIG+Training
   double noiseInterferenceW = (*j).GetDelta ();
   double powerW = event->GetRxPowerW ();
-
-  j++;
+    j++;
   while (ni->end () != j)
     {
       Time current = (*j).GetTime ();
       NS_ASSERT (current >= previous);
-
+      //Case 1: Both prev and curr point to the payload
       if (previous >= plcpPayloadStart)
         {
           psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
@@ -285,53 +301,230 @@
                                             current - previous,
                                             payloadMode);
         }
+      //Case 2: previous is before payload
+      else if (previous >= plcpHtTrainingSymbolsStart)
+        {
+          //Case 2a: current is after payload
+          if (current >= plcpPayloadStart)
+            { 
+               //Case 2ai and 2aii: All formats
+               psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                              noiseInterferenceW,
+                                                              payloadMode),
+                                                current - plcpPayloadStart,
+                                                payloadMode);
+                
+              }
+        }
+      //Case 3: previous is in HT-SIG: Non HT will not enter here since it didn't enter in the last two and they are all the same for non HT
+      else if (previous >=plcpHsigHeaderStart)
+        {
+          //Case 3a: cuurent after payload start
+          if (current >=plcpPayloadStart)
+             {
+                   psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                              noiseInterferenceW,
+                                                              payloadMode),
+                                                current - plcpPayloadStart,
+                                                payloadMode);
+                 
+                    psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                              noiseInterferenceW,
+                                                              headerMode),
+                                               plcpHtTrainingSymbolsStart - previous,
+                                                headerMode);
+              }
+          //case 3b: current after HT training symbols start
+          else if (current >=plcpHtTrainingSymbolsStart)
+             {
+                psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                                noiseInterferenceW,
+                                                                headerMode),
+                                                   plcpHtTrainingSymbolsStart - previous,
+                                                   headerMode);  
+                   
+             }
+         //Case 3c: current is with previous in HT sig
+         else
+            {
+                psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                                noiseInterferenceW,
+                                                                headerMode),
+                                                   current- previous,
+                                                   headerMode);  
+                   
+            }
+      }
+      //Case 4: previous in L-SIG: GF will not reach here because it will execute the previous if and exit
       else if (previous >= plcpHeaderStart)
         {
-          if (current >= plcpPayloadStart)
-            {
-              psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+          //Case 4a: current after payload start  
+          if (current >=plcpPayloadStart)
+             {
+                   psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                              noiseInterferenceW,
+                                                              payloadMode),
+                                                      current - plcpPayloadStart,
+                                                      payloadMode);
+                    //Case 4ai: Non HT format (No HT-SIG or Training Symbols)
+              if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT) //plcpHtTrainingSymbolsStart==plcpHeaderStart)
+                {
+                    psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
                                                               noiseInterferenceW,
                                                               headerMode),
                                                 plcpPayloadStart - previous,
                                                 headerMode);
-              psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                }
+
+               else{
+                    psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                              noiseInterferenceW,
+                                                              headerMode),
+                                                      plcpHtTrainingSymbolsStart - plcpHsigHeaderStart,
+                                                      headerMode);
+                    psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                                    noiseInterferenceW,
+                                                                    MfHeaderMode),
+                                                      plcpHsigHeaderStart - previous,
+                                                      MfHeaderMode);
+                 }
+              }
+           //Case 4b: current in HT training symbol. non HT will not come here since it went in previous if or if the previous ifis not true this will be not true        
+          else if (current >=plcpHtTrainingSymbolsStart)
+             {
+                psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
                                                               noiseInterferenceW,
-                                                              payloadMode),
-                                                current - plcpPayloadStart,
-                                                payloadMode);
-            }
-          else
+                                                              headerMode),
+                                                  plcpHtTrainingSymbolsStart - plcpHsigHeaderStart,
+                                                  headerMode);
+                psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                                noiseInterferenceW,
+                                                                MfHeaderMode),
+                                                   plcpHsigHeaderStart - previous,
+                                                   MfHeaderMode);
+              }
+          //Case 4c: current in H sig.non HT will not come here since it went in previous if or if the previous ifis not true this will be not true
+          else if (current >=plcpHsigHeaderStart)
+             {
+                psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                                noiseInterferenceW,
+                                                                headerMode),
+                                                  current - plcpHsigHeaderStart,
+                                                  headerMode);
+                 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                                 noiseInterferenceW,
+                                                                 MfHeaderMode),
+                                                   plcpHsigHeaderStart - previous,
+                                                   MfHeaderMode);
+
+             }
+         //Case 4d: Current with prev in L SIG
+         else 
             {
-              NS_ASSERT (current >= plcpHeaderStart);
-              psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                //Case 4di: Non HT format (No HT-SIG or Training Symbols)
+              if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT) //plcpHtTrainingSymbolsStart==plcpHeaderStart)
+                {
+                    psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
                                                               noiseInterferenceW,
                                                               headerMode),
                                                 current - previous,
                                                 headerMode);
+                }
+               else
+                {
+                psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                               noiseInterferenceW,
+                                                               MfHeaderMode),
+                                                 current - previous,
+                                                 MfHeaderMode);
+                }
             }
         }
+      //Case 5: previous is in the preamble works for all cases
       else
         {
           if (current >= plcpPayloadStart)
             {
-              psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
-                                                              noiseInterferenceW,
-                                                              headerMode),
-                                                plcpPayloadStart - plcpHeaderStart,
-                                                headerMode);
+              //for all
               psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
                                                               noiseInterferenceW,
                                                               payloadMode),
                                                 current - plcpPayloadStart,
-                                                payloadMode);
+                                                payloadMode); 
+             
+               // Non HT format (No HT-SIG or Training Symbols)
+              if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT)
+                 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                                 noiseInterferenceW,
+                                                                  headerMode),
+                                                    plcpPayloadStart - plcpHeaderStart,
+                                                    headerMode);
+              else
+              // Greenfield or Mixed format
+                psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                                noiseInterferenceW,
+                                                                headerMode),
+                                                  plcpHtTrainingSymbolsStart - plcpHsigHeaderStart,
+                                                  headerMode);
+              if (preamble == WIFI_PREAMBLE_HT_MF)
+                 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                                 noiseInterferenceW,
+                                                                 MfHeaderMode),
+                                                   plcpHsigHeaderStart-plcpHeaderStart,
+                                                   MfHeaderMode);             
             }
+          else if (current >=plcpHtTrainingSymbolsStart )
+          { 
+              // Non HT format will not come here since it will execute prev if
+              // Greenfield or Mixed format
+                psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                                noiseInterferenceW,
+                                                                headerMode),
+                                                  plcpHtTrainingSymbolsStart - plcpHsigHeaderStart,
+                                                  headerMode);
+              if (preamble == WIFI_PREAMBLE_HT_MF)
+                 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                                 noiseInterferenceW,
+                                                                 MfHeaderMode),
+                                                   plcpHsigHeaderStart-plcpHeaderStart,
+                                                   MfHeaderMode);       
+           }
+          //non HT will not come here     
+          else if (current >=plcpHsigHeaderStart)
+             { 
+                psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                                noiseInterferenceW,
+                                                                headerMode),
+                                                  current- plcpHsigHeaderStart,
+                                                  headerMode); 
+                if  (preamble != WIFI_PREAMBLE_HT_GF)
+                 {
+                   psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                                   noiseInterferenceW,
+                                                                   MfHeaderMode),
+                                                     plcpHsigHeaderStart-plcpHeaderStart,
+                                                     MfHeaderMode);    
+                  }          
+             }
+          // GF will not come here
           else if (current >= plcpHeaderStart)
             {
+               if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT)
+                 {
+                 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+                                                                 noiseInterferenceW,
+                                                                  headerMode),
+                                                    current - plcpHeaderStart,
+                                                    headerMode);
+                 }
+              else
+                 {
               psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
                                                               noiseInterferenceW,
-                                                              headerMode),
-                                                current - plcpHeaderStart,
-                                                headerMode);
+                                                             MfHeaderMode),
+                                               current - plcpHeaderStart,
+                                               MfHeaderMode);
+                       }
             }
         }
 
--- a/src/wifi/model/interference-helper.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/interference-helper.h	Tue Aug 13 22:05:25 2013 -0700
@@ -28,6 +28,7 @@
 #include "wifi-phy-standard.h"
 #include "ns3/nstime.h"
 #include "ns3/simple-ref-count.h"
+#include "ns3/wifi-tx-vector.h"
 
 namespace ns3 {
 
@@ -45,7 +46,7 @@
 public:
     Event (uint32_t size, WifiMode payloadMode,
            enum WifiPreamble preamble,
-           Time duration, double rxPower);
+           Time duration, double rxPower, WifiTxVector txvector);
     ~Event ();
 
     Time GetDuration (void) const;
@@ -55,6 +56,7 @@
     uint32_t GetSize (void) const;
     WifiMode GetPayloadMode (void) const;
     enum WifiPreamble GetPreambleType (void) const;
+    WifiTxVector GetTxVector (void) const;
 private:
     uint32_t m_size;
     WifiMode m_payloadMode;
@@ -62,6 +64,7 @@
     Time m_startTime;
     Time m_endTime;
     double m_rxPowerW;
+    WifiTxVector m_txVector;
   };
   struct SnrPer
   {
@@ -90,7 +93,7 @@
 
   Ptr<InterferenceHelper::Event> Add (uint32_t size, WifiMode payloadMode,
                                       enum WifiPreamble preamble,
-                                      Time duration, double rxPower);
+                                      Time duration, double rxPower, WifiTxVector txvector);
 
   struct InterferenceHelper::SnrPer CalculateSnrPer (Ptr<InterferenceHelper::Event> event);
   void NotifyRxStart ();
--- 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;
 }
 
--- a/src/wifi/model/mac-low.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/mac-low.h	Tue Aug 13 22:05:25 2013 -0700
@@ -41,6 +41,7 @@
 #include "ns3/nstime.h"
 #include "qos-utils.h"
 #include "block-ack-cache.h"
+#include "wifi-tx-vector.h"
 
 namespace ns3 {
 
@@ -391,12 +392,15 @@
   void SetAckTimeout (Time ackTimeout);
   void SetBasicBlockAckTimeout (Time blockAckTimeout);
   void SetCompressedBlockAckTimeout (Time blockAckTimeout);
+  void SetCtsToSelfSupported (bool enable);
   void SetCtsTimeout (Time ctsTimeout);
   void SetSifs (Time sifs);
+  void SetRifs (Time rifs);
   void SetSlotTime (Time slotTime);
   void SetPifs (Time pifs);
   void SetBssid (Mac48Address ad);
   void SetPromisc (void);
+  bool GetCtsToSelfSupported () const;
   Mac48Address GetAddress (void) const;
   Time GetAckTimeout (void) const;
   Time GetBasicBlockAckTimeout () const;
@@ -405,6 +409,7 @@
   Time GetSifs (void) const;
   Time GetSlotTime (void) const;
   Time GetPifs (void) const;
+  Time GetRifs (void) const;
   Mac48Address GetBssid (void) const;
 
   /**
@@ -515,20 +520,31 @@
   uint32_t GetCtsSize (void) const;
   uint32_t GetSize (Ptr<const Packet> packet, const WifiMacHeader *hdr) const;
   Time NowUs (void) const;
-  void ForwardDown (Ptr<const Packet> packet, const WifiMacHeader *hdr,
-                    WifiMode txMode);
+void ForwardDown (Ptr<const Packet> packet, const WifiMacHeader *hdr,
+                    WifiTxVector txVector, WifiPreamble preamble);
+  WifiTxVector GetRtsTxVector (Ptr<const Packet> packet, const WifiMacHeader *hdr) const;
+  WifiTxVector GetDataTxVector (Ptr<const Packet> packet, const WifiMacHeader *hdr) const;
+  WifiTxVector GetCtsTxVector (Mac48Address to, WifiMode rtsTxMode) const;
+  WifiTxVector GetAckTxVector (Mac48Address to, WifiMode dataTxMode) const;
+  WifiTxVector GetBlockAckTxVector (Mac48Address to, WifiMode dataTxMode) const;
+
+  WifiTxVector GetCtsToSelfTxVector (Ptr<const Packet> packet, const WifiMacHeader *hdr) const;
+
+  WifiTxVector GetCtsTxVectorForRts (Mac48Address to, WifiMode rtsTxMode) const;
+  WifiTxVector GetAckTxVectorForData (Mac48Address to, WifiMode dataTxMode) const;
+
+  Time GetCtsDuration (WifiTxVector ctsTxVector) const;
+  Time GetCtsDuration (Mac48Address to, WifiTxVector rtsTxVector) const;
+  Time GetAckDuration (WifiTxVector ackTxVector) const;
+  Time GetAckDuration (Mac48Address to, WifiTxVector dataTxVector) const;
+  Time GetBlockAckDuration (Mac48Address to, WifiTxVector blockAckReqTxVector, enum BlockAckType type) const;
+
+  bool NeedCtsToSelf (void);
+  
   Time CalculateOverallTxTime (Ptr<const Packet> packet,
                                const WifiMacHeader* hdr,
                                const MacLowTransmissionParameters &params) const;
-  WifiMode GetRtsTxMode (Ptr<const Packet> packet, const WifiMacHeader *hdr) const;
-  WifiMode GetDataTxMode (Ptr<const Packet> packet, const WifiMacHeader *hdr) const;
-  WifiMode GetCtsTxModeForRts (Mac48Address to, WifiMode rtsTxMode) const;
-  WifiMode GetAckTxModeForData (Mac48Address to, WifiMode dataTxMode) const;
-
-  Time GetCtsDuration (Mac48Address to, WifiMode rtsTxMode) const;
-  Time GetAckDuration (Mac48Address to, WifiMode dataTxMode) const;
-  Time GetBlockAckDuration (Mac48Address to, WifiMode blockAckReqTxMode, enum BlockAckType type) const;
-  void NotifyNav (const WifiMacHeader &hdr, WifiMode txMode, WifiPreamble preamble);
+  void NotifyNav (Ptr<const Packet> packet,const WifiMacHeader &hdr, WifiMode txMode, WifiPreamble preamble);
   void DoNavResetNow (Time duration);
   bool DoNavStartNow (Time duration);
   bool IsNavZero (void) const;
@@ -545,6 +561,7 @@
   void FastAckFailedTimeout (void);
   void BlockAckTimeout (void);
   void CtsTimeout (void);
+  void SendCtsToSelf (void);
   void SendCtsAfterRts (Mac48Address source, Time duration, WifiMode txMode, double rtsSnr);
   void SendAckAfterData (Mac48Address source, Time duration, WifiMode txMode, double rtsSnr);
   void SendDataAfterCts (Mac48Address source, Time duration, WifiMode txMode);
@@ -554,7 +571,7 @@
   void SendRtsForPacket (void);
   void SendDataPacket (void);
   void SendCurrentTxPacket (void);
-  void StartDataTxTimers (void);
+  void StartDataTxTimers (WifiTxVector dataTxVector);
   virtual void DoDispose (void);
   /**
    * \param originator Address of peer participating in Block Ack mechanism.
@@ -625,6 +642,7 @@
   EventId m_waitSifsEvent;
   EventId m_endTxNoAckEvent;
   EventId m_navCounterResetCtsMissed;
+  EventId m_waitRifsEvent;
 
   Ptr<Packet> m_currentPacket;
   WifiMacHeader m_currentHdr;
@@ -639,6 +657,7 @@
   Time m_sifs;
   Time m_slotTime;
   Time m_pifs;
+  Time m_rifs;
 
   Time m_lastNavStart;
   Time m_lastNavDuration;
@@ -668,6 +687,7 @@
 
   typedef std::map<AcIndex, MacLowBlockAckEventListener*> QueueListeners;
   QueueListeners m_edcaListeners;
+  bool m_ctsToSelfSupported;
 };
 
 } // namespace ns3
--- a/src/wifi/model/mgt-headers.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/mgt-headers.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -50,7 +50,17 @@
 {
   m_rates = rates;
 }
+void 
+MgtProbeRequestHeader::SetHtCapabilities(HtCapabilities htcapabilities)
+{
+  m_htCapability=htcapabilities;
+}
 
+HtCapabilities 
+MgtProbeRequestHeader::GetHtCapabilities (void) const
+{
+   return  m_htCapability;
+}
 SupportedRates
 MgtProbeRequestHeader::GetSupportedRates (void) const
 {
@@ -63,6 +73,7 @@
   size += m_ssid.GetSerializedSize ();
   size += m_rates.GetSerializedSize ();
   size += m_rates.extended.GetSerializedSize ();
+  size += m_htCapability.GetSerializedSize();
   return size;
 }
 TypeId
@@ -83,7 +94,8 @@
 MgtProbeRequestHeader::Print (std::ostream &os) const
 {
   os << "ssid=" << m_ssid << ", "
-     << "rates=" << m_rates;
+     << "rates=" << m_rates << ", "
+     << "HT Capabilities=" << m_htCapability;
 }
 void
 MgtProbeRequestHeader::Serialize (Buffer::Iterator start) const
@@ -92,6 +104,7 @@
   i = m_ssid.Serialize (i);
   i = m_rates.Serialize (i);
   i = m_rates.extended.Serialize (i);
+   i = m_htCapability.Serialize(i);
 }
 uint32_t
 MgtProbeRequestHeader::Deserialize (Buffer::Iterator start)
@@ -100,6 +113,7 @@
   i = m_ssid.Deserialize (i);
   i = m_rates.Deserialize (i);
   i = m_rates.extended.DeserializeIfPresent (i);
+  i = m_htCapability.DeserializeIfPresent (i);
   return i.GetDistanceFrom (start);
 }
 
@@ -136,7 +150,17 @@
 {
   return m_rates;
 }
+void 
+MgtProbeResponseHeader::SetHtCapabilities(HtCapabilities htcapabilities)
+{
+  m_htCapability=htcapabilities;
+}
 
+HtCapabilities 
+MgtProbeResponseHeader::GetHtCapabilities (void) const
+{
+   return  m_htCapability;
+}
 void
 MgtProbeResponseHeader::SetSsid (Ssid ssid)
 {
@@ -177,6 +201,7 @@
   size += m_rates.GetSerializedSize ();
   //size += 3; // ds parameter set
   size += m_rates.extended.GetSerializedSize ();
+  size += m_htCapability.GetSerializedSize();
   // xxx
   return size;
 }
@@ -184,7 +209,8 @@
 MgtProbeResponseHeader::Print (std::ostream &os) const
 {
   os << "ssid=" << m_ssid << ", "
-     << "rates=" << m_rates;
+     << "rates=" << m_rates << ", "
+     << "HT Capabilities=" << m_htCapability;
 }
 void
 MgtProbeResponseHeader::Serialize (Buffer::Iterator start) const
@@ -207,6 +233,7 @@
   i = m_rates.Serialize (i);
   //i.WriteU8 (0, 3); // ds parameter set.
   i = m_rates.extended.Serialize (i);
+  i = m_htCapability.Serialize(i);
 }
 uint32_t
 MgtProbeResponseHeader::Deserialize (Buffer::Iterator start)
@@ -220,6 +247,7 @@
   i = m_rates.Deserialize (i);
   //i.Next (3); // ds parameter set
   i = m_rates.extended.DeserializeIfPresent (i);
+  i = m_htCapability.DeserializeIfPresent (i);
   return i.GetDistanceFrom (start);
 }
 
@@ -247,11 +275,21 @@
 {
   m_rates = rates;
 }
+void 
+MgtAssocRequestHeader::SetHtCapabilities(HtCapabilities htcapabilities)
+{
+  m_htCapability = htcapabilities;
+}
 void
 MgtAssocRequestHeader::SetListenInterval (uint16_t interval)
 {
   m_listenInterval = interval;
 }
+HtCapabilities 
+MgtAssocRequestHeader::GetHtCapabilities (void) const
+{
+   return  m_htCapability;
+}
 Ssid
 MgtAssocRequestHeader::GetSsid (void) const
 {
@@ -290,6 +328,7 @@
   size += 2;
   size += m_ssid.GetSerializedSize ();
   size += m_rates.GetSerializedSize ();
+  size += m_htCapability.GetSerializedSize();
   size += m_rates.extended.GetSerializedSize ();
   return size;
 }
@@ -297,7 +336,8 @@
 MgtAssocRequestHeader::Print (std::ostream &os) const
 {
   os << "ssid=" << m_ssid << ", "
-     << "rates=" << m_rates;
+     << "rates=" << m_rates<< ", "
+     << "HT Capabilities=" << m_htCapability;
 }
 void
 MgtAssocRequestHeader::Serialize (Buffer::Iterator start) const
@@ -308,6 +348,7 @@
   i = m_ssid.Serialize (i);
   i = m_rates.Serialize (i);
   i = m_rates.extended.Serialize (i);
+  i = m_htCapability.Serialize(i);
 }
 uint32_t
 MgtAssocRequestHeader::Deserialize (Buffer::Iterator start)
@@ -318,6 +359,7 @@
   i = m_ssid.Deserialize (i);
   i = m_rates.Deserialize (i);
   i = m_rates.extended.DeserializeIfPresent (i);
+  i = m_htCapability.DeserializeIfPresent (i);
   return i.GetDistanceFrom (start);
 }
 
@@ -355,7 +397,17 @@
 {
   m_rates = rates;
 }
+void 
+MgtAssocResponseHeader::SetHtCapabilities(HtCapabilities htcapabilities)
+{
+  m_htCapability=htcapabilities;
+}
 
+HtCapabilities 
+MgtAssocResponseHeader::GetHtCapabilities (void) const
+{
+   return  m_htCapability;
+}
 TypeId
 MgtAssocResponseHeader::GetTypeId (void)
 {
@@ -379,6 +431,7 @@
   size += 2; // aid
   size += m_rates.GetSerializedSize ();
   size += m_rates.extended.GetSerializedSize ();
+size += m_htCapability.GetSerializedSize();
   return size;
 }
 
@@ -386,7 +439,8 @@
 MgtAssocResponseHeader::Print (std::ostream &os) const
 {
   os << "status code=" << m_code << ", "
-     << "rates=" << m_rates;
+     << "rates=" << m_rates << ", "
+  << "HT Capabilities=" << m_htCapability;
 }
 void
 MgtAssocResponseHeader::Serialize (Buffer::Iterator start) const
@@ -397,6 +451,7 @@
   i.WriteHtolsbU16 (m_aid);
   i = m_rates.Serialize (i);
   i = m_rates.extended.Serialize (i);
+ i = m_htCapability.Serialize(i);
 }
 uint32_t
 MgtAssocResponseHeader::Deserialize (Buffer::Iterator start)
@@ -407,6 +462,7 @@
   m_aid = i.ReadLsbtohU16 ();
   i = m_rates.Deserialize (i);
   i = m_rates.extended.DeserializeIfPresent (i);
+ i = m_htCapability.DeserializeIfPresent (i);
   return i.GetDistanceFrom (start);
 }
 /**********************************************************
--- a/src/wifi/model/mgt-headers.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/mgt-headers.h	Tue Aug 13 22:05:25 2013 -0700
@@ -29,6 +29,7 @@
 #include "capability-information.h"
 #include "supported-rates.h"
 #include "ssid.h"
+#include "ht-capabilities.h"
 
 namespace ns3 {
 
@@ -45,7 +46,9 @@
   void SetSsid (Ssid ssid);
   void SetSupportedRates (SupportedRates rates);
   void SetListenInterval (uint16_t interval);
-
+  void SetHtCapabilities(HtCapabilities htcapabilities);
+  
+  HtCapabilities GetHtCapabilities (void) const;
   Ssid GetSsid (void) const;
   SupportedRates GetSupportedRates (void) const;
   uint16_t GetListenInterval (void) const;
@@ -61,6 +64,7 @@
   Ssid m_ssid;
   SupportedRates m_rates;
   CapabilityInformation m_capability;
+  HtCapabilities m_htCapability;
   uint16_t m_listenInterval;
 };
 
@@ -77,7 +81,9 @@
 
   StatusCode GetStatusCode (void);
   SupportedRates GetSupportedRates (void);
+  HtCapabilities GetHtCapabilities (void) const;
 
+  void SetHtCapabilities(HtCapabilities htcapabilities);
   void SetSupportedRates (SupportedRates rates);
   void SetStatusCode (StatusCode code);
 
@@ -93,6 +99,7 @@
   CapabilityInformation m_capability;
   StatusCode m_code;
   uint16_t m_aid;
+  HtCapabilities m_htCapability;
 };
 
 
@@ -109,7 +116,9 @@
   void SetSupportedRates (SupportedRates rates);
   Ssid GetSsid (void) const;
   SupportedRates GetSupportedRates (void) const;
+ HtCapabilities GetHtCapabilities (void) const;
 
+  void SetHtCapabilities(HtCapabilities htcapabilities);
   static TypeId GetTypeId (void);
   virtual TypeId GetInstanceTypeId (void) const;
   virtual void Print (std::ostream &os) const;
@@ -119,6 +128,7 @@
 private:
   Ssid m_ssid;
   SupportedRates m_rates;
+  HtCapabilities m_htCapability;
 };
 
 
@@ -135,7 +145,9 @@
   Ssid GetSsid (void) const;
   uint64_t GetBeaconIntervalUs (void) const;
   SupportedRates GetSupportedRates (void) const;
+ HtCapabilities GetHtCapabilities (void) const;
 
+  void SetHtCapabilities(HtCapabilities htcapabilities);
   void SetSsid (Ssid ssid);
   void SetBeaconIntervalUs (uint64_t us);
   void SetSupportedRates (SupportedRates rates);
@@ -153,6 +165,7 @@
   uint64_t m_beaconInterval;
   SupportedRates m_rates;
   CapabilityInformation m_capability;
+  HtCapabilities m_htCapability;
 };
 
 
--- a/src/wifi/model/minstrel-wifi-manager.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/minstrel-wifi-manager.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -38,6 +38,8 @@
 #include "ns3/assert.h"
 #include <vector>
 
+#define Min(a,b) ((a < b) ? a : b)
+
 NS_LOG_COMPONENT_DEFINE ("MinstrelWifiManager");
 
 
@@ -136,7 +138,9 @@
   for (uint32_t i = 0; i < nModes; i++)
     {
       WifiMode mode = phy->GetMode (i);
-      AddCalcTxTime (mode, phy->CalculateTxDuration (m_pktLen, mode, WIFI_PREAMBLE_LONG));
+      WifiTxVector txVector;
+      txVector.SetMode(mode);
+      AddCalcTxTime (mode, phy->CalculateTxDuration (m_pktLen, txVector, WIFI_PREAMBLE_LONG));
     }
   WifiRemoteStationManager::SetupPhy (phy);
 }
@@ -435,8 +439,8 @@
   station->m_longRetry = 0;
 }
 
-WifiMode
-MinstrelWifiManager::DoGetDataMode (WifiRemoteStation *st,
+WifiTxVector
+MinstrelWifiManager::DoGetDataTxVector (WifiRemoteStation *st,
                                     uint32_t size)
 {
   MinstrelWifiRemoteStation *station = (MinstrelWifiRemoteStation *) st;
@@ -448,16 +452,16 @@
       station->m_txrate = m_nsupported / 2;
     }
   UpdateStats (station);
-  return GetSupported (station, station->m_txrate);
+  return WifiTxVector (GetSupported (station, station->m_txrate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (station), GetStbc (station));
 }
 
-WifiMode
-MinstrelWifiManager::DoGetRtsMode (WifiRemoteStation *st)
+WifiTxVector
+MinstrelWifiManager::DoGetRtsTxVector (WifiRemoteStation *st)
 {
   MinstrelWifiRemoteStation *station = (MinstrelWifiRemoteStation *) st;
   NS_LOG_DEBUG ("DoGetRtsMode m_txrate=" << station->m_txrate);
 
-  return GetSupported (station, 0);
+  return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (station), GetStbc (station));
 }
 
 bool
--- a/src/wifi/model/minstrel-wifi-manager.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/minstrel-wifi-manager.h	Tue Aug 13 22:05:25 2013 -0700
@@ -117,8 +117,8 @@
                                double ackSnr, WifiMode ackMode, double dataSnr);
   virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
   virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
-  virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
-  virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
+ virtual WifiTxVector DoGetDataTxVector (WifiRemoteStation *station, uint32_t size);
+  virtual WifiTxVector DoGetRtsTxVector (WifiRemoteStation *station);
   virtual bool IsLowLatency (void) const;
 
   /// for estimating the TxTime of a packet with a given mode
--- a/src/wifi/model/nist-error-rate-model.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/nist-error-rate-model.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -193,7 +193,7 @@
 NistErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const
 {
   if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM
-      || mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM)
+      || mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM|| mode.GetModulationClass()==WIFI_MOD_CLASS_HT)
     {
       if (mode.GetConstellationSize () == 2)
         {
--- a/src/wifi/model/onoe-wifi-manager.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/onoe-wifi-manager.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -23,6 +23,8 @@
 #include "ns3/log.h"
 #include "ns3/uinteger.h"
 
+#define Min(a,b) ((a < b) ? a : b)
+
 NS_LOG_COMPONENT_DEFINE ("OnoeWifiRemoteStation");
 
 namespace ns3 {
@@ -215,8 +217,8 @@
 
 }
 
-WifiMode
-OnoeWifiManager::DoGetDataMode (WifiRemoteStation *st,
+WifiTxVector
+OnoeWifiManager::DoGetDataTxVector (WifiRemoteStation *st,
                                 uint32_t size)
 {
   OnoeWifiRemoteStation *station = (OnoeWifiRemoteStation *)st;
@@ -260,15 +262,15 @@
           rateIndex = station->m_txrate;
         }
     }
-  return GetSupported (station, rateIndex);
+  return WifiTxVector (GetSupported (station, rateIndex), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (station), GetStbc (station));
 }
-WifiMode
-OnoeWifiManager::DoGetRtsMode (WifiRemoteStation *st)
+WifiTxVector
+OnoeWifiManager::DoGetRtsTxVector (WifiRemoteStation *st)
 {
   OnoeWifiRemoteStation *station = (OnoeWifiRemoteStation *)st;
   UpdateMode (station);
   /// \todo can we implement something smarter ?
-  return GetSupported (station, 0);
+  return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (station), GetStbc (station));
 }
 
 bool
--- a/src/wifi/model/onoe-wifi-manager.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/onoe-wifi-manager.h	Tue Aug 13 22:05:25 2013 -0700
@@ -58,8 +58,8 @@
                                double ackSnr, WifiMode ackMode, double dataSnr);
   virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
   virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
-  virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
-  virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
+  virtual WifiTxVector DoGetDataTxVector (WifiRemoteStation *station, uint32_t size);
+  virtual WifiTxVector DoGetRtsTxVector (WifiRemoteStation *station);
   virtual bool IsLowLatency (void) const;
 
   void UpdateRetry (OnoeWifiRemoteStation *station);
--- a/src/wifi/model/regular-wifi-mac.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/regular-wifi-mac.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -120,6 +120,7 @@
 {
   NS_LOG_FUNCTION (this << stationManager);
   m_stationManager = stationManager;
+  m_stationManager->SetHtSupported (GetHtSupported());
   m_low->SetWifiRemoteStationManager (stationManager);
 
   m_dca->SetWifiRemoteStationManager (stationManager);
@@ -244,6 +245,30 @@
 {
   return m_qosSupported;
 }
+void
+RegularWifiMac::SetHtSupported (bool enable)
+{
+  NS_LOG_FUNCTION (this);
+  m_htSupported = enable;
+}
+
+bool
+RegularWifiMac::GetHtSupported () const
+{
+  return m_htSupported;
+}
+void
+RegularWifiMac::SetCtsToSelfSupported(bool enable)
+{
+  NS_LOG_FUNCTION (this);
+  m_low->SetCtsToSelfSupported (enable);
+}
+
+bool
+RegularWifiMac::GetCtsToSelfSupported () const
+{
+   return  m_low->GetCtsToSelfSupported ();
+}
 
 void
 RegularWifiMac::SetSlot (Time slotTime)
@@ -285,6 +310,18 @@
 {
   return m_dcfManager->GetEifsNoDifs ();
 }
+void
+RegularWifiMac::SetRifs (Time rifs)
+{
+  NS_LOG_FUNCTION (this << rifs);
+  m_low->SetRifs (rifs);
+}
+
+Time
+RegularWifiMac::GetRifs (void) const
+{
+  return m_low->GetRifs();
+}
 
 void
 RegularWifiMac::SetPifs (Time pifs)
@@ -609,6 +646,18 @@
                    MakeBooleanAccessor (&RegularWifiMac::SetQosSupported,
                                         &RegularWifiMac::GetQosSupported),
                    MakeBooleanChecker ())
+    .AddAttribute ("HtSupported",
+                   "This Boolean attribute is set to enable 802.11n support at this STA",
+                   BooleanValue (false),
+                   MakeBooleanAccessor (&RegularWifiMac::SetHtSupported,
+                                        &RegularWifiMac::GetHtSupported),
+                   MakeBooleanChecker ())
+   .AddAttribute ("CtsToSelfSupported",
+                   "Use CTS to Self when using a rate that is not in the basic set rate",
+                   BooleanValue (false),
+                   MakeBooleanAccessor (&RegularWifiMac::SetCtsToSelfSupported,
+                                        &RegularWifiMac::GetCtsToSelfSupported),
+                    MakeBooleanChecker ())
     .AddAttribute ("DcaTxop", "The DcaTxop object",
                    PointerValue (),
                    MakePointerAccessor (&RegularWifiMac::GetDcaTxop),
@@ -663,6 +712,8 @@
     case WIFI_PHY_STANDARD_80211g:
     case WIFI_PHY_STANDARD_80211_10MHZ:
     case WIFI_PHY_STANDARD_80211_5MHZ:
+    case WIFI_PHY_STANDARD_80211n_5GHZ:
+    case WIFI_PHY_STANDARD_80211n_2_4GHZ:
       cwmin = 15;
       cwmax = 1023;
       break;
--- a/src/wifi/model/regular-wifi-mac.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/regular-wifi-mac.h	Tue Aug 13 22:05:25 2013 -0700
@@ -74,6 +74,8 @@
    * \param pifs the pifs duration.
    */
   void SetPifs (Time pifs);
+
+  void SetRifs (Time rifs);
   /**
    * \param ctsTimeout the duration of a CTS timeout.
    */
@@ -82,6 +84,8 @@
    * \param ackTimeout the duration of an ACK timeout.
    */
   void SetAckTimeout (Time ackTimeout);
+
+  Time GetRifs (void) const;
   /**
    * \returns the current PIFS duration.
    */
@@ -106,6 +110,10 @@
    * \returns the current ACK timeout duration.
    */
   Time GetAckTimeout (void) const;
+
+  void SetCtsToSelfSupported (bool enable);
+ 
+  bool GetCtsToSelfSupported () const;
   /**
    * \returns the MAC address associated to this MAC layer.
    */
@@ -321,6 +329,26 @@
   void SetQosSupported (bool enable);
   /** Get accessor for the \c m_qosSupported member */
   bool GetQosSupported () const;
+
+ /**
+   * This Boolean is set \c true iff this WifiMac is to model
+   * 802.11n. It is exposed through the
+   * attribute system.
+   *
+   * At the moment, this flag is the sole selection between HT and
+   * non-HT operation for the STA (whether IBSS, AP, or
+   * non-AP). Ultimately, we will want a HT-enabled STA to be able to
+   * fall back to non-HT operation with a non-HT peer. This'll
+   * require further intelligence - i.e., per-association HT
+   * state. Having a big switch seems like a good intermediate stage,
+   * however.
+   */
+  bool m_htSupported;
+  /** Set accessor for the \c m_htSupported member */
+  void SetHtSupported (bool enable);
+  /** Get accessor for the \c m_htSupported member */
+  bool GetHtSupported () const;
+
 private:
   RegularWifiMac (const RegularWifiMac &);
   RegularWifiMac & operator= (const RegularWifiMac &);
--- a/src/wifi/model/rraa-wifi-manager.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/rraa-wifi-manager.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -26,6 +26,8 @@
 #include "ns3/uinteger.h"
 #include "ns3/simulator.h"
 
+#define Min(a,b) ((a < b) ? a : b)
+
 NS_LOG_COMPONENT_DEFINE ("RraaWifiManager");
 
 namespace ns3 {
@@ -267,8 +269,8 @@
 {
 }
 
-WifiMode
-RraaWifiManager::DoGetDataMode (WifiRemoteStation *st,
+WifiTxVector
+RraaWifiManager::DoGetDataTxVector (WifiRemoteStation *st,
                                 uint32_t size)
 {
   RraaWifiRemoteStation *station = (RraaWifiRemoteStation *) st;
@@ -276,12 +278,12 @@
     {
       ResetCountersBasic (station);
     }
-  return GetSupported (station, station->m_rate);
+  return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (station), GetStbc (station));
 }
-WifiMode
-RraaWifiManager::DoGetRtsMode (WifiRemoteStation *st)
+WifiTxVector
+RraaWifiManager::DoGetRtsTxVector (WifiRemoteStation *st)
 {
-  return GetSupported (st, 0);
+  return WifiTxVector (GetSupported (st, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (st), GetShortGuardInterval (st), Min (GetNumberOfReceiveAntennas (st),GetNumberOfTransmitAntennas()), GetNumberOfTransmitAntennas (st), GetStbc (st));
 }
 
 bool
--- a/src/wifi/model/rraa-wifi-manager.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/rraa-wifi-manager.h	Tue Aug 13 22:05:25 2013 -0700
@@ -65,8 +65,8 @@
                                double ackSnr, WifiMode ackMode, double dataSnr);
   virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
   virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
-  virtual WifiMode DoGetDataMode (WifiRemoteStation *station, uint32_t size);
-  virtual WifiMode DoGetRtsMode (WifiRemoteStation *station);
+  virtual WifiTxVector DoGetDataTxVector (WifiRemoteStation *station, uint32_t size);
+  virtual WifiTxVector DoGetRtsTxVector (WifiRemoteStation *station);
   virtual bool DoNeedRts (WifiRemoteStation *st,
                           Ptr<const Packet> packet, bool normally);
   virtual bool IsLowLatency (void) const;
--- a/src/wifi/model/sta-wifi-mac.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/sta-wifi-mac.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -37,6 +37,7 @@
 #include "msdu-aggregator.h"
 #include "amsdu-subframe-header.h"
 #include "mgt-headers.h"
+#include "ht-capabilities.h"
 
 NS_LOG_COMPONENT_DEFINE ("StaWifiMac");
 
@@ -168,6 +169,12 @@
   MgtProbeRequestHeader probe;
   probe.SetSsid (GetSsid ());
   probe.SetSupportedRates (GetSupportedRates ());
+  if (m_htSupported)
+    {
+      probe.SetHtCapabilities (GetHtCapabilities());
+      hdr.SetNoOrder();
+    }
+
   packet->AddHeader (probe);
 
   // The standard is not clear on the correct queue for management
@@ -195,6 +202,12 @@
   MgtAssocRequestHeader assoc;
   assoc.SetSsid (GetSsid ());
   assoc.SetSupportedRates (GetSupportedRates ());
+  if (m_htSupported)
+    {
+      assoc.SetHtCapabilities (GetHtCapabilities());
+      hdr.SetNoOrder();
+    }
+
   packet->AddHeader (assoc);
 
   // The standard is not clear on the correct queue for management
@@ -351,6 +364,10 @@
     {
       hdr.SetTypeData ();
     }
+if (m_htSupported)
+    {
+      hdr.SetNoOrder();
+    }
 
   hdr.SetAddr1 (GetBssid ());
   hdr.SetAddr2 (m_low->GetAddress ());
@@ -444,6 +461,15 @@
         {
           goodBeacon = true;
         }
+      SupportedRates rates = beacon.GetSupportedRates ();
+      for (uint32_t i = 0; i < m_phy->GetNBssMembershipSelectors (); i++)
+        {
+           uint32_t selector = m_phy->GetBssMembershipSelector (i);
+           if (!rates.IsSupportedRate (selector))
+             {
+                goodBeacon = false;
+             }
+         }
       if ((IsWaitAssocResp () || IsAssociated ()) && hdr->GetAddr3 () != GetBssid ())
         {
           goodBeacon = false;
@@ -472,6 +498,15 @@
               //not a probe resp for our ssid.
               return;
             }
+          SupportedRates rates = probeResp.GetSupportedRates ();
+          for (uint32_t i = 0; i < m_phy->GetNBssMembershipSelectors (); i++)
+            {
+             uint32_t selector = m_phy->GetBssMembershipSelector (i);
+             if (!rates.IsSupportedRate (selector))
+               {
+                 return;
+               }
+            }
           SetBssid (hdr->GetAddr3 ());
           Time delay = MicroSeconds (probeResp.GetBeaconIntervalUs () * m_maxMissedBeacons);
           RestartBeaconWatchdog (delay);
@@ -499,6 +534,12 @@
               SetState (ASSOCIATED);
               NS_LOG_DEBUG ("assoc completed");
               SupportedRates rates = assocResp.GetSupportedRates ();
+              if (m_htSupported)
+                {
+                  HtCapabilities htcapabilities = assocResp.GetHtCapabilities ();
+                  m_stationManager->AddStationHtCapabilities (hdr->GetAddr2 (),htcapabilities);
+                }
+
               for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
                 {
                   WifiMode mode = m_phy->GetMode (i);
@@ -511,6 +552,19 @@
                         }
                     }
                 }
+              if(m_htSupported)
+                {
+                  HtCapabilities htcapabilities = assocResp.GetHtCapabilities ();
+                  for (uint32_t i = 0; i < m_phy->GetNMcs(); i++)
+                    {
+                       uint8_t mcs=m_phy->GetMcs(i);
+                       if (htcapabilities.IsSupportedMcs (mcs))
+                         {
+                           m_stationManager->AddSupportedMcs (hdr->GetAddr2 (), mcs);
+                          //here should add a control to add basic MCS when it is implemented
+                         }
+                    }
+                }
               if (!m_linkUp.IsNull ())
                 {
                   m_linkUp ();
@@ -535,6 +589,13 @@
 StaWifiMac::GetSupportedRates (void) const
 {
   SupportedRates rates;
+  if(m_htSupported)
+    {
+      for (uint32_t i = 0; i < m_phy->GetNBssMembershipSelectors(); i++)
+        {
+          rates.SetBasicRate(m_phy->GetBssMembershipSelector(i));
+        }
+    }
   for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
     {
       WifiMode mode = m_phy->GetMode (i);
@@ -542,7 +603,20 @@
     }
   return rates;
 }
-
+HtCapabilities
+StaWifiMac::GetHtCapabilities (void) const
+{
+ HtCapabilities capabilities;
+ capabilities.SetHtSupported(1);
+ capabilities.SetLdpc (m_phy->GetLdpc());
+ capabilities.SetShortGuardInterval20 (m_phy->GetGuardInterval());
+ capabilities.SetGreenfield (m_phy->GetGreenfield());
+for (uint8_t i =0 ; i < m_phy->GetNMcs();i++)
+  {
+     capabilities.SetRxMcsBitmask(m_phy->GetMcs(i));
+  }
+ return capabilities;
+}
 void
 StaWifiMac::SetState (MacState value)
 {
--- a/src/wifi/model/sta-wifi-mac.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/sta-wifi-mac.h	Tue Aug 13 22:05:25 2013 -0700
@@ -108,6 +108,9 @@
   SupportedRates GetSupportedRates (void) const;
   void SetState (enum MacState value);
 
+  HtCapabilities GetHtCapabilities (void) const;
+
+
   enum MacState m_state;
   Time m_probeRequestTimeout;
   Time m_assocRequestTimeout;
--- a/src/wifi/model/supported-rates.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/supported-rates.h	Tue Aug 13 22:05:25 2013 -0700
@@ -29,11 +29,11 @@
 
 /**
  * This defines the maximum number of supported rates that a STA is
- * allowed to have. Currently this number is set for IEEE 802.11b/g
+ * allowed to have. Currently this number is set for IEEE 802.11b/g and SISO IEE 802.11n
  * stations which need 2 rates each from Clauses 15 and 18, and then 8
  * from Clause 19.
  */
-#define MAX_SUPPORTED_RATES (12)
+#define MAX_SUPPORTED_RATES (32)
 
 class SupportedRates;
 
--- a/src/wifi/model/wifi-information-element.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/wifi-information-element.h	Tue Aug 13 22:05:25 2013 -0700
@@ -77,7 +77,7 @@
 #define IE_ERP_INFORMATION                     ((WifiInformationElementId)42)
 #define IE_TS_DELAY                            ((WifiInformationElementId)43)
 #define IE_TCLAS_PROCESSING                    ((WifiInformationElementId)44)
-// 45 is reserved in 802.11-2007
+#define IE_HT_CAPABILITIES                     ((WifiInformationElementId)45)
 #define IE_QOS_CAPABILITY                      ((WifiInformationElementId)46)
 // 47 is reserved in 802.11-2007
 #define IE_RSN                                 ((WifiInformationElementId)48)
--- a/src/wifi/model/wifi-mac-header.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/wifi-mac-header.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -40,7 +40,9 @@
   SUBTYPE_CTL_BACKRESP = 9,
   SUBTYPE_CTL_RTS = 11,
   SUBTYPE_CTL_CTS = 12,
-  SUBTYPE_CTL_ACK = 13
+  SUBTYPE_CTL_ACK = 13,
+  SUBTYPE_CTL_CTLWRAPPER=7
+
 };
 
 WifiMacHeader::WifiMacHeader ()
@@ -182,6 +184,10 @@
       m_ctrlType = TYPE_CTL;
       m_ctrlSubtype = SUBTYPE_CTL_ACK;
       break;
+    case WIFI_MAC_CTL_CTLWRAPPER: 
+      m_ctrlType = TYPE_CTL;
+      m_ctrlSubtype = SUBTYPE_CTL_CTLWRAPPER;
+      break;
     case WIFI_MAC_MGT_ASSOCIATION_REQUEST:
       m_ctrlType = TYPE_MGT;
       m_ctrlSubtype = 0;
@@ -332,6 +338,14 @@
 {
   m_ctrlMoreFrag = 1;
 }
+void WifiMacHeader::SetOrder (void)
+{
+  m_ctrlOrder = 1;
+}
+void WifiMacHeader::SetNoOrder (void)
+{
+  m_ctrlOrder = 0;
+}
 void WifiMacHeader::SetRetry (void)
 {
   m_ctrlRetry = 1;
@@ -865,6 +879,9 @@
         case SUBTYPE_CTL_BACKRESP:
           size = 2 + 2 + 6 + 6;
           break;
+        case SUBTYPE_CTL_CTLWRAPPER:
+          size = 2 +2 +6 +2 +4;
+          break;
         }
       break;
     case TYPE_DATA:
@@ -978,6 +995,8 @@
       break;
     case WIFI_MAC_CTL_BACKRESP:
       break;
+    case WIFI_MAC_CTL_CTLWRAPPER:
+      break;
 
     case WIFI_MAC_MGT_BEACON:
     case WIFI_MAC_MGT_ASSOCIATION_REQUEST:
--- a/src/wifi/model/wifi-mac-header.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/wifi-mac-header.h	Tue Aug 13 22:05:25 2013 -0700
@@ -36,6 +36,7 @@
   WIFI_MAC_CTL_ACK,
   WIFI_MAC_CTL_BACKREQ,
   WIFI_MAC_CTL_BACKRESP,
+  WIFI_MAC_CTL_CTLWRAPPER,
 
   WIFI_MAC_MGT_BEACON,
   WIFI_MAC_MGT_ASSOCIATION_REQUEST,
@@ -141,7 +142,8 @@
   void SetQosAmsdu (void);
   void SetQosNoAmsdu (void);
   void SetQosTxopLimit (uint8_t txop);
-
+  void SetOrder (void);
+  void SetNoOrder (void);
 
   Mac48Address GetAddr1 (void) const;
   Mac48Address GetAddr2 (void) const;
--- a/src/wifi/model/wifi-mac.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/wifi-mac.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -44,6 +44,12 @@
   // 802.11-a specific
   return MicroSeconds (16);
 }
+Time 
+WifiMac::GetDefaultRifs (void)
+{
+  //802.11n specific
+  return MicroSeconds (2);
+}
 Time
 WifiMac::GetDefaultEifsNoDifs (void)
 {
@@ -78,8 +84,9 @@
 Time
 WifiMac::GetDefaultCompressedBlockAckDelay (void)
 {
-  // This value must be rivisited
-  return MicroSeconds (68);
+  // This value must be rivisited was 68. 
+ //CompressedBlockAckSize 32* 8*time it takes to transfer at the lowest rate (6Mb/s)+ aPhy-StartDelay(33)
+  return MicroSeconds (76);
 }
 Time
 WifiMac::GetDefaultBasicBlockAckTimeout (void)
@@ -171,6 +178,12 @@
                    MakeTimeAccessor (&WifiMac::SetPifs,
                                      &WifiMac::GetPifs),
                    MakeTimeChecker ())
+.AddAttribute ("Rifs", "The value of the RIFS constant.",
+                   TimeValue (GetDefaultRifs ()),
+                   MakeTimeAccessor (&WifiMac::SetRifs,
+                                     &WifiMac::GetRifs),
+                   MakeTimeChecker ())
+
     .AddAttribute ("MaxPropagationDelay", "The maximum propagation delay. Unused for now.",
                    TimeValue (GetDefaultMaxPropagationDelay ()),
                    MakeTimeAccessor (&WifiMac::m_maxPropagationDelay),
@@ -286,6 +299,12 @@
     case WIFI_PHY_STANDARD_80211p_SCH:
       Configure80211p_SCH ();
       break;
+    case WIFI_PHY_STANDARD_80211n_2_4GHZ:
+      Configure80211n_2_4Ghz ();
+      break;
+    case WIFI_PHY_STANDARD_80211n_5GHZ:
+      Configure80211n_5Ghz ();
+      break;
     default:
       NS_ASSERT (false);
       break;
@@ -360,6 +379,22 @@
 {
   Configure80211_10Mhz ();
 }
+void
+WifiMac::Configure80211n_2_4Ghz (void)
+{
+  Configure80211g ();
+  SetRifs(MicroSeconds (2));
+  SetCtsTimeout (MicroSeconds (10 + 52 + 20 + GetDefaultMaxPropagationDelay ().GetMicroSeconds () * 2));
+  SetAckTimeout (MicroSeconds (10 + 52 + 20 + GetDefaultMaxPropagationDelay ().GetMicroSeconds () * 2));
+}
+void
+WifiMac::Configure80211n_5Ghz (void)
+{
+  Configure80211a ();
+  SetRifs(MicroSeconds (2));
+  SetCtsTimeout (MicroSeconds (10 + 52 + 20 + GetDefaultMaxPropagationDelay ().GetMicroSeconds () * 2));
+  SetAckTimeout (MicroSeconds (10 + 52 + 20 + GetDefaultMaxPropagationDelay ().GetMicroSeconds () * 2));
+}
 
 void
 WifiMac::ConfigureDcf (Ptr<Dcf> dcf, uint32_t cwmin, uint32_t cwmax, enum AcIndex ac)
--- a/src/wifi/model/wifi-mac.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/wifi-mac.h	Tue Aug 13 22:05:25 2013 -0700
@@ -65,6 +65,11 @@
    * \param pifs the pifs duration.
    */
   virtual void SetPifs (Time pifs) = 0;
+/**
+   * \param rifs the rifs duration.
+   */
+
+  virtual void SetRifs (Time rifs) = 0;
   /**
    * \param ctsTimeout the duration of a CTS timeout.
    */
@@ -79,6 +84,11 @@
    * Unused for now.
    */
   void SetMaxPropagationDelay (Time delay);
+/**
+   * \returns the current RIFS duration.
+   */
+
+  virtual Time GetRifs (void) const = 0;
 
   /**
    * \returns the current PIFS duration.
@@ -233,6 +243,7 @@
   static Time GetDefaultMaxPropagationDelay (void);
   static Time GetDefaultSlot (void);
   static Time GetDefaultSifs (void);
+  static Time GetDefaultRifs (void);
   static Time GetDefaultEifsNoDifs (void);
   static Time GetDefaultCtsAckDelay (void);
   static Time GetDefaultCtsAckTimeout (void);
@@ -259,6 +270,8 @@
   void Configure80211_5Mhz ();
   void Configure80211p_CCH (void);
   void Configure80211p_SCH (void);
+  void Configure80211n_2_4Ghz (void);
+  void Configure80211n_5Ghz (void);
 
   /**
    * The trace source fired when packets come into the "top" of the device
--- a/src/wifi/model/wifi-mode.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/wifi-mode.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -139,6 +139,9 @@
 
   switch (codingRate)
     {
+    case WIFI_CODE_RATE_5_6:
+      item->phyRate = dataRate * 6 / 5;
+      break;
     case WIFI_CODE_RATE_3_4:
       item->phyRate = dataRate * 4 / 3;
       break;
--- a/src/wifi/model/wifi-mode.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/wifi-mode.h	Tue Aug 13 22:05:25 2013 -0700
@@ -73,7 +73,10 @@
   /** Rate 2/3 */
   WIFI_CODE_RATE_2_3,
   /** Rate 1/2 */
-  WIFI_CODE_RATE_1_2
+  WIFI_CODE_RATE_1_2,
+ /** Rate 5/6 */
+ WIFI_CODE_RATE_5_6
+
 };
 
 /**
@@ -174,6 +177,9 @@
 typedef std::vector<WifiMode> WifiModeList;
 typedef WifiModeList::const_iterator WifiModeListIterator;
 
+typedef std::vector<uint8_t> WifiMcsList;
+typedef WifiMcsList::const_iterator WifiMcsListIterator;
+
 /**
  * \brief create WifiMode class instances and keep track of them.
  *
--- a/src/wifi/model/wifi-phy-standard.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/wifi-phy-standard.h	Tue Aug 13 22:05:25 2013 -0700
@@ -48,7 +48,11 @@
   /** \deprecated see <A HREF="http://www.nsnam.org/bugzilla/show_bug.cgi?id=945">bug 945</A> */
   WIFI_PHY_STANDARD_80211p_CCH,
   /** \deprecated see <A HREF="http://www.nsnam.org/bugzilla/show_bug.cgi?id=945">bug 945</A> */
-  WIFI_PHY_STANDARD_80211p_SCH
+  WIFI_PHY_STANDARD_80211p_SCH,
+  // 11n support
+  WIFI_PHY_STANDARD_80211n_2_4GHZ,
+  // needed for different mac parameters
+  WIFI_PHY_STANDARD_80211n_5GHZ
 };
 
 } // namespace ns3
--- a/src/wifi/model/wifi-phy.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/wifi-phy.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -93,6 +93,56 @@
   NS_LOG_FUNCTION (this);
 }
 
+//Added by Ghada to support 11n
+
+//return the L-SIG
+WifiMode
+WifiPhy::GetMFPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble)
+{
+    switch (payloadMode.GetBandwidth ())
+       {
+       case 20000000:
+          return WifiPhy::GetOfdmRate6_5MbpsBW20MHz ();
+        case 40000000:
+           return WifiPhy::GetOfdmRate13_5MbpsBW40MHz ();
+        default:
+            return WifiPhy::GetOfdmRate6_5MbpsBW20MHz ();
+      }
+}
+uint32_t
+WifiPhy::GetPlcpHtTrainingSymbolDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble, WifiTxVector txvector)
+{
+   switch (preamble)
+     {
+     case WIFI_PREAMBLE_HT_MF:
+        return 4+ (4* txvector.GetNss());
+     case WIFI_PREAMBLE_HT_GF:
+         return (4*txvector.GetNss())+(4*txvector.GetNess());
+      default:
+         // no training for non HT
+          return 0;
+      }
+}
+
+//return L-SIG
+uint32_t
+WifiPhy::GetPlcpHtSigHeaderDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble)
+{
+         switch (preamble)
+            {
+             case WIFI_PREAMBLE_HT_MF:
+               // HT-SIG
+               return 8;
+             case WIFI_PREAMBLE_HT_GF:
+               //HT-SIG
+               return 8;
+             default:
+               // no HT-SIG for non HT
+               return 0;
+            }
+
+}
+//end added by Ghada
 
 WifiMode
 WifiPhy::GetPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble)
@@ -115,7 +165,36 @@
             return WifiPhy::GetOfdmRate6Mbps ();
           }
       }
-
+    //Added by Ghada to support 11n
+    case WIFI_MOD_CLASS_HT:
+      {  //return the HT-SIG
+         // IEEE Std 802.11n, 20.3.23
+         switch (preamble)
+           {
+            case WIFI_PREAMBLE_HT_MF:
+                switch (payloadMode.GetBandwidth ())
+                  {
+                   case 20000000:
+                      return WifiPhy::GetOfdmRate13MbpsBW20MHz ();
+                   case 40000000:
+                      return WifiPhy::GetOfdmRate27MbpsBW40MHz ();
+                   default:
+                      return WifiPhy::GetOfdmRate13MbpsBW20MHz ();
+                  }
+            case WIFI_PREAMBLE_HT_GF:
+                  switch (payloadMode.GetBandwidth ())
+                  {
+                   case 20000000:
+                      return WifiPhy::GetOfdmRate13MbpsBW20MHz ();
+                   case 40000000:
+                      return WifiPhy::GetOfdmRate27MbpsBW40MHz ();
+                   default:
+                      return WifiPhy::GetOfdmRate13MbpsBW20MHz ();
+                  }
+             default:
+                return WifiPhy::GetOfdmRate6Mbps ();
+          }
+      }
     case WIFI_MOD_CLASS_ERP_OFDM:
       return WifiPhy::GetErpOfdmRate6Mbps ();
 
@@ -137,6 +216,7 @@
     }
 }
 
+
 uint32_t
 WifiPhy::GetPlcpHeaderDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble)
 {
@@ -163,7 +243,22 @@
             return 16;
           }
       }
-
+     //Added by Ghada to support 11n
+    case WIFI_MOD_CLASS_HT:
+      { //IEEE 802.11n Figure 20.1
+         switch (preamble)
+            {
+             case WIFI_PREAMBLE_HT_MF:
+               // L-SIG
+               return 4;
+             case WIFI_PREAMBLE_HT_GF:
+               //L-SIG
+               return 0;
+             default:
+               // L-SIG
+               return 4;
+            }
+      }
     case WIFI_MOD_CLASS_ERP_OFDM:
       return 16;
 
@@ -209,7 +304,10 @@
             return 64;
           }
       }
-
+    case WIFI_MOD_CLASS_HT:
+      { //IEEE 802.11n Figure 20.1 the training symbols before L_SIG or HT_SIG
+           return 16;
+      }
     case WIFI_MOD_CLASS_ERP_OFDM:
       return 4;
 
@@ -224,18 +322,19 @@
           // IEEE Std 802.11-2007, sections 18.2.2.1 and figure 18-1
           return 144;
         }
-
     default:
       NS_FATAL_ERROR ("unsupported modulation class");
       return 0;
     }
 }
 
-uint32_t
-WifiPhy::GetPayloadDurationMicroSeconds (uint32_t size, WifiMode payloadMode)
+double
+WifiPhy::GetPayloadDurationMicroSeconds (uint32_t size, WifiTxVector txvector)
 {
+  WifiMode payloadMode=txvector.GetMode();
+
   NS_LOG_FUNCTION (size << payloadMode);
-
+ 
   switch (payloadMode.GetModulationClass ())
     {
     case WIFI_MOD_CLASS_OFDM:
@@ -261,10 +360,10 @@
 
         // IEEE Std 802.11-2007, section 17.3.2.2, table 17-3
         // corresponds to N_{DBPS} in the table
-        double numDataBitsPerSymbol = payloadMode.GetDataRate ()  * symbolDurationUs / 1e6;
+        double numDataBitsPerSymbol = payloadMode.GetDataRate () * symbolDurationUs / 1e6;
 
         // IEEE Std 802.11-2007, section 17.3.5.3, equation (17-11)
-        uint32_t numSymbols = lrint (std::ceil ((16 + size * 8.0 + 6.0) / numDataBitsPerSymbol));
+        uint32_t numSymbols = lrint (ceil ((16 + size * 8.0 + 6.0) / numDataBitsPerSymbol));
 
         // Add signal extension for ERP PHY
         if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
@@ -276,13 +375,59 @@
             return numSymbols * symbolDurationUs;
           }
       }
-
+    case WIFI_MOD_CLASS_HT:
+      {
+         double symbolDurationUs;
+         double m_Stbc;
+        //if short GI data rate is used then symbol duration is 3.6us else symbol duration is 4us
+        //In the future has to create a stationmanager that only uses these data rates if sender and reciever support GI
+         if (payloadMode.GetUniqueName() == "OfdmRate135MbpsBW40MHzShGi" || payloadMode.GetUniqueName() == "OfdmRate65MbpsBW20MHzShGi" )
+           {
+             symbolDurationUs=3.6;
+           }
+         else
+           {
+             switch (payloadMode.GetDataRate ()/ (txvector.GetNss()))
+               { //shortGi
+                  case 7200000:
+                  case 14400000:
+                  case 21700000:
+                  case 28900000:
+                  case 43300000:
+                  case 57800000:
+                  case 72200000:
+                  case 15000000:
+                  case 30000000:
+                  case 45000000:
+                  case 60000000:
+                  case 90000000:
+                  case 120000000:
+                  case 150000000:
+                    symbolDurationUs=3.6;
+                    break;               
+                 default:
+                    symbolDurationUs=4;
+              }
+           }
+         if  (txvector.IsStbc())
+            m_Stbc=2;
+         else
+           m_Stbc=1;
+         double numDataBitsPerSymbol = payloadMode.GetDataRate () *txvector.GetNss()  * symbolDurationUs / 1e6;
+         //check tables 20-35 and 20-36 in the standard to get cases when nes =2
+         double Nes=1;
+        // IEEE Std 802.11n, section 20.3.11, equation (20-32)
+        uint32_t numSymbols = lrint (m_Stbc*ceil ((16 + size * 8.0 + 6.0*Nes) / (m_Stbc* numDataBitsPerSymbol)));
+       
+        return numSymbols * symbolDurationUs;
+         
+      }
     case WIFI_MOD_CLASS_DSSS:
       // IEEE Std 802.11-2007, section 18.2.3.5
       NS_LOG_LOGIC (" size=" << size
                              << " mode=" << payloadMode
                              << " rate=" << payloadMode.GetDataRate () );
-      return lrint (std::ceil ((size * 8.0) / (payloadMode.GetDataRate () / 1.0e6)));
+      return lrint (ceil ((size * 8.0) / (payloadMode.GetDataRate () / 1.0e6)));
 
     default:
       NS_FATAL_ERROR ("unsupported modulation class");
@@ -291,15 +436,19 @@
 }
 
 Time
-WifiPhy::CalculateTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble)
+WifiPhy::CalculateTxDuration (uint32_t size, WifiTxVector txvector, WifiPreamble preamble)
 {
-  uint32_t duration = GetPlcpPreambleDurationMicroSeconds (payloadMode, preamble)
+  WifiMode payloadMode=txvector.GetMode();
+  double duration = GetPlcpPreambleDurationMicroSeconds (payloadMode, preamble)
     + GetPlcpHeaderDurationMicroSeconds (payloadMode, preamble)
-    + GetPayloadDurationMicroSeconds (size, payloadMode);
+    + GetPlcpHtSigHeaderDurationMicroSeconds (payloadMode, preamble)
+    + GetPlcpHtTrainingSymbolDurationMicroSeconds (payloadMode, preamble,txvector)
+    + GetPayloadDurationMicroSeconds (size, txvector);
   return MicroSeconds (duration);
 }
 
 
+
 void
 WifiPhy::NotifyTxBegin (Ptr<const Packet> packet)
 {
@@ -343,9 +492,9 @@
 }
 
 void
-WifiPhy::NotifyMonitorSniffTx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble)
+WifiPhy::NotifyMonitorSniffTx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble, uint8_t txPower)
 {
-  m_phyMonitorSniffTxTrace (packet, channelFreqMhz, channelNumber, rate, isShortPreamble);
+  m_phyMonitorSniffTxTrace (packet, channelFreqMhz, channelNumber, rate, isShortPreamble, txPower);
 }
 
 
@@ -835,6 +984,419 @@
   return mode;
 }
 
+/*Clause 20*/
+
+WifiMode
+WifiPhy::GetOfdmRate6_5MbpsBW20MHz ()
+{
+  static WifiMode mode =
+  WifiModeFactory::CreateWifiMode ("OfdmRate6_5MbpsBW20MHz",
+                                    WIFI_MOD_CLASS_HT,
+                                    true,
+                                    20000000, 6500000,
+                                    WIFI_CODE_RATE_1_2,
+                                    2);
+  return mode;
+}
+WifiMode
+WifiPhy::GetOfdmRate7_2MbpsBW20MHz ()
+{
+  static WifiMode mode =
+  WifiModeFactory::CreateWifiMode ("OfdmRate7_2MbpsBW20MHz",
+                                    WIFI_MOD_CLASS_HT,
+                                    false,
+                                    20000000, 7200000,
+                                    WIFI_CODE_RATE_1_2,
+                                    2);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate13MbpsBW20MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate13MbpsBW20MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     true,
+                                     20000000, 13000000,
+                                     WIFI_CODE_RATE_1_2,
+                                     4);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate14_4MbpsBW20MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate14_4MbpsBW20MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     20000000, 14400000,
+                                     WIFI_CODE_RATE_1_2,
+                                     4);
+  return mode;
+}
+WifiMode
+WifiPhy::GetOfdmRate19_5MbpsBW20MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate19_5MbpsBW20MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     true,
+                                     20000000, 19500000,
+                                     WIFI_CODE_RATE_3_4,
+                                     4);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate21_7MbpsBW20MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate21_7MbpsBW20MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     20000000, 21700000,
+                                     WIFI_CODE_RATE_3_4,
+                                     4);
+  return mode;
+}
+
+
+WifiMode
+WifiPhy::GetOfdmRate26MbpsBW20MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate26MbpsBW20MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     true,
+                                     20000000, 26000000,
+                                     WIFI_CODE_RATE_1_2,
+                                     16);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate28_9MbpsBW20MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate28_9MbpsBW20MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     20000000, 28900000,
+                                     WIFI_CODE_RATE_1_2,
+                                     16);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate39MbpsBW20MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate39MbpsBW20MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     true,
+                                     20000000, 39000000,
+                                     WIFI_CODE_RATE_3_4,
+                                     16);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate43_3MbpsBW20MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate43_3MbpsBW20MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     20000000, 43300000,
+                                     WIFI_CODE_RATE_3_4,
+                                     16);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate52MbpsBW20MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate52MbpsBW20MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     true,
+                                     20000000, 52000000,
+                                     WIFI_CODE_RATE_2_3,
+                                     64);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate57_8MbpsBW20MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate57_8MbpsBW20MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     20000000, 57800000,
+                                     WIFI_CODE_RATE_2_3,
+                                     64);
+  return mode;
+}
+
+
+WifiMode
+WifiPhy::GetOfdmRate58_5MbpsBW20MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate58_5MbpsBW20MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     true,
+                                     20000000, 58500000,
+                                     WIFI_CODE_RATE_3_4,
+                                     64);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate65MbpsBW20MHzShGi ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate65MbpsBW20MHzShGi",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     20000000, 65000000,
+                                     WIFI_CODE_RATE_3_4,
+                                     64);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate65MbpsBW20MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate65MbpsBW20MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     true,
+                                     20000000, 65000000,
+                                     WIFI_CODE_RATE_5_6,
+                                     64);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate72_2MbpsBW20MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate72_2MbpsBW20MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     20000000, 72200000,
+                                     WIFI_CODE_RATE_5_6,
+                                     64);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate13_5MbpsBW40MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate13_5MbpsBW40MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     40000000, 13500000,
+                                     WIFI_CODE_RATE_1_2,
+                                     2);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate15MbpsBW40MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate15MbpsBW40MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     40000000, 15000000,
+                                     WIFI_CODE_RATE_1_2,
+                                     2);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate27MbpsBW40MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate27MbpsBW40MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     40000000, 27000000,
+                                     WIFI_CODE_RATE_1_2,
+                                     4);
+  return mode;
+}
+WifiMode
+WifiPhy::GetOfdmRate30MbpsBW40MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate30MbpsBW40MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     40000000, 30000000,
+                                     WIFI_CODE_RATE_1_2,
+                                     4);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate40_5MbpsBW40MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate40_5MbpsBW40MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     40000000, 40500000,
+                                     WIFI_CODE_RATE_3_4,
+                                     4);
+  return mode;
+}
+WifiMode
+WifiPhy::GetOfdmRate45MbpsBW40MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate45MbpsBW40MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     40000000, 45000000,
+                                     WIFI_CODE_RATE_3_4,
+                                     4);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate54MbpsBW40MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate54MbpsBW40MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     40000000, 54000000,
+                                     WIFI_CODE_RATE_1_2,
+                                     16);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate60MbpsBW40MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate60MbpsBW40MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     40000000, 60000000,
+                                     WIFI_CODE_RATE_1_2,
+                                     16);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate81MbpsBW40MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate81MbpsBW40MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     40000000, 81000000,
+                                     WIFI_CODE_RATE_3_4,
+                                     16);
+  return mode;
+}
+WifiMode
+WifiPhy::GetOfdmRate90MbpsBW40MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate90MbpsBW40MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     40000000, 90000000,
+                                     WIFI_CODE_RATE_3_4,
+                                     16);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate108MbpsBW40MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate108MbpsBW40MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     40000000, 108000000,
+                                     WIFI_CODE_RATE_2_3,
+                                     64);
+  return mode;
+}
+WifiMode
+WifiPhy::GetOfdmRate120MbpsBW40MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate120MbpsBW40MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     40000000, 120000000,
+                                     WIFI_CODE_RATE_2_3,
+                                     64);
+  return mode;
+}
+WifiMode
+WifiPhy::GetOfdmRate121_5MbpsBW40MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate121_5MbpsBW40MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     40000000, 121500000,
+                                     WIFI_CODE_RATE_3_4,
+                                     64);
+  return mode;
+}
+WifiMode
+WifiPhy::GetOfdmRate135MbpsBW40MHzShGi ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate135MbpsBW40MHzShGi",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     40000000, 135000000,
+                                     WIFI_CODE_RATE_3_4,
+                                     64);
+  return mode;
+}
+WifiMode
+WifiPhy::GetOfdmRate135MbpsBW40MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate135MbpsBW40MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     40000000, 135000000,
+                                     WIFI_CODE_RATE_5_6,
+                                     64);
+  return mode;
+}
+
+WifiMode
+WifiPhy::GetOfdmRate150MbpsBW40MHz ()
+{
+  static WifiMode mode =
+    WifiModeFactory::CreateWifiMode ("OfdmRate150MbpsBW40MHz",
+                                     WIFI_MOD_CLASS_HT,
+                                     false,
+                                     40000000, 150000000,
+                                     WIFI_CODE_RATE_5_6,
+                                     64);
+  return mode;
+}
+
+
+
 std::ostream& operator<< (std::ostream& os, enum WifiPhy::State state)
 {
   switch (state)
@@ -855,6 +1417,8 @@
     }
 }
 
+
+
 } // namespace ns3
 
 namespace {
@@ -900,6 +1464,31 @@
     ns3::WifiPhy::GetOfdmRate9MbpsBW5MHz ();
     ns3::WifiPhy::GetOfdmRate12MbpsBW5MHz ();
     ns3::WifiPhy::GetOfdmRate13_5MbpsBW5MHz ();
+    ns3::WifiPhy::GetOfdmRate6_5MbpsBW20MHz ();
+    ns3::WifiPhy::GetOfdmRate13MbpsBW20MHz ();
+    ns3::WifiPhy::GetOfdmRate19_5MbpsBW20MHz ();
+    ns3::WifiPhy::GetOfdmRate26MbpsBW20MHz ();
+    ns3::WifiPhy::GetOfdmRate39MbpsBW20MHz ();
+    ns3::WifiPhy::GetOfdmRate52MbpsBW20MHz ();
+    ns3::WifiPhy::GetOfdmRate58_5MbpsBW20MHz ();
+    ns3::WifiPhy::GetOfdmRate65MbpsBW20MHz ();
+    ns3::WifiPhy::GetOfdmRate13_5MbpsBW40MHz ();
+    ns3::WifiPhy::GetOfdmRate27MbpsBW40MHz ();
+    ns3::WifiPhy::GetOfdmRate40_5MbpsBW40MHz ();    
+    ns3::WifiPhy::GetOfdmRate54MbpsBW40MHz ();
+    ns3::WifiPhy::GetOfdmRate81MbpsBW40MHz ();
+    ns3::WifiPhy::GetOfdmRate108MbpsBW40MHz ();
+    ns3::WifiPhy::GetOfdmRate121_5MbpsBW40MHz ();
+    ns3::WifiPhy::GetOfdmRate135MbpsBW40MHz ();
+    ns3::WifiPhy::GetOfdmRate7_2MbpsBW20MHz ();
+    ns3::WifiPhy::GetOfdmRate14_4MbpsBW20MHz ();
+    ns3::WifiPhy::GetOfdmRate21_7MbpsBW20MHz ();
+    ns3::WifiPhy::GetOfdmRate28_9MbpsBW20MHz ();
+    ns3::WifiPhy::GetOfdmRate43_3MbpsBW20MHz ();
+    ns3::WifiPhy::GetOfdmRate57_8MbpsBW20MHz ();
+    ns3::WifiPhy::GetOfdmRate65MbpsBW20MHzShGi ();
+    ns3::WifiPhy::GetOfdmRate72_2MbpsBW20MHz ();
+
   }
 } g_constructor;
 }
--- a/src/wifi/model/wifi-phy.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/wifi-phy.h	Tue Aug 13 22:05:25 2013 -0700
@@ -31,7 +31,7 @@
 #include "wifi-preamble.h"
 #include "wifi-phy-standard.h"
 #include "ns3/traced-callback.h"
-
+#include "wifi-tx-vector.h"
 
 namespace ns3 {
 
@@ -184,10 +184,10 @@
    * \param packet the packet to send
    * \param mode the transmission mode to use to send this packet
    * \param preamble the type of preamble to use to send this packet.
-   * \param txPowerLevel a power level to use to send this packet. The real
+   * \param txvector the txvector that has tx parameters as txPowerLevel a power level to use to send this packet. The real
    *        transmission power is calculated as txPowerMin + txPowerLevel * (txPowerMax - txPowerMin) / nTxLevels
    */
-  virtual void SendPacket (Ptr<const Packet> packet, WifiMode mode, enum WifiPreamble preamble, uint8_t txPowerLevel) = 0;
+  virtual void SendPacket (Ptr<const Packet> packet, WifiMode mode, enum WifiPreamble preamble, WifiTxVector txvector) = 0;
 
   /**
    * \param listener the new listener
@@ -237,12 +237,36 @@
 
   /**
    * \param size the number of bytes in the packet to send
-   * \param payloadMode the transmission mode to use for this packet
+   * \param txvector the transmission parameters used for this packet
    * \param preamble the type of preamble to use for this packet.
    * \return the total amount of time this PHY will stay busy for
    *          the transmission of these bytes.
    */
-  static Time CalculateTxDuration (uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble);
+  static Time CalculateTxDuration (uint32_t size, WifiTxVector txvector, enum WifiPreamble preamble);
+
+/** 
+   * \param payloadMode the WifiMode use for the transmission of the payload
+   * \param preamble the type of preamble
+   * \param txvector the transmission parameters used for this packet
+
+   * \return the training symbol duration
+   */
+  static uint32_t GetPlcpHtTrainingSymbolDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble, WifiTxVector txvector);
+/** 
+   * \param payloadMode the WifiMode use for the transmission of the payload
+   * \param preamble the type of preamble
+   * 
+   * \return the WifiMode used for the transmission of the HT-SIG in Mixed Format and greenfield format PLCP header 
+   */
+  static WifiMode GetMFPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble);
+/** 
+   * \param payloadMode the WifiMode use for the transmission of the payload
+   * \param preamble the type of preamble
+   * 
+   * \return the duration of the GT-SIG in Mixed Format and greenfield format PLCP header 
+   */
+  static uint32_t GetPlcpHtSigHeaderDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble);
+
 
   /** 
    * \param payloadMode the WifiMode use for the transmission of the payload
@@ -270,11 +294,11 @@
 
   /** 
    * \param size the number of bytes in the packet to send
-   * \param payloadMode the WifiMode use for the transmission of the payload
+   * \param txvector the transmission parameters used for this packet
    * 
    * \return the duration of the payload in microseconds
    */
-  static uint32_t GetPayloadDurationMicroSeconds (uint32_t size, WifiMode payloadMode);
+  static double GetPayloadDurationMicroSeconds (uint32_t size, WifiTxVector txvector);
 
   /**
    * The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used
@@ -320,7 +344,60 @@
    *          the requested ber for the specified transmission mode. (W/W)
    */
   virtual double CalculateSnr (WifiMode txMode, double ber) const = 0;
+   /**
+   * The WifiPhy::NBssMembershipSelectors() and WifiPhy::BssMembershipSelector() methods are used
+   * (e.g., by a WifiRemoteStationManager) to determine the set of
+   * transmission/reception modes that this WifiPhy(-derived class)
+   * can support - a set of WifiMode objects which we call the
+   * BssMemebershipSelectorSet, and which is stored as WifiPhy::m_bssMembershipSelectorSet.
+   *
+   * This was introduced with 11n
+   *
+   * \param selector index in array of supported memeberships
+   * \returns the memebership selector whose index is specified.
+   *
+   * \sa WifiPhy::NBssMembershipSelectors()
+   */
+  virtual uint32_t GetNBssMembershipSelectors (void) const=0;
 
+  virtual uint32_t GetBssMembershipSelector (uint32_t selector) const=0;
+  /**
+   * The WifiPhy::GetMembershipSelectorModes() method is used
+   * (e.g., by a WifiRemoteStationManager) to determine the set of
+   * transmission/reception modes that this WifiPhy(-derived class)
+   * can support - a set of WifiMode objects which we call the
+   * BssMemebershipSelectorSet, and which is stored as WifiPhy::m_bssMembershipSelectorSet.
+   *
+   * This was introduced with 11n
+   *
+   * \param selector index in array of supported memeberships
+   * \returns a WifiModeList that contains the WifiModes associrated with the selected index.
+   *
+   * \sa WifiPhy::GetMembershipSelectorModes()
+   */
+  virtual WifiModeList GetMembershipSelectorModes(uint32_t selector)=0;
+  /**
+   * The WifiPhy::GetNMcs() and  WifiPhy::GetMcs() methods are used
+   * (e.g., by a WifiRemoteStationManager) to determine the set of
+   * transmission/reception MCS indexes that this WifiPhy(-derived class)
+   * can support - a set of Mcs indexes which we call the
+   * DeviceMcsSet, and which is stored as WifiPhy::m_deviceMcsSet.
+   *
+   * This was introduced with 11n
+   *
+   * \param Mcs index in array of supported Mcs
+   * \returns the Mcs index whose index is specified.
+   *
+   * \sa WifiPhy::GetNMcs()
+   */
+  virtual uint8_t GetNMcs (void) const=0;
+  virtual uint8_t GetMcs (uint8_t mcs) const=0;
+
+  /* Converts from DataRate to MCS index and vice versa */
+  virtual uint32_t WifiModeToMcs (WifiMode mode)=0;
+  virtual WifiMode McsToWifiMode (uint8_t mcs)=0;
+
+  
   /**
    * \brief Set channel number.
    *
@@ -373,6 +450,39 @@
   static WifiMode GetOfdmRate9MbpsBW5MHz ();
   static WifiMode GetOfdmRate12MbpsBW5MHz ();
   static WifiMode GetOfdmRate13_5MbpsBW5MHz ();
+  static WifiMode GetOfdmRate6_5MbpsBW20MHz ();
+  static WifiMode GetOfdmRate13MbpsBW20MHz ();
+  static WifiMode GetOfdmRate19_5MbpsBW20MHz ();
+  static WifiMode GetOfdmRate26MbpsBW20MHz ();
+  static WifiMode GetOfdmRate39MbpsBW20MHz ();
+  static WifiMode GetOfdmRate52MbpsBW20MHz ();
+  static WifiMode GetOfdmRate58_5MbpsBW20MHz ();
+  static WifiMode GetOfdmRate65MbpsBW20MHz ();
+  static WifiMode GetOfdmRate13_5MbpsBW40MHz ();
+  static WifiMode GetOfdmRate27MbpsBW40MHz (); 
+  static WifiMode GetOfdmRate40_5MbpsBW40MHz ();
+  static WifiMode GetOfdmRate54MbpsBW40MHz ();
+  static WifiMode GetOfdmRate81MbpsBW40MHz ();
+  static WifiMode GetOfdmRate108MbpsBW40MHz ();
+  static WifiMode GetOfdmRate121_5MbpsBW40MHz ();
+  static WifiMode GetOfdmRate135MbpsBW40MHz ();
+  //Rates for clause 20 with short guard interval
+  static WifiMode GetOfdmRate7_2MbpsBW20MHz ();
+  static WifiMode GetOfdmRate14_4MbpsBW20MHz ();
+  static WifiMode GetOfdmRate21_7MbpsBW20MHz ();
+  static WifiMode GetOfdmRate28_9MbpsBW20MHz ();
+  static WifiMode GetOfdmRate43_3MbpsBW20MHz ();
+  static WifiMode GetOfdmRate57_8MbpsBW20MHz ();
+  static WifiMode GetOfdmRate65MbpsBW20MHzShGi ();
+  static WifiMode GetOfdmRate72_2MbpsBW20MHz ();
+  static WifiMode GetOfdmRate15MbpsBW40MHz ();
+  static WifiMode GetOfdmRate30MbpsBW40MHz (); 
+  static WifiMode GetOfdmRate45MbpsBW40MHz ();
+  static WifiMode GetOfdmRate60MbpsBW40MHz ();
+  static WifiMode GetOfdmRate90MbpsBW40MHz ();
+  static WifiMode GetOfdmRate120MbpsBW40MHz ();
+  static WifiMode GetOfdmRate135MbpsBW40MHzShGi ();
+  static WifiMode GetOfdmRate150MbpsBW40MHz ();
 
 
   /**
@@ -447,7 +557,7 @@
    * units used both for the radiotap and for the prism header)
    * @param isShortPreamble true if short preamble is used, false otherwise
    */
-  void NotifyMonitorSniffTx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble);
+  void NotifyMonitorSniffTx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble, uint8_t txPower);
 
  /**
   * Assign a fixed random variable stream number to the random variables
@@ -459,6 +569,66 @@
   */
   virtual int64_t AssignStreams (int64_t stream) = 0;
 
+  /**
+   * \param the operating frequency on this node.
+   */
+  virtual void SetFrequency (uint32_t freq)=0;
+  virtual uint32_t GetFrequency (void) const=0;
+  /**
+   * \param the number of transmitters on this node.
+   */
+  virtual void SetNumberOfTransmitAntennas (uint32_t tx)=0;
+
+  virtual uint32_t GetNumberOfTransmitAntennas (void) const=0;
+   /**
+   * \param the number of recievers on this node.
+   */
+  virtual void SetNumberOfReceiveAntennas (uint32_t rx)=0 ;
+  /**
+   * \returns the number of recievers on this node.
+   */
+  virtual uint32_t GetNumberOfReceiveAntennas (void) const=0;
+  /**
+   * \paramif short guard interval is supported or not
+   */
+   virtual void SetGuardInterval (bool GuardInterval)=0;
+   /**
+   *  \returns if short guard interval is supported or not
+   */
+  virtual bool GetGuardInterval (void) const = 0;
+  /**
+   * \paramif LDPC is supported or not
+   */
+  virtual void SetLdpc (bool Ldpc)=0;
+  /**
+   * \returns if LDPC is supported or not
+   */
+  virtual bool GetLdpc (void) const=0;
+  /**
+   * \paramif STBC is supported or not
+   */
+  virtual void SetStbc (bool stbc)=0;
+  /**
+   *  \returns if STBC is supported or not
+   */
+  virtual bool GetStbc (void) const=0;
+   
+  /**
+   * \paramif GreenField is supported or not
+   */
+  virtual void SetGreenfield (bool greenfield)=0;
+  /**
+   *  \returns if Green field is supported or not
+   */
+  virtual bool GetGreenfield (void) const=0;
+  /**
+   * \paramif channel bonding 40 MHz is supported or not
+   */
+  virtual bool GetChannelBonding (void) const = 0;
+  /**
+   *  \returns if channel bonding is supported or not
+   */
+  virtual void SetChannelBonding (bool channelbonding) = 0 ;
 
 private:
   /**
@@ -530,7 +700,7 @@
    *
    * \see class CallBackTraceSource
    */
-  TracedCallback<Ptr<const Packet>, uint16_t, uint16_t, uint32_t, bool> m_phyMonitorSniffTxTrace;
+  TracedCallback<Ptr<const Packet>, uint16_t, uint16_t, uint32_t, bool,uint8_t> m_phyMonitorSniffTxTrace;
 
 };
 
--- a/src/wifi/model/wifi-preamble.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/wifi-preamble.h	Tue Aug 13 22:05:25 2013 -0700
@@ -29,7 +29,9 @@
 enum WifiPreamble
 {
   WIFI_PREAMBLE_LONG,
-  WIFI_PREAMBLE_SHORT
+  WIFI_PREAMBLE_SHORT,
+  WIFI_PREAMBLE_HT_MF,
+  WIFI_PREAMBLE_HT_GF
 };
 
 } // namespace ns3
--- a/src/wifi/model/wifi-remote-station-manager.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/wifi-remote-station-manager.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -40,13 +40,77 @@
 
 namespace ns3 {
 
-class TxModeTag : public Tag
+class HighLatencyDataTxVectorTag : public Tag
 {
 public:
-  TxModeTag ();
-  TxModeTag (WifiMode rtsMode, WifiMode dataMode);
-  WifiMode GetRtsMode (void) const;
-  WifiMode GetDataMode (void) const;
+  HighLatencyDataTxVectorTag ();
+  HighLatencyDataTxVectorTag (WifiTxVector dataTxVector);
+  WifiTxVector GetDataTxVector (void) const;
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (TagBuffer i) const;
+  virtual void Deserialize (TagBuffer i);
+  virtual void Print (std::ostream &os) const;
+private:
+  WifiTxVector m_dataTxVector;
+};
+
+HighLatencyDataTxVectorTag::HighLatencyDataTxVectorTag ()
+{
+}
+HighLatencyDataTxVectorTag::HighLatencyDataTxVectorTag ( WifiTxVector dataTxVector)
+  : m_dataTxVector (dataTxVector)
+{
+}
+
+WifiTxVector 
+HighLatencyDataTxVectorTag::GetDataTxVector (void) const
+{
+  return m_dataTxVector;
+}
+TypeId
+HighLatencyDataTxVectorTag::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::HighLatencyDataTxVectorTag")
+    .SetParent<Tag> ()
+    .AddConstructor<HighLatencyDataTxVectorTag> ()  
+    ;
+  return tid;
+}
+TypeId
+HighLatencyDataTxVectorTag::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+uint32_t
+HighLatencyDataTxVectorTag::GetSerializedSize (void) const
+{
+  return sizeof (WifiTxVector);
+}
+void
+HighLatencyDataTxVectorTag::Serialize (TagBuffer i) const
+{
+  i.Write ((uint8_t *)&m_dataTxVector, sizeof (WifiTxVector));
+}
+void
+HighLatencyDataTxVectorTag::Deserialize (TagBuffer i)
+{
+  i.Read ((uint8_t *)&m_dataTxVector, sizeof (WifiTxVector));
+}
+void
+HighLatencyDataTxVectorTag::Print (std::ostream &os) const
+{
+  os << "Data=" << m_dataTxVector;
+}
+
+class HighLatencyRtsTxVectorTag : public Tag
+{
+public:
+  HighLatencyRtsTxVectorTag ();
+  HighLatencyRtsTxVectorTag (WifiTxVector rtsTxVector);
+  WifiTxVector GetRtsTxVector (void) const;
 
   static TypeId GetTypeId (void);
   virtual TypeId GetInstanceTypeId (void) const;
@@ -55,78 +119,124 @@
   virtual void Deserialize (TagBuffer i);
   virtual void Print (std::ostream &os) const;
 private:
-  WifiMode m_rtsMode;
-  WifiMode m_dataMode;
+  WifiTxVector m_rtsTxVector;
 };
 
-TxModeTag::TxModeTag ()
+HighLatencyRtsTxVectorTag::HighLatencyRtsTxVectorTag ()
 {
 }
-TxModeTag::TxModeTag (WifiMode rtsMode, WifiMode dataMode)
-  : m_rtsMode (rtsMode),
-    m_dataMode (dataMode)
+HighLatencyRtsTxVectorTag::HighLatencyRtsTxVectorTag ( WifiTxVector rtsTxVector)
+  : m_rtsTxVector (rtsTxVector)
 {
 }
-WifiMode
-TxModeTag::GetRtsMode (void) const
+
+WifiTxVector 
+HighLatencyRtsTxVectorTag::GetRtsTxVector (void) const
 {
-  return m_rtsMode;
-}
-WifiMode
-TxModeTag::GetDataMode (void) const
-{
-  return m_dataMode;
+  return m_rtsTxVector;
 }
 TypeId
-TxModeTag::GetTypeId (void)
+HighLatencyRtsTxVectorTag::GetTypeId (void)
 {
-  static TypeId tid = TypeId ("ns3::TxModeTag")
+  static TypeId tid = TypeId ("ns3::HighLatencyRtsTxVectorTag")
     .SetParent<Tag> ()
-    .AddConstructor<TxModeTag> ()
-    .AddAttribute ("RtsTxMode",
-                   "Tx mode of rts to use later",
-                   EmptyAttributeValue (),
-                   MakeWifiModeAccessor (&TxModeTag::GetRtsMode),
-                   MakeWifiModeChecker ())
-    .AddAttribute ("DataTxMode",
-                   "Tx mode of data to use later",
-                   EmptyAttributeValue (),
-                   MakeWifiModeAccessor (&TxModeTag::GetDataMode),
-                   MakeWifiModeChecker ())
-  ;
+    .AddConstructor<HighLatencyRtsTxVectorTag> ()  
+    ;
   return tid;
 }
 TypeId
-TxModeTag::GetInstanceTypeId (void) const
+HighLatencyRtsTxVectorTag::GetInstanceTypeId (void) const
 {
   return GetTypeId ();
 }
 uint32_t
-TxModeTag::GetSerializedSize (void) const
+HighLatencyRtsTxVectorTag::GetSerializedSize (void) const
+{
+  return sizeof (WifiTxVector);
+}
+void
+HighLatencyRtsTxVectorTag::Serialize (TagBuffer i) const
 {
-  return sizeof (WifiMode) * 2;
+  i.Write ((uint8_t *)&m_rtsTxVector, sizeof (WifiTxVector));
+}
+void
+HighLatencyRtsTxVectorTag::Deserialize (TagBuffer i)
+{
+  i.Read ((uint8_t *)&m_rtsTxVector, sizeof (WifiTxVector));
 }
 void
-TxModeTag::Serialize (TagBuffer i) const
+HighLatencyRtsTxVectorTag::Print (std::ostream &os) const
+{
+  os << "Rts=" << m_rtsTxVector;
+}
+
+class HighLatencyCtsToSelfTxVectorTag : public Tag
+{
+public:
+  HighLatencyCtsToSelfTxVectorTag ();
+  HighLatencyCtsToSelfTxVectorTag (WifiTxVector ctsToSelfTxVector);
+  WifiTxVector GetCtsToSelfTxVector (void) const;
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (TagBuffer i) const;
+  virtual void Deserialize (TagBuffer i);
+  virtual void Print (std::ostream &os) const;
+private:
+  WifiTxVector m_ctsToSelfTxVector;
+};
+
+HighLatencyCtsToSelfTxVectorTag::HighLatencyCtsToSelfTxVectorTag ()
 {
-  i.Write ((uint8_t *)&m_rtsMode, sizeof (WifiMode));
-  i.Write ((uint8_t *)&m_dataMode, sizeof (WifiMode));
+}
+HighLatencyCtsToSelfTxVectorTag::HighLatencyCtsToSelfTxVectorTag ( WifiTxVector ctsToSelfTxVector)
+  : m_ctsToSelfTxVector (ctsToSelfTxVector)
+{
+}
+
+WifiTxVector 
+HighLatencyCtsToSelfTxVectorTag::GetCtsToSelfTxVector (void) const
+{
+  return m_ctsToSelfTxVector;
+}
+TypeId
+HighLatencyCtsToSelfTxVectorTag::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::HighLatencyCtsToSelfTxVectorTag")
+    .SetParent<Tag> ()
+    .AddConstructor<HighLatencyCtsToSelfTxVectorTag> ()  
+    ;
+  return tid;
+}
+TypeId
+HighLatencyCtsToSelfTxVectorTag::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+uint32_t
+HighLatencyCtsToSelfTxVectorTag::GetSerializedSize (void) const
+{
+  return sizeof (WifiTxVector);
 }
 void
-TxModeTag::Deserialize (TagBuffer i)
+HighLatencyCtsToSelfTxVectorTag::Serialize (TagBuffer i) const
 {
-  i.Read ((uint8_t *)&m_rtsMode, sizeof (WifiMode));
-  i.Read ((uint8_t *)&m_dataMode, sizeof (WifiMode));
+  i.Write ((uint8_t *)&m_ctsToSelfTxVector, sizeof (WifiTxVector));
 }
 void
-TxModeTag::Print (std::ostream &os) const
+HighLatencyCtsToSelfTxVectorTag::Deserialize (TagBuffer i)
 {
-  os << "Rts=" << m_rtsMode << ", Data=" << m_dataMode;
+  i.Read ((uint8_t *)&m_ctsToSelfTxVector, sizeof (WifiTxVector));
+}
+void
+HighLatencyCtsToSelfTxVectorTag::Print (std::ostream &os) const
+{
+  os << "Cts To Self=" << m_ctsToSelfTxVector;
 }
 
 } // namespace ns3
 
-
 namespace ns3 {
 
 NS_OBJECT_ENSURE_REGISTERED (WifiRemoteStationManager);
@@ -172,6 +282,12 @@
                    WifiModeValue (),
                    MakeWifiModeAccessor (&WifiRemoteStationManager::m_nonUnicastMode),
                    MakeWifiModeChecker ())
+    .AddAttribute ("DefaultTxPowerLevel", "Default power level to be used for transmissions. "
+                   "This is the power level that is used by all those WifiManagers that do not"
+                   "implement TX power control.",
+                   UintegerValue (0),
+                   MakeUintegerAccessor (&WifiRemoteStationManager::m_defaultTxPowerLevel),
+                   MakeUintegerChecker<uint8_t> ())
     .AddTraceSource ("MacTxRtsFailed",
                      "The transmission of a RTS by the MAC layer has failed",
                      MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxRtsFailed))
@@ -219,9 +335,27 @@
   // acknowledgements.
   m_wifiPhy = phy;
   m_defaultTxMode = phy->GetMode (0);
+  if(HasHtSupported())
+    {
+       m_defaultTxMcs = phy->GetMcs (0);
+    }
+  else
+    {
+      m_defaultTxMcs = 0;
+    }
   Reset ();
 }
+void
+WifiRemoteStationManager::SetHtSupported (bool enable)
+{
+  m_htSupported=enable;
+}
 
+bool
+WifiRemoteStationManager::HasHtSupported (void) const
+{
+  return m_htSupported;
+}
 uint32_t
 WifiRemoteStationManager::GetMaxSsrc (void) const
 {
@@ -269,7 +403,9 @@
   NS_ASSERT (!address.IsGroup ());
   WifiRemoteStationState *state = LookupState (address);
   state->m_operationalRateSet.clear ();
+  state->m_operationalMcsSet.clear ();
   AddSupportedMode (address, GetDefaultMode ());
+  AddSupportedMcs(address,GetDefaultMcs());
 }
 void
 WifiRemoteStationManager::AddSupportedMode (Mac48Address address, WifiMode mode)
@@ -286,6 +422,42 @@
     }
   state->m_operationalRateSet.push_back (mode);
 }
+/*void
+WifiRemoteStationManager::AddBssMembershipParameters(Mac48Address address, uint32_t selector)
+{
+  NS_ASSERT (!address.IsGroup ());
+  WifiRemoteStationState *state = LookupState (address);
+  WifiMode mode;
+  WifiModeList membershipselectormodes = m_wifiPhy->GetMembershipSelectorModes(selector);
+  for (WifiModeListIterator j = membershipselectormodes.begin (); j != membershipselectormodes.end (); j++)
+    {
+      mode=(*j);
+     for (WifiModeListIterator i = state->m_operationalRateSet.begin (); i != state->m_operationalRateSet.end (); i++)
+      {
+        if ((*i) == mode)
+          {
+            // already in.
+            break;
+          }
+      }
+    state->m_operationalRateSet.push_back (mode);
+  }
+}*/
+void 
+WifiRemoteStationManager::AddSupportedMcs (Mac48Address address, uint8_t mcs)
+{
+  NS_ASSERT (!address.IsGroup ());
+  WifiRemoteStationState *state = LookupState (address);
+  for (WifiMcsListIterator i = state->m_operationalMcsSet.begin (); i != state->m_operationalMcsSet.end (); i++)
+    {
+      if ((*i) == mcs)
+        {
+          // already in.
+          return;
+        }
+    }
+  state->m_operationalMcsSet.push_back (mcs);
+}
 bool
 WifiRemoteStationManager::IsBrandNew (Mac48Address address) const
 {
@@ -346,47 +518,94 @@
       return;
     }
   WifiRemoteStation *station = Lookup (address, header);
-  WifiMode rts = DoGetRtsMode (station);
-  WifiMode data = DoGetDataMode (station, fullPacketSize);
-  TxModeTag tag;
+  WifiTxVector rts = DoGetRtsTxVector (station);
+  WifiTxVector data = DoGetDataTxVector (station, fullPacketSize); 
+  WifiTxVector ctstoself = DoGetCtsToSelfTxVector (); 
+  HighLatencyDataTxVectorTag datatag;
+  HighLatencyRtsTxVectorTag rtstag;
+  HighLatencyCtsToSelfTxVectorTag ctstoselftag;
   // first, make sure that the tag is not here anymore.
-  ConstCast<Packet> (packet)->RemovePacketTag (tag);
-  tag = TxModeTag (rts, data);
+  ConstCast<Packet> (packet)->RemovePacketTag (datatag);
+  ConstCast<Packet> (packet)->RemovePacketTag (rtstag);
+  ConstCast<Packet> (packet)->RemovePacketTag (ctstoselftag);
+  datatag = HighLatencyDataTxVectorTag (data);
+  rtstag = HighLatencyRtsTxVectorTag (rts);
+  ctstoselftag = HighLatencyCtsToSelfTxVectorTag (ctstoself);
   // and then, add it back
-  packet->AddPacketTag (tag);
+  packet->AddPacketTag (datatag);
+  packet->AddPacketTag (rtstag);
+  packet->AddPacketTag (ctstoselftag);
 }
-WifiMode
-WifiRemoteStationManager::GetDataMode (Mac48Address address, const WifiMacHeader *header,
+WifiTxVector
+WifiRemoteStationManager::GetDataTxVector (Mac48Address address, const WifiMacHeader *header,
                                        Ptr<const Packet> packet, uint32_t fullPacketSize)
 {
   if (address.IsGroup ())
     {
-      return GetNonUnicastMode ();
+      WifiTxVector v;
+      v.SetMode (GetNonUnicastMode ());
+      v.SetTxPowerLevel (m_defaultTxPowerLevel);
+      v.SetShortGuardInterval (false);
+      v.SetNss (1);
+      v.SetNess (0);
+      v.SetStbc (false);
+      return v;
     }
   if (!IsLowLatency ())
     {
-      TxModeTag tag;
+      HighLatencyDataTxVectorTag datatag;
       bool found;
-      found = ConstCast<Packet> (packet)->PeekPacketTag (tag);
+      found = ConstCast<Packet> (packet)->PeekPacketTag (datatag);
       NS_ASSERT (found);
-      return tag.GetDataMode ();
+      // cast found to void, to suppress 'found' set but not used
+      // compiler warning
+      (void) found;
+      return datatag.GetDataTxVector ();
     }
-  return DoGetDataMode (Lookup (address, header), fullPacketSize);
+  return DoGetDataTxVector (Lookup (address, header), fullPacketSize);
 }
-WifiMode
-WifiRemoteStationManager::GetRtsMode (Mac48Address address, const WifiMacHeader *header,
+WifiTxVector
+WifiRemoteStationManager::GetCtsToSelfTxVector(const WifiMacHeader *header,
+                                      Ptr<const Packet> packet)
+{
+  
+  if (!IsLowLatency ())
+    {
+      HighLatencyCtsToSelfTxVectorTag ctstoselftag;
+      bool found;
+      found = ConstCast<Packet> (packet)->PeekPacketTag (ctstoselftag);
+      NS_ASSERT (found);
+      // cast found to void, to suppress 'found' set but not used
+      // compiler warning
+      (void) found;
+      return ctstoselftag.GetCtsToSelfTxVector ();
+    }
+  return DoGetCtsToSelfTxVector ();
+}
+
+WifiTxVector
+WifiRemoteStationManager::DoGetCtsToSelfTxVector (void)
+{
+  return WifiTxVector (GetDefaultMode(), GetDefaultTxPowerLevel (),0,m_wifiPhy->GetGuardInterval(),GetNumberOfTransmitAntennas(), GetNumberOfTransmitAntennas(), false);
+}
+
+WifiTxVector
+WifiRemoteStationManager::GetRtsTxVector (Mac48Address address, const WifiMacHeader *header,
                                       Ptr<const Packet> packet)
 {
   NS_ASSERT (!address.IsGroup ());
   if (!IsLowLatency ())
     {
-      TxModeTag tag;
+      HighLatencyRtsTxVectorTag rtstag;
       bool found;
-      found = ConstCast<Packet> (packet)->PeekPacketTag (tag);
+      found = ConstCast<Packet> (packet)->PeekPacketTag (rtstag);
       NS_ASSERT (found);
-      return tag.GetRtsMode ();
+      // cast found to void, to suppress 'found' set but not used
+      // compiler warning
+      (void) found;
+      return rtstag.GetRtsTxVector ();
     }
-  return DoGetRtsMode (Lookup (address, header));
+  return DoGetRtsTxVector (Lookup (address, header));
 }
 void
 WifiRemoteStationManager::ReportRtsFailed (Mac48Address address, const WifiMacHeader *header)
@@ -469,6 +688,34 @@
   return DoNeedRts (Lookup (address, header), packet, normally);
 }
 bool
+WifiRemoteStationManager::NeedCtsToSelf (WifiTxVector txVector)
+{
+  WifiMode mode = txVector.GetMode();
+ 
+  // search the BSS Basic Rate set if the used mode in the basic set then no need for Cts to self
+  for (WifiModeListIterator i = m_bssBasicRateSet.begin ();
+       i != m_bssBasicRateSet.end (); i++)
+    {
+      if (mode == *i)
+        {
+          return false;
+        }
+    }
+  if (HasHtSupported())
+    {
+      uint8_t mcs = m_wifiPhy->WifiModeToMcs (mode);
+      for (WifiMcsListIterator i = m_bssBasicMcsSet.begin ();
+           i != m_bssBasicMcsSet.end (); i++)
+        {
+          if (mcs == *i)
+            {
+              return false;
+            }
+        }
+    }
+  return true;
+}
+bool
 WifiRemoteStationManager::NeedRtsRetransmission (Mac48Address address, const WifiMacHeader *header,
                                                  Ptr<const Packet> packet)
 {
@@ -622,7 +869,29 @@
           found = true;
         }
     }
-
+  if(HasHtSupported())
+      {
+  if (!found)
+    {
+     uint8_t mcs = GetDefaultMcs (); 
+      mode=  m_wifiPhy->McsToWifiMode (mcs); 
+    }
+  for (WifiMcsListIterator i = m_bssBasicMcsSet.begin ();
+       i != m_bssBasicMcsSet.end (); i++)
+    {
+       WifiMode thismode=  m_wifiPhy->McsToWifiMode (*i); 
+      if ((!found || thismode.GetPhyRate () > mode.GetPhyRate ())
+          && thismode.GetPhyRate () <= reqMode.GetPhyRate ()
+          && thismode.GetModulationClass () == reqMode.GetModulationClass ())
+        {
+          mode = thismode;
+          // We've found a potentially-suitable transmit rate, but we
+          // need to continue and consider all the basic rates before
+          // we can be sure we've got the right one.
+          found = true;
+        }
+    }
+}
   // If we found a suitable rate in the BSSBasicRateSet, then we are
   // done and can return that mode.
   if (found)
@@ -673,6 +942,27 @@
           found = true;
         }
     }
+    if(HasHtSupported())
+      {
+        for (uint32_t idx = 0; idx < m_wifiPhy->GetNMcs (); idx++)
+          {
+            uint8_t thismcs = m_wifiPhy->GetMcs (idx);
+            WifiMode thismode=  m_wifiPhy->McsToWifiMode (thismcs);
+             if (thismode.IsMandatory ()
+          && (!found || thismode.GetPhyRate () > mode.GetPhyRate ())
+          && thismode.GetPhyRate () <= reqMode.GetPhyRate ()
+          && thismode.GetModulationClass () == reqMode.GetModulationClass ())
+        {
+          mode = thismode;
+          // As above; we've found a potentially-suitable transmit
+          // rate, but we need to continue and consider all the
+          // mandatory rates before we can be sure we've got the right
+          // one.
+          found = true;
+        }
+            
+          }
+      }
 
   /**
    * If we still haven't found a suitable rate for the response then
@@ -693,18 +983,137 @@
   return mode;
 }
 
-WifiMode
-WifiRemoteStationManager::GetCtsMode (Mac48Address address, WifiMode rtsMode)
+WifiTxVector
+WifiRemoteStationManager::GetCtsTxVector (Mac48Address address, WifiMode rtsMode)
+{
+  NS_ASSERT (!address.IsGroup ());
+  WifiTxVector v;
+  v.SetMode (GetControlAnswerMode (address, rtsMode));
+  v.SetTxPowerLevel (DoGetCtsTxPowerLevel (address, v.GetMode()));
+  v.SetShortGuardInterval (DoGetCtsTxGuardInterval(address, v.GetMode()));
+  v.SetNss (DoGetCtsTxNss(address, v.GetMode()));
+  v.SetNess (DoGetCtsTxNess(address, v.GetMode()));
+  v.SetStbc (DoGetCtsTxStbc(address, v.GetMode()));
+  return v;
+}
+WifiTxVector
+WifiRemoteStationManager::GetAckTxVector (Mac48Address address, WifiMode dataMode)
+{
+  NS_ASSERT (!address.IsGroup ());
+  WifiTxVector v;
+  v.SetMode (GetControlAnswerMode (address, dataMode));
+  v.SetTxPowerLevel (DoGetAckTxPowerLevel (address, v.GetMode()));
+  v.SetShortGuardInterval(DoGetAckTxGuardInterval(address, v.GetMode()));
+  v.SetNss(DoGetAckTxNss(address, v.GetMode()));
+  v.SetNess(DoGetAckTxNess(address, v.GetMode()));
+  v.SetStbc(DoGetAckTxStbc(address, v.GetMode()));
+  return v;
+}
+WifiTxVector
+WifiRemoteStationManager::GetBlockAckTxVector (Mac48Address address, WifiMode blockAckReqMode)
 {
   NS_ASSERT (!address.IsGroup ());
-  return GetControlAnswerMode (address, rtsMode);
+  WifiTxVector v;
+  v.SetMode (GetControlAnswerMode (address, blockAckReqMode));
+  v.SetTxPowerLevel (DoGetBlockAckTxPowerLevel (address, v.GetMode()));
+  v.SetShortGuardInterval (DoGetBlockAckTxGuardInterval(address, v.GetMode()));
+  v.SetNss (DoGetBlockAckTxNss(address, v.GetMode()));
+  v.SetNess (DoGetBlockAckTxNess(address, v.GetMode()));
+  v.SetStbc (DoGetBlockAckTxStbc(address, v.GetMode()));
+  return v;
+}
+
+uint8_t 
+WifiRemoteStationManager::DoGetCtsTxPowerLevel (Mac48Address address, WifiMode ctsMode)
+{
+  return m_defaultTxPowerLevel;
+}
+
+bool 
+WifiRemoteStationManager::DoGetCtsTxGuardInterval(Mac48Address address, WifiMode ctsMode)
+{
+  return m_wifiPhy->GetGuardInterval();
+}
+
+uint8_t
+WifiRemoteStationManager::DoGetCtsTxNss(Mac48Address address, WifiMode ctsMode)
+{
+  return 1;
+}
+uint8_t
+WifiRemoteStationManager::DoGetCtsTxNess(Mac48Address address, WifiMode ctsMode)
+{
+  return 0;
+}
+bool 
+WifiRemoteStationManager::DoGetCtsTxStbc(Mac48Address address, WifiMode ctsMode)
+{
+  return m_wifiPhy->GetStbc();
+}
+
+uint8_t 
+WifiRemoteStationManager::DoGetAckTxPowerLevel (Mac48Address address, WifiMode ackMode)
+{
+  return m_defaultTxPowerLevel;
+}
+
+bool 
+WifiRemoteStationManager::DoGetAckTxGuardInterval(Mac48Address address, WifiMode ackMode)
+{
+  return m_wifiPhy->GetGuardInterval();
 }
-WifiMode
-WifiRemoteStationManager::GetAckMode (Mac48Address address, WifiMode dataMode)
+
+uint8_t
+WifiRemoteStationManager::DoGetAckTxNss(Mac48Address address, WifiMode ackMode)
+{
+  return 1;
+}
+uint8_t
+WifiRemoteStationManager::DoGetAckTxNess(Mac48Address address, WifiMode ackMode)
+{
+  return 0;
+}
+bool 
+WifiRemoteStationManager::DoGetAckTxStbc(Mac48Address address, WifiMode ackMode)
+{
+  return m_wifiPhy->GetStbc();
+}
+
+uint8_t 
+WifiRemoteStationManager::DoGetBlockAckTxPowerLevel (Mac48Address address, WifiMode blockAckMode)
+{
+  return m_defaultTxPowerLevel;
+}
+
+bool 
+WifiRemoteStationManager::DoGetBlockAckTxGuardInterval(Mac48Address address, WifiMode blockAckMode)
 {
-  NS_ASSERT (!address.IsGroup ());
-  return GetControlAnswerMode (address, dataMode);
+  return m_wifiPhy->GetGuardInterval();
+}
+
+uint8_t
+WifiRemoteStationManager::DoGetBlockAckTxNss(Mac48Address address, WifiMode blockAckMode)
+{
+  return 1;
+}
+uint8_t
+WifiRemoteStationManager::DoGetBlockAckTxNess(Mac48Address address, WifiMode blockAckMode)
+{
+  return 0;
 }
+bool 
+WifiRemoteStationManager::DoGetBlockAckTxStbc(Mac48Address address, WifiMode blockAckMode)
+{
+  return m_wifiPhy->GetStbc();
+}
+
+
+uint8_t
+WifiRemoteStationManager::GetDefaultTxPowerLevel (void) const
+{
+  return m_defaultTxPowerLevel;
+}
+
 
 WifiRemoteStationInfo
 WifiRemoteStationManager::GetInfo (Mac48Address address)
@@ -727,6 +1136,12 @@
   state->m_state = WifiRemoteStationState::BRAND_NEW;
   state->m_address = address;
   state->m_operationalRateSet.push_back (GetDefaultMode ());
+  state->m_operationalMcsSet.push_back(GetDefaultMcs());
+  state->m_shortGuardInterval=m_wifiPhy->GetGuardInterval();
+  state->m_greenfield=m_wifiPhy->GetGreenfield();
+  state->m_rx=1;
+  state->m_tx=1;
+  state->m_stbc=false;
   const_cast<WifiRemoteStationManager *> (this)->m_states.push_back (state);
   return state;
 }
@@ -767,12 +1182,32 @@
   return station;
 
 }
-
+//Used by all stations to record HT capabilities of remote stations
+void
+WifiRemoteStationManager::AddStationHtCapabilities (Mac48Address from, HtCapabilities htcapabilities)
+{
+  WifiRemoteStationState *state;
+  state=LookupState (from);
+  state->m_shortGuardInterval=htcapabilities.GetShortGuardInterval20();
+  state->m_greenfield=htcapabilities.GetGreenfield();
+ 
+}
+//Used by mac low to choose format used GF, MF or Non HT
+bool 
+WifiRemoteStationManager::GetGreenfieldSupported (Mac48Address address) const
+{
+ return LookupState(address)->m_greenfield;
+}
 WifiMode
 WifiRemoteStationManager::GetDefaultMode (void) const
 {
   return m_defaultTxMode;
 }
+uint8_t
+WifiRemoteStationManager::GetDefaultMcs (void) const
+{
+  return m_defaultTxMcs;
+}
 void
 WifiRemoteStationManager::Reset (void)
 {
@@ -783,6 +1218,8 @@
   m_stations.clear ();
   m_bssBasicRateSet.clear ();
   m_bssBasicRateSet.push_back (m_defaultTxMode);
+  m_bssBasicMcsSet.clear();
+  m_bssBasicMcsSet.push_back (m_defaultTxMcs);
   NS_ASSERT (m_defaultTxMode.IsMandatory ());
 }
 void
@@ -808,6 +1245,32 @@
   NS_ASSERT (i < m_bssBasicRateSet.size ());
   return m_bssBasicRateSet[i];
 }
+
+void 
+WifiRemoteStationManager::AddBasicMcs (uint8_t mcs)
+{
+   for (uint32_t i = 0; i < GetNBasicMcs (); i++)
+    {
+      if (GetBasicMcs (i) == mcs)
+        {
+          return;
+        }
+    }
+  m_bssBasicMcsSet.push_back (mcs);
+}
+
+uint32_t
+WifiRemoteStationManager::GetNBasicMcs (void) const
+{
+  return m_bssBasicMcsSet.size ();
+}
+uint8_t 
+WifiRemoteStationManager::GetBasicMcs (uint32_t i) const
+{
+   NS_ASSERT (i < m_bssBasicMcsSet.size ());
+  return m_bssBasicMcsSet[i];
+}
+
 WifiMode
 WifiRemoteStationManager::GetNonUnicastMode (void) const
 {
@@ -852,12 +1315,69 @@
   NS_ASSERT (i < GetNSupported (station));
   return station->m_state->m_operationalRateSet[i];
 }
+uint8_t
+WifiRemoteStationManager::GetMcsSupported (const WifiRemoteStation *station, uint32_t i) const
+{
+  NS_ASSERT (i < GetNMcsSupported (station));
+  return station->m_state->m_operationalMcsSet[i];
+}
+bool 
+WifiRemoteStationManager::GetShortGuardInterval (const WifiRemoteStation *station) const
+{
+  return station->m_state->m_shortGuardInterval;
+}
+bool 
+WifiRemoteStationManager::GetGreenfield (const WifiRemoteStation *station) const
+{
+  return station->m_state->m_greenfield;
+}
+bool 
+WifiRemoteStationManager::GetStbc (const WifiRemoteStation *station) const
+{
+  return station->m_state->m_stbc;
+}
+uint32_t 
+WifiRemoteStationManager::GetNumberOfReceiveAntennas (const WifiRemoteStation *station) const
+{
+  return station->m_state->m_rx;
+}
+uint32_t 
+WifiRemoteStationManager::GetNumberOfTransmitAntennas (const WifiRemoteStation *station) const
+{
+  return station->m_state->m_tx;
+}
+uint32_t 
+WifiRemoteStationManager::GetShortRetryCount (const WifiRemoteStation *station) const
+{
+  return station->m_ssrc;
+}
+uint32_t 
+WifiRemoteStationManager::GetLongRetryCount (const WifiRemoteStation *station) const
+{
+  return station->m_slrc;
+}
 uint32_t
 WifiRemoteStationManager::GetNSupported (const WifiRemoteStation *station) const
 {
   return station->m_state->m_operationalRateSet.size ();
 }
+uint32_t
+WifiRemoteStationManager::GetNMcsSupported (const WifiRemoteStation *station) const
+{
+  return station->m_state->m_operationalMcsSet.size ();
+}
+void
+WifiRemoteStationManager::SetDefaultTxPowerLevel (uint8_t txPower)
+{
+  m_defaultTxPowerLevel = txPower;
+}
 
+//support 11n
+uint32_t
+WifiRemoteStationManager::GetNumberOfTransmitAntennas (void)
+{
+  return m_wifiPhy->GetNumberOfTransmitAntennas();
+}
 //WifiRemoteStationInfo constructor
 WifiRemoteStationInfo::WifiRemoteStationInfo ()
   : m_memoryTime (Seconds (1.0)),
--- a/src/wifi/model/wifi-remote-station-manager.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/wifi-remote-station-manager.h	Tue Aug 13 22:05:25 2013 -0700
@@ -28,6 +28,8 @@
 #include "ns3/object.h"
 #include "ns3/nstime.h"
 #include "wifi-mode.h"
+#include "wifi-tx-vector.h"
+#include "ht-capabilities.h"
 
 namespace ns3 {
 
@@ -96,6 +98,9 @@
   void SetMaxSlrc (uint32_t maxSlrc);
   void SetRtsCtsThreshold (uint32_t threshold);
   void SetFragmentationThreshold (uint32_t threshold);
+  void AddStationHtCapabilities (Mac48Address from,HtCapabilities     htcapabilities);
+  void SetHtSupported (bool enable);
+  bool HasHtSupported (void) const;
 
   // Invoked in a STA upon dis-association
   // or in an AP upon reboot
@@ -110,6 +115,13 @@
   WifiMode GetDefaultMode (void) const;
   uint32_t GetNBasicModes (void) const;
   WifiMode GetBasicMode (uint32_t i) const;
+  bool GetGreenfieldSupported (Mac48Address address) const;
+  void AddBasicMcs (uint8_t mcs);
+
+  uint8_t GetDefaultMcs (void) const;
+  uint32_t GetNBasicMcs (void) const;
+  uint8_t GetBasicMcs (uint32_t i) const;
+  void AddSupportedMcs (Mac48Address address, uint8_t mcs);
 
   WifiMode GetNonUnicastMode (void) const;
 
@@ -127,6 +139,7 @@
    * the BSSBasicRateSet.
    */
   void AddSupportedMode (Mac48Address address, WifiMode mode);
+  //void  AddBssMembershipParameters(Mac48Address address, uint32_t selector);
 
   bool IsBrandNew (Mac48Address address) const;
   bool IsAssociated (Mac48Address address) const;
@@ -149,6 +162,7 @@
    */
   void PrepareForQueue (Mac48Address address, const WifiMacHeader *header,
                         Ptr<const Packet> packet, uint32_t fullPacketSize);
+  
   /**
    * \param address remote address
    * \param header MAC header
@@ -156,7 +170,7 @@
    * \param fullPacketSize the size of the packet after its 802.11 MAC header has been added.
    * \returns the transmission mode to use to send this packet
    */
-  WifiMode GetDataMode (Mac48Address address, const WifiMacHeader *header,
+  WifiTxVector GetDataTxVector (Mac48Address address, const WifiMacHeader *header,
                         Ptr<const Packet> packet, uint32_t fullPacketSize);
   /**
    * \param address remote address
@@ -165,8 +179,16 @@
    * \returns the transmission mode to use to send the RTS prior to the
    *          transmission of the data packet itself.
    */
-  WifiMode GetRtsMode (Mac48Address address, const WifiMacHeader *header,
+  WifiTxVector GetRtsTxVector (Mac48Address address, const WifiMacHeader *header,
+                       Ptr<const Packet> packet);
+
+  WifiTxVector GetCtsToSelfTxVector (const WifiMacHeader *header,
                        Ptr<const Packet> packet);
+
+  //Since CTS to Self parameters don't depened on the station it is implemented in wifiremote station manager
+  WifiTxVector DoGetCtsToSelfTxVector (void);
+
+
   /**
    * Should be invoked whenever the RtsTimeout associated to a transmission
    * attempt expires.
@@ -220,6 +242,8 @@
    */
   bool NeedRts (Mac48Address address, const WifiMacHeader *header,
                 Ptr<const Packet> packet);
+  bool NeedCtsToSelf (WifiTxVector txVector);
+
   /**
    * \param address remote address
    * \param header MAC header
@@ -281,21 +305,54 @@
    * \returns the transmission mode to use for the CTS to complete the RTS/CTS
    *          handshake.
    */
-  WifiMode GetCtsMode (Mac48Address address, WifiMode rtsMode);
+  WifiTxVector GetCtsTxVector (Mac48Address address, WifiMode rtsMode);
+  /**
+   * \param address
+   * \param dataMode the transmission mode used to send an ACK we just received
+   * \returns the transmission mode to use for the ACK to complete the data/ACK
+   *          handshake.
+   */
+  WifiTxVector GetAckTxVector (Mac48Address address, WifiMode dataMode);
   /**
    * \param address
    * \param dataMode the transmission mode used to send an ACK we just received
    * \returns the transmission mode to use for the ACK to complete the data/ACK
    *          handshake.
    */
-  WifiMode GetAckMode (Mac48Address address, WifiMode dataMode);
+  WifiTxVector GetBlockAckTxVector (Mac48Address address, WifiMode dataMode);
+  /**
+   * \returns the default transmission power
+   */ 
+  uint8_t GetDefaultTxPowerLevel (void) const;
+  /**
+   * \param address of the remote station
+   * \returns information regarding the remote station associated with the given address
+   */
+  WifiRemoteStationInfo GetInfo (Mac48Address address);
+  /**
+   * Set the default transmission power level
+   */
+  void SetDefaultTxPowerLevel (uint8_t txPower);
+ /**
+  * \returns the number of transmit antennas supported by the phy layer
+  */
+ uint32_t GetNumberOfTransmitAntennas (void);
 
-  WifiRemoteStationInfo GetInfo (Mac48Address address);
-protected:
+ protected:
   virtual void DoDispose (void);
   // for convenience
   WifiMode GetSupported (const WifiRemoteStation *station, uint32_t i) const;
   uint32_t GetNSupported (const WifiRemoteStation *station) const;
+  uint8_t GetMcsSupported (const WifiRemoteStation *station, uint32_t i) const;
+  uint32_t GetNMcsSupported (const WifiRemoteStation *station) const;
+
+  bool GetShortGuardInterval (const WifiRemoteStation *station) const;
+  bool GetStbc (const WifiRemoteStation *station) const;
+  bool GetGreenfield (const WifiRemoteStation *station) const;
+  uint32_t GetNumberOfReceiveAntennas (const WifiRemoteStation *station) const;
+  uint32_t GetNumberOfTransmitAntennas (const WifiRemoteStation *station) const;
+  uint32_t GetLongRetryCount (const WifiRemoteStation *station) const;
+  uint32_t GetShortRetryCount (const WifiRemoteStation *station) const;
 private:
   /**
    * \param station the station with which we need to communicate
@@ -359,7 +416,7 @@
    * \return a new station data structure
    */
   virtual WifiRemoteStation* DoCreateStation (void) const = 0;
-  /**
+ /**
    * \param station the station with which we need to communicate
    * \param size size of the packet or fragment we want to send
    * \returns the transmission mode to use to send a packet to the station
@@ -367,7 +424,7 @@
    * Note: This method is called before sending a unicast packet or a fragment
    *       of a unicast packet to decide which transmission mode to use.
    */
-  virtual WifiMode DoGetDataMode (WifiRemoteStation *station,
+  virtual WifiTxVector DoGetDataTxVector (WifiRemoteStation *station,
                                   uint32_t size) = 0;
   /**
    * \param station the station with which we need to communicate
@@ -376,7 +433,47 @@
    * Note: This method is called before sending an rts to a station
    *       to decide which transmission mode to use for the rts.
    */
-  virtual WifiMode DoGetRtsMode (WifiRemoteStation *station) = 0;
+  virtual WifiTxVector DoGetRtsTxVector (WifiRemoteStation *station) = 0;
+
+  
+  /** 
+   * \param address the address of the recipient of the CTS
+   * \param ctsMode the mode to be used for the CTS 
+   * 
+   * \return the power level to be used to send the CTS
+   */
+  virtual uint8_t DoGetCtsTxPowerLevel (Mac48Address address, WifiMode ctsMode);
+
+  /** 
+   * \param address the address of the recipient of the ACK
+   * \param ctsMode the mode to be used for the ACK 
+   * 
+   * \return the power level to be used to send the ACK
+   */  
+  virtual uint8_t DoGetAckTxPowerLevel (Mac48Address address, WifiMode ackMode);
+
+  /** 
+   * \param address the address of the recipient of the Block ACK
+   * \param ctsMode the mode to be used for the Block ACK 
+   * 
+   * \return the power level to be used to send the Block ACK
+   */  
+  virtual uint8_t DoGetBlockAckTxPowerLevel (Mac48Address address, WifiMode blockAckMode);
+
+  virtual bool DoGetCtsTxGuardInterval (Mac48Address address, WifiMode ctsMode);
+
+  virtual uint8_t DoGetCtsTxNss(Mac48Address address, WifiMode ctsMode);
+  virtual uint8_t DoGetCtsTxNess(Mac48Address address, WifiMode ctsMode);
+  virtual bool  DoGetCtsTxStbc(Mac48Address address, WifiMode ctsMode);
+  virtual bool DoGetAckTxGuardInterval(Mac48Address address, WifiMode ackMode);
+  virtual uint8_t DoGetAckTxNss(Mac48Address address, WifiMode ackMode);
+  virtual uint8_t DoGetAckTxNess(Mac48Address address, WifiMode ackMode);
+  virtual bool DoGetAckTxStbc(Mac48Address address, WifiMode ackMode);
+  virtual bool DoGetBlockAckTxGuardInterval(Mac48Address address, WifiMode blockAckMode);
+  virtual uint8_t DoGetBlockAckTxNss(Mac48Address address, WifiMode blockAckMode);
+  virtual uint8_t DoGetBlockAckTxNess(Mac48Address address, WifiMode blockAckMode);
+  virtual bool DoGetBlockAckTxStbc(Mac48Address address, WifiMode blockAckMode);
+
   virtual void DoReportRtsFailed (WifiRemoteStation *station) = 0;
   virtual void DoReportDataFailed (WifiRemoteStation *station) = 0;
   virtual void DoReportRtsOk (WifiRemoteStation *station,
@@ -413,6 +510,7 @@
    */
   Ptr<WifiPhy> m_wifiPhy;
   WifiMode m_defaultTxMode;
+  uint8_t m_defaultTxMcs;
 
   /**
    * This member is the list of WifiMode objects that comprise the
@@ -423,12 +521,15 @@
    * WifiRemoteStationManager::GetBasicMode().
    */
   WifiModeList m_bssBasicRateSet;
+  WifiMcsList m_bssBasicMcsSet;
 
+  bool m_htSupported;
   bool m_isLowLatency;
   uint32_t m_maxSsrc;
   uint32_t m_maxSlrc;
   uint32_t m_rtsCtsThreshold;
   uint32_t m_fragmentationThreshold;
+  uint8_t m_defaultTxPowerLevel;
   WifiMode m_nonUnicastMode;
   double m_avgSlrcCoefficient;
   /**
@@ -472,9 +573,15 @@
    * WifiRemoteStationManager::GetSupported().
    */
   WifiModeList m_operationalRateSet;
-
+  WifiMcsList m_operationalMcsSet;
   Mac48Address m_address;
   WifiRemoteStationInfo m_info;
+  bool m_shortGuardInterval;
+  uint32_t m_rx;
+  uint32_t m_tx;
+  bool m_stbc;
+  bool m_greenfield;
+
 };
 
 /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wifi/model/wifi-tx-vector.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -0,0 +1,119 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as 
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>
+ *       : Ghada Badawy <gbadawy@gmail.com>
+ */
+
+#include "ns3/wifi-tx-vector.h"
+
+namespace ns3 {
+
+WifiTxVector::WifiTxVector ()
+{
+}
+
+WifiTxVector::WifiTxVector (WifiMode m, uint8_t l, uint8_t r, bool sg, uint8_t ns, uint8_t ne, bool Stbc)
+  : m_mode (m),
+    m_txPowerLevel (l),
+    m_retries (r),
+    m_shortGuardInterval(sg),
+    m_nss(ns),
+    m_ness(ne),
+    m_stbc(Stbc)
+{
+}
+
+WifiMode
+WifiTxVector::GetMode (void) const
+{
+  return m_mode;
+}
+uint8_t 
+WifiTxVector::GetTxPowerLevel (void) const
+{
+  return m_txPowerLevel;
+}
+uint8_t 
+WifiTxVector::GetRetries (void) const
+{
+  return m_retries;
+}
+bool 
+WifiTxVector::IsShortGuardInterval (void) const
+{
+ return m_shortGuardInterval;
+}
+uint8_t 
+WifiTxVector::GetNss (void) const
+{
+  return m_nss;
+}
+uint8_t 
+WifiTxVector::GetNess (void) const
+{
+  return m_ness;
+}
+bool 
+WifiTxVector::IsStbc (void) const
+{
+  return m_stbc;
+}
+
+void 
+WifiTxVector::SetMode (WifiMode mode)
+{
+  m_mode=mode;
+}
+void 
+WifiTxVector::SetTxPowerLevel (uint8_t powerlevel)
+{
+  m_txPowerLevel=powerlevel;
+}
+void 
+WifiTxVector::SetRetries (uint8_t retries)
+{
+  m_retries = retries;
+}
+void 
+WifiTxVector::SetShortGuardInterval (bool guardinterval)
+{
+  m_shortGuardInterval=guardinterval;
+}
+void 
+WifiTxVector::SetNss (uint8_t nss)
+{
+  m_nss= nss;
+}
+void 
+WifiTxVector::SetNess (uint8_t ness)
+{
+  m_ness=ness;
+}
+void 
+WifiTxVector::SetStbc (bool stbc)
+{
+  m_stbc=stbc;
+}
+
+std::ostream & operator << ( std::ostream &os, const WifiTxVector &v)
+{ 
+  os << "mode:" << v.GetMode() << " txpwrlvl:" << v.GetTxPowerLevel() << " retries:" << v.GetRetries() << " Short GI: " << v.IsShortGuardInterval() << " Nss: " << v.GetNss() << " Ness: " << v.GetNess() << " STBC: " << v.IsStbc();
+  return os;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wifi/model/wifi-tx-vector.h	Tue Aug 13 22:05:25 2013 -0700
@@ -0,0 +1,131 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 CTTC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as 
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>
+ *       : Ghada Badawy <gbadawy@gmail.com>
+ */
+
+#ifndef WIFI_TX_VECTOR_H
+#define WIFI_TX_VECTOR_H
+
+#include <ns3/wifi-mode.h>
+#include <ostream>
+
+namespace ns3 {
+
+
+/**
+ * This class mimics the TXVECTOR which is to be
+ * passed to the PHY in order to define the parameters which are to be
+ * used for a transmission. See IEEE 802.11-2007 15.2.6 "Transmit PLCP",
+ * and also 15.4.4.2 "PMD_SAP peer-to-peer service primitive
+ * parameters".
+ *
+ * \note the above reference is valid for the DSSS PHY only (clause
+ * 15). TXVECTOR is defined also for the other PHYs, however they
+ * don't include the TXPWRLVL explicitly in the TXVECTOR. This is
+ * somewhat strange, since all PHYs actually have a
+ * PMD_TXPWRLVL.request primitive. We decide to include the power
+ * level in WifiTxVector for all PHYs, since it serves better our
+ * purposes, and furthermore it seems close to the way real devices
+ * work (e.g., madwifi).
+ */
+class WifiTxVector
+{
+public:
+  WifiTxVector ();
+  WifiTxVector (WifiMode m, uint8_t l, uint8_t r, bool sg, uint8_t ns, uint8_t ne, bool Stbc);
+  /**
+   *  \returns the txvector payload mode
+   */
+  WifiMode GetMode (void) const;
+ /**
+  * Sets the selected payload transmission mode
+  */
+  void SetMode (WifiMode mode);
+  /**
+   *  \returns the transmission power level
+   */
+  uint8_t GetTxPowerLevel (void) const;
+  /**
+   * Sets the selected transmission power level
+   */
+  void SetTxPowerLevel (uint8_t powerlevel);
+  /**
+   *  \returns the number of retries
+   */
+  uint8_t GetRetries (void) const;
+   /**
+   * Sets the number of retries
+   */
+  void SetRetries (uint8_t retries);
+  /**
+   *  \returns if ShortGuardInterval is used or not
+   */
+  bool IsShortGuardInterval (void) const;
+   /**
+   * Sets if short gurad interval is being used
+   */
+  void SetShortGuardInterval (bool guardinterval);
+ /**
+   *  \returns the number of Nss
+   */
+  uint8_t GetNss (void) const;
+   /**
+   * Sets the number of Nss refer to IEEE802.11n Table 20-28 for explanation and range
+   */
+  void SetNss (uint8_t nss);
+  /**
+   *  \returns the number of Ness  
+   */
+  uint8_t GetNess (void) const;
+   /**
+   * Sets the Ness number refer to IEEE802.11n Table 20-6 for explanation
+   */
+  void SetNess (uint8_t ness);
+  /**
+   *  \returns if STBC is used or not
+   */
+  bool IsStbc (void) const;
+  /**
+   * Sets if STBC is being used
+   */
+  void SetStbc (bool stbcsatuts);
+
+  
+private:
+
+  WifiMode m_mode;         /**< The DATARATE parameter in Table 15-4. 
+                           It is the value that will be passed
+                           to PMD_RATE.request */ 
+  uint8_t  m_txPowerLevel;  /**< The TXPWR_LEVEL parameter in Table 15-4. 
+                           It is the value that will be passed
+                           to PMD_TXPWRLVL.request */ 
+  uint8_t  m_retries;      /**< The DATA_RETRIES/RTS_RETRIES parameter
+                           for Click radiotap information */
+  bool     m_shortGuardInterval; //true if short GI is going to be used
+  uint8_t  m_nss; //number of streams
+  uint8_t  m_ness; //number of stream in beamforming
+  bool     m_stbc; //STBC used or not
+
+};
+
+std::ostream & operator << (std::ostream & os,const WifiTxVector &v); 
+
+} // namespace ns3
+
+#endif // WIFI_TX_VECTOR_H
--- a/src/wifi/model/yans-wifi-channel.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/yans-wifi-channel.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -76,11 +76,12 @@
 
 void
 YansWifiChannel::Send (Ptr<YansWifiPhy> sender, Ptr<const Packet> packet, double txPowerDbm,
-                       WifiMode wifiMode, WifiPreamble preamble) const
+                       WifiTxVector txVector, WifiPreamble preamble) const
 {
   Ptr<MobilityModel> senderMobility = sender->GetMobility ()->GetObject<MobilityModel> ();
   NS_ASSERT (senderMobility != 0);
   uint32_t j = 0;
+  WifiMode wifiMode=txVector.GetMode();
   for (PhyList::const_iterator i = m_phyList.begin (); i != m_phyList.end (); i++, j++)
     {
       if (sender != (*i))
@@ -109,16 +110,16 @@
             }
           Simulator::ScheduleWithContext (dstNode,
                                           delay, &YansWifiChannel::Receive, this,
-                                          j, copy, rxPowerDbm, wifiMode, preamble);
+                                          j, copy, rxPowerDbm, txVector, preamble);
         }
     }
 }
 
 void
 YansWifiChannel::Receive (uint32_t i, Ptr<Packet> packet, double rxPowerDbm,
-                          WifiMode txMode, WifiPreamble preamble) const
+                          WifiTxVector txVector, WifiPreamble preamble) const
 {
-  m_phyList[i]->StartReceivePacket (packet, rxPowerDbm, txMode, preamble);
+  m_phyList[i]->StartReceivePacket (packet, rxPowerDbm, txVector, preamble);
 }
 
 uint32_t
--- a/src/wifi/model/yans-wifi-channel.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/yans-wifi-channel.h	Tue Aug 13 22:05:25 2013 -0700
@@ -26,6 +26,7 @@
 #include "wifi-channel.h"
 #include "wifi-mode.h"
 #include "wifi-preamble.h"
+#include "wifi-tx-vector.h"
 
 namespace ns3 {
 
@@ -82,7 +83,7 @@
    * e.g. PHYs that are operating on the same channel.
    */
   void Send (Ptr<YansWifiPhy> sender, Ptr<const Packet> packet, double txPowerDbm,
-             WifiMode wifiMode, WifiPreamble preamble) const;
+             WifiTxVector txVector, WifiPreamble preamble) const;
 
  /**
   * Assign a fixed random variable stream number to the random variables
@@ -100,7 +101,7 @@
 
   typedef std::vector<Ptr<YansWifiPhy> > PhyList;
   void Receive (uint32_t i, Ptr<Packet> packet, double rxPowerDbm,
-                WifiMode txMode, WifiPreamble preamble) const;
+                WifiTxVector txVector, WifiPreamble preamble) const;
 
 
   PhyList m_phyList;
--- a/src/wifi/model/yans-wifi-phy.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/yans-wifi-phy.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -16,6 +16,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Ghada Badawy <gbadawy@gmail.com>
  */
 
 #include "yans-wifi-phy.h"
@@ -34,6 +35,7 @@
 #include "ns3/pointer.h"
 #include "ns3/net-device.h"
 #include "ns3/trace-source-accessor.h"
+#include "ns3/boolean.h"
 #include <cmath>
 
 NS_LOG_COMPONENT_DEFINE ("YansWifiPhy");
@@ -119,6 +121,47 @@
                    MakeUintegerAccessor (&YansWifiPhy::SetChannelNumber,
                                          &YansWifiPhy::GetChannelNumber),
                    MakeUintegerChecker<uint16_t> ())
+    .AddAttribute ("Frequency", "The operating frequency.",
+                   UintegerValue (2407),
+                   MakeUintegerAccessor (&YansWifiPhy::GetFrequency,
+                                        &YansWifiPhy::SetFrequency),
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("Transmitters", "The number of transmitters.",
+                   UintegerValue (1),
+                   MakeUintegerAccessor (&YansWifiPhy::GetNumberOfTransmitAntennas,
+                                        &YansWifiPhy::SetNumberOfTransmitAntennas),
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("Recievers", "The number of recievers.",
+                   UintegerValue (1),
+                   MakeUintegerAccessor (&YansWifiPhy::GetNumberOfReceiveAntennas,
+                                        &YansWifiPhy::SetNumberOfReceiveAntennas),
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("ShortGuardEnabled", "Whether or not short guard interval is enabled.",
+                   BooleanValue (false),
+                   MakeBooleanAccessor (&YansWifiPhy::GetGuardInterval,
+                                        &YansWifiPhy::SetGuardInterval),
+                   MakeBooleanChecker ())
+    .AddAttribute ("LdpcEnabled", "Whether or not LDPC is enabled.",
+                   BooleanValue (false),
+                   MakeBooleanAccessor (&YansWifiPhy::GetLdpc,
+                                        &YansWifiPhy::SetLdpc),
+                   MakeBooleanChecker ())
+    .AddAttribute ("STBCEnabled", "Whether or not STBC is enabled.",
+                   BooleanValue (false),
+                   MakeBooleanAccessor (&YansWifiPhy::GetStbc,
+                                        &YansWifiPhy::SetStbc),
+                   MakeBooleanChecker ())
+    .AddAttribute ("GreenfieldEnabled", "Whether or not STBC is enabled.",
+                   BooleanValue (false),
+                   MakeBooleanAccessor (&YansWifiPhy::GetGreenfield,
+                                        &YansWifiPhy::SetGreenfield),
+                   MakeBooleanChecker ())
+    .AddAttribute ("ChannelBonding", "Whether 20MHz or 40MHz.",
+                   BooleanValue (false),
+                   MakeBooleanAccessor (&YansWifiPhy::GetChannelBonding,
+                                        &YansWifiPhy::SetChannelBonding),
+                   MakeBooleanChecker ())
+
 
   ;
   return tid;
@@ -145,6 +188,7 @@
   NS_LOG_FUNCTION (this);
   m_channel = 0;
   m_deviceRateSet.clear ();
+  m_deviceMcsSet.clear();
   m_device = 0;
   m_mobility = 0;
   m_state = 0;
@@ -180,6 +224,15 @@
     case WIFI_PHY_STANDARD_80211p_SCH:
       Configure80211p_SCH ();
       break;
+    case WIFI_PHY_STANDARD_80211n_2_4GHZ:
+      m_channelStartingFrequency=2407;
+      Configure80211n ();
+      break;
+    case WIFI_PHY_STANDARD_80211n_5GHZ:
+      m_channelStartingFrequency=5e3;
+      Configure80211n ();
+      break;
+
     default:
       NS_ASSERT (false);
       break;
@@ -397,13 +450,14 @@
 void
 YansWifiPhy::StartReceivePacket (Ptr<Packet> packet,
                                  double rxPowerDbm,
-                                 WifiMode txMode,
+                                 WifiTxVector txVector,
                                  enum WifiPreamble preamble)
 {
-  NS_LOG_FUNCTION (this << packet << rxPowerDbm << txMode << preamble);
+  NS_LOG_FUNCTION (this << packet << rxPowerDbm << txVector.GetMode()<< preamble);
   rxPowerDbm += m_rxGainDb;
   double rxPowerW = DbmToW (rxPowerDbm);
-  Time rxDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble);
+  Time rxDuration = CalculateTxDuration (packet->GetSize (), txVector, preamble);
+WifiMode txMode=txVector.GetMode();
   Time endRx = Simulator::Now () + rxDuration;
 
   Ptr<InterferenceHelper::Event> event;
@@ -411,7 +465,8 @@
                               txMode,
                               preamble,
                               rxDuration,
-                              rxPowerW);
+                              rxPowerW,
+		          txVector);  // we need it to calculate duration of HT training symbols
 
   switch (m_state->GetState ())
     {
@@ -495,9 +550,9 @@
 }
 
 void
-YansWifiPhy::SendPacket (Ptr<const Packet> packet, WifiMode txMode, WifiPreamble preamble, uint8_t txPower)
+YansWifiPhy::SendPacket (Ptr<const Packet> packet, WifiMode txMode, WifiPreamble preamble, WifiTxVector txVector)
 {
-  NS_LOG_FUNCTION (this << packet << txMode << preamble << (uint32_t)txPower);
+  NS_LOG_FUNCTION (this << packet << txMode << preamble << (uint32_t)txVector.GetTxPowerLevel());
   /* Transmission can happen if:
    *  - we are syncing on a packet. It is the responsability of the
    *    MAC layer to avoid doing this but the PHY does nothing to
@@ -506,18 +561,18 @@
    */
   NS_ASSERT (!m_state->IsStateTx () && !m_state->IsStateSwitching ());
 
-  Time txDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble);
+  Time txDuration = CalculateTxDuration (packet->GetSize (), txVector, preamble);
   if (m_state->IsStateRx ())
     {
       m_endRxEvent.Cancel ();
       m_interference.NotifyRxEnd ();
     }
   NotifyTxBegin (packet);
-  uint32_t dataRate500KbpsUnits = txMode.GetDataRate () / 500000;
+  uint32_t dataRate500KbpsUnits = txVector.GetMode().GetDataRate () * txVector.GetNss() / 500000;
   bool isShortPreamble = (WIFI_PREAMBLE_SHORT == preamble);
-  NotifyMonitorSniffTx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, isShortPreamble);
-  m_state->SwitchToTx (txDuration, packet, txMode, preamble, txPower);
-  m_channel->Send (this, packet, GetPowerDbm (txPower) + m_txGainDb, txMode, preamble);
+  NotifyMonitorSniffTx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, isShortPreamble, txVector.GetTxPowerLevel());
+  m_state->SwitchToTx (txDuration, packet, txVector.GetMode(), preamble,  txVector.GetTxPowerLevel());
+  m_channel->Send (this, packet, GetPowerDbm ( txVector.GetTxPowerLevel()) + m_txGainDb, txVector, preamble);
 }
 
 uint32_t
@@ -782,7 +837,7 @@
   if (m_random->GetValue () > snrPer.per)
     {
       NotifyRxEnd (packet);
-      uint32_t dataRate500KbpsUnits = event->GetPayloadMode ().GetDataRate () / 500000;
+      uint32_t dataRate500KbpsUnits = event->GetPayloadMode ().GetDataRate () * event->GetTxVector().GetNss()/ 500000;
       bool isShortPreamble = (WIFI_PREAMBLE_SHORT == event->GetPreambleType ());
       double signalDbm = RatioToDb (event->GetRxPowerW ()) + 30;
       double noiseDbm = RatioToDb (event->GetRxPowerW () / snrPer.snr) - GetRxNoiseFigure () + 30;
@@ -804,4 +859,389 @@
   m_random->SetStream (stream);
   return 1;
 }
+
+void
+YansWifiPhy::SetFrequency (uint32_t freq)
+{
+  m_channelStartingFrequency = freq;
+}
+
+void
+YansWifiPhy::SetNumberOfTransmitAntennas (uint32_t tx)
+{
+  m_numberOfTransmitters = tx;
+}
+void
+YansWifiPhy::SetNumberOfReceiveAntennas (uint32_t rx)
+{
+  m_numberOfReceivers = rx;
+}
+
+void
+YansWifiPhy::SetLdpc (bool Ldpc)
+{
+  m_ldpc = Ldpc;
+}
+
+void
+YansWifiPhy::SetStbc (bool stbc)
+{
+  m_stbc = stbc;
+}
+
+void
+YansWifiPhy::SetGreenfield (bool greenfield)
+{
+  m_greenfield = greenfield;
+}
+bool
+YansWifiPhy::GetGuardInterval (void) const
+{
+  return m_guardInterval;
+}
+void
+YansWifiPhy::SetGuardInterval (bool GuardInterval)
+{
+  m_guardInterval = GuardInterval;
+}
+
+uint32_t
+YansWifiPhy::GetFrequency (void) const
+{
+  return m_channelStartingFrequency;
+}
+
+uint32_t
+YansWifiPhy::GetNumberOfTransmitAntennas (void) const
+{
+  return m_numberOfTransmitters;
+}
+uint32_t
+YansWifiPhy::GetNumberOfReceiveAntennas (void) const
+{
+  return m_numberOfReceivers;
+}
+
+bool
+YansWifiPhy::GetLdpc (void) const
+{
+  return m_ldpc;
+}
+bool
+YansWifiPhy::GetStbc (void) const
+{
+  return m_stbc;
+}
+
+bool
+YansWifiPhy::GetGreenfield (void) const
+{
+  return m_greenfield;
+}
+
+bool
+YansWifiPhy::GetChannelBonding(void) const
+{
+  return m_channelBonding;
+}
+
+void
+YansWifiPhy::SetChannelBonding(bool channelbonding) 
+{
+  m_channelBonding= channelbonding;
+}
+
+void
+YansWifiPhy::Configure80211n (void)
+{
+  NS_LOG_FUNCTION (this);
+  m_deviceRateSet.push_back (WifiPhy::GetDsssRate1Mbps ());
+  m_deviceRateSet.push_back (WifiPhy::GetDsssRate2Mbps ());
+  m_deviceRateSet.push_back (WifiPhy::GetDsssRate5_5Mbps ());
+  m_deviceRateSet.push_back (WifiPhy::GetErpOfdmRate6Mbps ());
+  m_deviceRateSet.push_back (WifiPhy::GetDsssRate11Mbps ());
+  m_deviceRateSet.push_back (WifiPhy::GetErpOfdmRate12Mbps ());
+  m_deviceRateSet.push_back (WifiPhy::GetErpOfdmRate24Mbps ());
+  m_bssMembershipSelectorSet.push_back(HT_PHY);
+  for (uint8_t i=0; i <8; i++)
+    {
+      m_deviceMcsSet.push_back(i);
+    }
+
+}
+uint32_t
+YansWifiPhy::GetNBssMembershipSelectors (void) const
+{
+  return  m_bssMembershipSelectorSet.size ();
+}
+uint32_t
+YansWifiPhy::GetBssMembershipSelector (uint32_t selector) const
+{
+  return  m_bssMembershipSelectorSet[selector];
+}
+WifiModeList
+YansWifiPhy::GetMembershipSelectorModes(uint32_t selector)
+{
+  uint32_t id=GetBssMembershipSelector(selector);
+  WifiModeList supportedmodes;
+  if (id == HT_PHY)
+  {
+    //mandatory MCS 0 to 7
+     supportedmodes.push_back (WifiPhy::GetOfdmRate6_5MbpsBW20MHz ());
+     supportedmodes.push_back (WifiPhy::GetOfdmRate13MbpsBW20MHz ());
+     supportedmodes.push_back (WifiPhy::GetOfdmRate19_5MbpsBW20MHz ());
+     supportedmodes.push_back (WifiPhy::GetOfdmRate26MbpsBW20MHz ());
+     supportedmodes.push_back (WifiPhy::GetOfdmRate39MbpsBW20MHz ());
+     supportedmodes.push_back (WifiPhy::GetOfdmRate52MbpsBW20MHz ());
+     supportedmodes.push_back (WifiPhy::GetOfdmRate58_5MbpsBW20MHz ());
+     supportedmodes.push_back (WifiPhy::GetOfdmRate65MbpsBW20MHz ());
+  }
+  return supportedmodes;
+}
+uint8_t
+YansWifiPhy::GetNMcs (void) const
+{
+  return  m_deviceMcsSet.size ();
+}
+uint8_t
+YansWifiPhy::GetMcs (uint8_t mcs) const
+{
+  return  m_deviceMcsSet[mcs];
+}
+uint32_t 
+YansWifiPhy::WifiModeToMcs (WifiMode mode)
+{
+    uint32_t mcs = 0;
+   if (mode.GetUniqueName() == "OfdmRate135MbpsBW40MHzShGi" || mode.GetUniqueName() == "OfdmRate65MbpsBW20MHzShGi" )
+     {
+             mcs=6;
+     }
+  else
+    {
+     switch (mode.GetDataRate())
+       {
+         case 6500000:
+         case 7200000:
+         case 13500000:
+         case 15000000:
+           mcs=0;
+           break;
+         case 13000000:
+         case 14400000:
+         case 27000000:
+         case 30000000:
+           mcs=1;
+           break;
+         case 19500000:
+         case 21700000:
+         case 40500000:
+         case 45000000:
+           mcs=2;
+           break;
+         case 26000000:
+         case 28900000:
+         case 54000000:
+         case 60000000:
+           mcs=3;
+           break;
+         case 39000000:
+         case 43300000:
+         case 81000000:
+         case 90000000:        
+           mcs=4;
+           break;
+         case 52000000:
+         case 57800000:
+         case 108000000:
+         case 120000000:
+           mcs=5;
+           break; 
+         case 58500000:
+         case 121500000:
+           mcs=6;
+           break;
+         case 65000000:
+         case 72200000:
+         case 135000000:
+         case 150000000:
+           mcs=7;
+           break;     
+       }
+    }
+  return mcs;
+}
+WifiMode
+YansWifiPhy::McsToWifiMode (uint8_t mcs)
+{
+   WifiMode mode;
+   switch (mcs)
+     { 
+       case 7:
+          if (!GetGuardInterval() && !GetChannelBonding())
+           {
+              mode =  WifiPhy::GetOfdmRate65MbpsBW20MHz ();
+            }
+         else if(GetGuardInterval() && !GetChannelBonding())
+            {
+              mode = WifiPhy::GetOfdmRate72_2MbpsBW20MHz ();
+            }
+          else if (!GetGuardInterval() && GetChannelBonding())
+            {
+              mode = WifiPhy::GetOfdmRate135MbpsBW40MHz ();
+            }
+          else
+            {
+              mode = WifiPhy::GetOfdmRate150MbpsBW40MHz ();
+            }
+          break;
+       case 6:
+          if (!GetGuardInterval() && !GetChannelBonding())
+           {
+              mode = WifiPhy::GetOfdmRate58_5MbpsBW20MHz ();
+ 
+            }
+         else if(GetGuardInterval() && !GetChannelBonding())
+            {
+              mode =  WifiPhy::GetOfdmRate65MbpsBW20MHzShGi ();
+       
+            }
+          else if (!GetGuardInterval() && GetChannelBonding())
+            {
+              mode = WifiPhy::GetOfdmRate121_5MbpsBW40MHz ();
+     
+            }
+          else
+            {
+              mode= WifiPhy::GetOfdmRate135MbpsBW40MHzShGi ();
+          
+            }
+          break;
+       case 5:
+          if (!GetGuardInterval() && !GetChannelBonding())
+           {
+              mode = WifiPhy::GetOfdmRate52MbpsBW20MHz ();
+  
+            }
+         else if(GetGuardInterval() && !GetChannelBonding())
+            {
+              mode = WifiPhy::GetOfdmRate57_8MbpsBW20MHz ();
+            }
+          else if (!GetGuardInterval() && GetChannelBonding())
+            {
+              mode = WifiPhy::GetOfdmRate108MbpsBW40MHz ();
+     
+            }
+          else
+            {
+              mode = WifiPhy::GetOfdmRate120MbpsBW40MHz ();
+       
+            }
+          break;
+       case 4:
+          if (!GetGuardInterval() && !GetChannelBonding())
+           {
+              mode = WifiPhy::GetOfdmRate39MbpsBW20MHz ();
+            }
+         else if(GetGuardInterval() && !GetChannelBonding())
+            {
+              mode = WifiPhy::GetOfdmRate43_3MbpsBW20MHz ();
+            }
+          else if (!GetGuardInterval() && GetChannelBonding())
+            {
+              mode = WifiPhy::GetOfdmRate81MbpsBW40MHz ();
+  
+            }
+          else
+            {
+              mode = WifiPhy::GetOfdmRate90MbpsBW40MHz ();
+         
+            }
+          break;
+       case 3:
+          if (!GetGuardInterval() && !GetChannelBonding())
+           {
+              mode =  WifiPhy::GetOfdmRate26MbpsBW20MHz ();
+  
+            }
+         else if(GetGuardInterval() && !GetChannelBonding())
+            {
+              mode = WifiPhy::GetOfdmRate28_9MbpsBW20MHz ();
+      
+            }
+          else if (!GetGuardInterval() && GetChannelBonding())
+            {
+              mode = WifiPhy::GetOfdmRate54MbpsBW40MHz ();
+     
+            }
+          else
+            {
+              mode = WifiPhy::GetOfdmRate60MbpsBW40MHz ();
+            }
+          break;
+       case 2:
+          if (!GetGuardInterval() && !GetChannelBonding())
+           {
+              mode = WifiPhy::GetOfdmRate19_5MbpsBW20MHz ();
+ 
+            }
+         else if(GetGuardInterval() && !GetChannelBonding())
+            {
+              mode = WifiPhy::GetOfdmRate21_7MbpsBW20MHz ();
+     
+            }
+          else if (!GetGuardInterval() && GetChannelBonding())
+            {
+              mode =  WifiPhy::GetOfdmRate40_5MbpsBW40MHz ();
+  
+            }
+          else
+            {
+              mode = WifiPhy::GetOfdmRate45MbpsBW40MHz ();
+           
+            }
+          break;
+       case 1:
+          if (!GetGuardInterval() && !GetChannelBonding())
+           {
+            mode = WifiPhy::GetOfdmRate13MbpsBW20MHz ();
+  
+            }
+         else if(GetGuardInterval() && !GetChannelBonding())
+            {
+              mode =  WifiPhy::GetOfdmRate14_4MbpsBW20MHz ();
+            }
+          else if (!GetGuardInterval() && GetChannelBonding())
+            {
+              mode = WifiPhy::GetOfdmRate27MbpsBW40MHz ();
+     
+            }
+          else
+            {
+              mode = WifiPhy::GetOfdmRate30MbpsBW40MHz ();
+            }
+          break;
+       case 0:
+       default:
+         if (!GetGuardInterval() && !GetChannelBonding())
+           {
+              mode = WifiPhy::GetOfdmRate6_5MbpsBW20MHz ();
+              
+            }
+         else if(GetGuardInterval() && !GetChannelBonding())
+            {
+              mode = WifiPhy::GetOfdmRate7_2MbpsBW20MHz ();
+            }
+          else if (!GetGuardInterval() && GetChannelBonding())
+            {
+              mode = WifiPhy::GetOfdmRate13_5MbpsBW40MHz ();
+ 
+            }
+          else
+            {
+              mode = WifiPhy::GetOfdmRate15MbpsBW40MHz ();
+            }
+         break;
+        }
+ return mode;
+}
 } // namespace ns3
--- a/src/wifi/model/yans-wifi-phy.h	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/model/yans-wifi-phy.h	Tue Aug 13 22:05:25 2013 -0700
@@ -16,6 +16,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: ghada Badawy <gbadawy@gmail.com>
  */
 
 #ifndef YANS_WIFI_PHY_H
@@ -39,6 +40,8 @@
 
 namespace ns3 {
 
+#define HT_PHY 127
+
 class YansWifiChannel;
 class WifiPhyStateHelper;
 
@@ -91,7 +94,7 @@
 
   void StartReceivePacket (Ptr<Packet> packet,
                            double rxPowerDbm,
-                           WifiMode mode,
+                           WifiTxVector txVector,
                            WifiPreamble preamble);
 
   void SetRxNoiseFigure (double noiseFigureDb);
@@ -122,7 +125,7 @@
   virtual uint32_t GetNTxPower (void) const;
   virtual void SetReceiveOkCallback (WifiPhy::RxOkCallback callback);
   virtual void SetReceiveErrorCallback (WifiPhy::RxErrorCallback callback);
-  virtual void SendPacket (Ptr<const Packet> packet, WifiMode mode, enum WifiPreamble preamble, uint8_t txPowerLevel);
+  virtual void SendPacket (Ptr<const Packet> packet, WifiMode mode, enum WifiPreamble preamble, WifiTxVector txvector);
   virtual void RegisterListener (WifiPhyListener *listener);
   virtual bool IsStateCcaBusy (void);
   virtual bool IsStateIdle (void);
@@ -149,6 +152,90 @@
   */
   int64_t AssignStreams (int64_t stream);
 
+  /**
+   * \param the operating frequency on this node (2.4 GHz or 5GHz).
+   */
+  virtual void SetFrequency (uint32_t freq);
+  /**
+   * \returns the operating frequency on this node
+   */
+  virtual uint32_t GetFrequency (void) const;
+  /**
+   * \param the number of transmitters on this node.
+   */
+  virtual void SetNumberOfTransmitAntennas (uint32_t tx);
+  virtual uint32_t GetNumberOfTransmitAntennas (void) const;
+  /**
+   * \param the number of recievers on this node.
+   */
+  virtual void SetNumberOfReceiveAntennas (uint32_t rx) ;
+  /**
+   * \returns the number of recievers on this node.
+   */
+  virtual uint32_t GetNumberOfReceiveAntennas (void) const;
+  /**
+   * \param set short/long guard interval.
+   */
+  virtual void SetGuardInterval (bool GuardInterval);
+   virtual bool GetGuardInterval (void) const;
+  /**
+   * \param sets LDPC is supported or not
+   */
+  virtual void SetLdpc (bool Ldpc);
+  /**
+   * \returns if LDPC is supported or not
+   */
+  virtual bool GetLdpc (void) const;
+  /**
+   * \param sets STBC is supported or not
+   */
+  virtual void SetStbc (bool stbc);
+ /**
+   * \returns if STBC is supported or not
+   */
+  virtual bool GetStbc (void) const;
+  /**
+   * \param sets Greenfield is supported or not
+   */
+  virtual void SetGreenfield (bool greenfield);
+  /**
+   * \returns if Greenfield is supported or not
+   */
+  virtual bool GetGreenfield (void) const;
+  /**
+   * \param sets channel bonding is supported or not
+   */
+  virtual bool GetChannelBonding (void) const ;
+  /**
+   * \returns if channel bonding is supported or not
+   */
+  virtual void SetChannelBonding (bool channelbonding) ;
+
+  virtual uint32_t GetNBssMembershipSelectors (void) const;
+  virtual uint32_t GetBssMembershipSelector (uint32_t selector) const;
+  virtual WifiModeList GetMembershipSelectorModes(uint32_t selector);
+  /**
+   * \returns the number of MCS supported by this phy
+   */
+  virtual uint8_t GetNMcs (void) const;
+  virtual uint8_t GetMcs (uint8_t mcs) const;
+  /**
+  * For a given WifiMode finds the corresponding MCS value and returns it 
+  * as defined in the IEEE 802.11n standard 
+  *
+  * \param mode the WifiMode
+  * \returns the MCS number that corresponds to the given WifiMode
+  */
+  virtual uint32_t WifiModeToMcs (WifiMode mode);
+ /**
+  * For a given MCS finds the corresponding WifiMode and returns it 
+  * as defined in the IEEE 802.11n standard. 
+  * 
+  * \param mcs the MCS number 
+  * \returns the WifiMode that corresponds to the given mcs number
+  */
+  virtual WifiMode McsToWifiMode (uint8_t mcs);
+
 private:
   YansWifiPhy (const YansWifiPhy &o);
   virtual void DoDispose (void);
@@ -160,6 +247,7 @@
   void ConfigureHolland (void);
   void Configure80211p_CCH (void);
   void Configure80211p_SCH (void);
+  void Configure80211n (void);
   double GetEdThresholdW (void) const;
   double DbmToW (double dbm) const;
   double DbToRatio (double db) const;
@@ -178,9 +266,25 @@
   uint32_t m_nTxPower;
 
   Ptr<YansWifiChannel> m_channel;
-  uint16_t m_channelNumber;
-  Ptr<Object> m_device;
-  Ptr<Object> m_mobility;
+  uint16_t             m_channelNumber;
+  Ptr<Object>          m_device;
+  Ptr<Object>          m_mobility;
+
+  // number of transmitters
+  uint32_t m_numberOfTransmitters;
+  // number of recievers
+  uint32_t m_numberOfReceivers;
+  //if true use LDPC
+  bool     m_ldpc;
+  // True if STBC is used
+  bool     m_stbc;
+  //True if GreenField format is supported
+  bool     m_greenfield;
+  //True is short guard interval is used
+  bool     m_guardInterval;
+  //True if channel bonding is used
+  bool     m_channelBonding;
+
 
   /**
    * This vector holds the set of transmission modes that this
@@ -219,7 +323,9 @@
    * mandatory rates".
    */
   WifiModeList m_deviceRateSet;
-
+  
+  std::vector<uint32_t> m_bssMembershipSelectorSet;
+  std::vector<uint8_t> m_deviceMcsSet;
   EventId m_endRxEvent;
   /// Provides uniform random variables.
   Ptr<UniformRandomVariable> m_random;
--- a/src/wifi/test/tx-duration-test.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/test/tx-duration-test.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -60,7 +60,7 @@
    *
    * @return true if values correspond, false otherwise
    */
-  bool CheckTxDuration (uint32_t size, WifiMode payloadMode,  WifiPreamble preamble, uint32_t knownDurationMicroSeconds);
+  bool CheckTxDuration (uint32_t size, WifiMode payloadMode,  WifiPreamble preamble, double knownDurationMicroSeconds);
 
 };
 
@@ -78,7 +78,9 @@
 bool
 TxDurationTest::CheckPayloadDuration (uint32_t size, WifiMode payloadMode, uint32_t knownDurationMicroSeconds)
 {
-  uint32_t calculatedDurationMicroSeconds = WifiPhy::GetPayloadDurationMicroSeconds (size, payloadMode);
+  WifiTxVector txVector;
+  txVector.SetMode (payloadMode);
+  uint32_t calculatedDurationMicroSeconds = WifiPhy::GetPayloadDurationMicroSeconds (size, txVector);
   if (calculatedDurationMicroSeconds != knownDurationMicroSeconds)
     {
       std::cerr << " size=" << size
@@ -92,9 +94,14 @@
 }
 
 bool
-TxDurationTest::CheckTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble, uint32_t knownDurationMicroSeconds)
+TxDurationTest::CheckTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble, double knownDurationMicroSeconds)
 {
-  uint32_t calculatedDurationMicroSeconds = WifiPhy::CalculateTxDuration (size, payloadMode, preamble).GetMicroSeconds ();
+  WifiTxVector txVector;
+  txVector.SetMode (payloadMode);
+  txVector.SetNss(1);
+  txVector.SetStbc(0);
+  txVector.SetNess(0);
+  double calculatedDurationMicroSeconds = WifiPhy::CalculateTxDuration (size, txVector, preamble).GetMicroSeconds ();
   if (calculatedDurationMicroSeconds != knownDurationMicroSeconds)
     {
       std::cerr << " size=" << size
@@ -112,6 +119,7 @@
 TxDurationTest::DoRun (void)
 {
   bool retval = true;
+  
 
   // IEEE Std 802.11-2007 Table 18-2 "Example of LENGTH calculations for CCK"
   retval = retval
@@ -177,6 +185,16 @@
     && CheckTxDuration (1536, WifiPhy::GetErpOfdmRate54Mbps (), WIFI_PREAMBLE_LONG, 254)
     && CheckTxDuration (76, WifiPhy::GetErpOfdmRate54Mbps (), WIFI_PREAMBLE_LONG, 38)
     && CheckTxDuration (14, WifiPhy::GetErpOfdmRate54Mbps (), WIFI_PREAMBLE_LONG, 30);
+
+  //802.11n durations
+  retval = retval
+    && CheckTxDuration (1536,WifiPhy::GetOfdmRate65MbpsBW20MHz (), WIFI_PREAMBLE_HT_MF,228) 
+    && CheckTxDuration (76, WifiPhy::GetOfdmRate65MbpsBW20MHz (), WIFI_PREAMBLE_HT_MF,48)
+    && CheckTxDuration (14, WifiPhy::GetOfdmRate65MbpsBW20MHz (), WIFI_PREAMBLE_HT_MF,40 )
+    //should be 218.8, 38,8 and 31.6  but microseconds are only represented as integers will have to change Time to change that
+    && CheckTxDuration (1536, WifiPhy::GetOfdmRate65MbpsBW20MHzShGi (), WIFI_PREAMBLE_HT_GF,218)
+    && CheckTxDuration (76, WifiPhy::GetOfdmRate65MbpsBW20MHzShGi (), WIFI_PREAMBLE_HT_GF,38)
+    && CheckTxDuration (14, WifiPhy::GetOfdmRate65MbpsBW20MHzShGi (), WIFI_PREAMBLE_HT_GF,31);
 }
 
 class TxDurationTestSuite : public TestSuite
--- a/src/wifi/test/wifi-test.cc	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/test/wifi-test.cc	Tue Aug 13 22:05:25 2013 -0700
@@ -427,7 +427,6 @@
 }
 
 //-----------------------------------------------------------------------------
-
 class WifiTestSuite : public TestSuite
 {
 public:
--- a/src/wifi/wscript	Tue Aug 13 10:37:49 2013 -0700
+++ b/src/wifi/wscript	Tue Aug 13 22:05:25 2013 -0700
@@ -61,6 +61,9 @@
         'model/block-ack-manager.cc',
         'model/block-ack-cache.cc',
         'model/snr-tag.cc',
+        'model/ht-capabilities.cc',
+        'model/wifi-tx-vector.cc',
+        'helper/ht-wifi-mac-helper.cc',
         'helper/athstats-helper.cc',
         'helper/wifi-helper.cc',
         'helper/yans-wifi-helper.cc',
@@ -134,6 +137,9 @@
         'model/block-ack-manager.h',
         'model/block-ack-cache.h',
         'model/snr-tag.h',
+        'model/ht-capabilities.h',
+        'model/wifi-tx-vector.h',
+        'helper/ht-wifi-mac-helper.h',
         'helper/athstats-helper.h',
         'helper/wifi-helper.h',
         'helper/yans-wifi-helper.h',