Merge with ns-3-dev
authorKirill Andreev <andreev@iitp.ru>
Wed, 29 Apr 2009 18:26:25 +0400
changeset 4987 1bee3ec2793d
parent 4986 73ca74882f12 (current diff)
parent 4428 e404c4e63681 (diff)
child 4988 9293f61456d7
Merge with ns-3-dev
bindings/python/ns3_module_common.py
examples/mesh.cc
examples/wscript
src/applications/udp-echo/udp-echo-server.cc
src/devices/mesh/mesh-point-device.cc
src/devices/wifi/dca-txop.h
src/devices/wifi/qos-utils.cc
src/devices/wifi/wifi-mac-header.cc
src/devices/wifi/wifi-mac-header.h
src/devices/wifi/wscript
src/helper/wscript
src/wscript
--- a/CHANGES.html	Wed Apr 29 18:59:48 2009 +0400
+++ b/CHANGES.html	Wed Apr 29 18:26:25 2009 +0400
@@ -56,7 +56,9 @@
 
 <h2>Changes to existing API:</h2>
 <ul>
-<li> deconflict NetDevice::ifIndex and Ipv4::ifIndex (bug 85). All function parameters named "ifIndex" that refer 
+
+<li><b>Deconflict NetDevice::ifIndex and Ipv4::ifIndex (bug 85).</b>
+<p>All function parameters named "ifIndex" that refer 
 to an Ipv4 interface are instead named "interface".
 <pre>
 - static const uint32_t Ipv4RoutingProtocol::IF_INDEX_ANY = 0xffffffff;
@@ -74,38 +76,63 @@
 + bool Ipv4::GetInterfaceForDestination (Ipv4Address dest, uint32_t &interface) const;
 (N.B. this function is not needed in the proposed Ipv4 routing refactoring)
 </pre>
-<li> allow multiple IPv4 addresses to be assigned to an interface (bug 188).  
-<ul>
-<li> Add class Ipv4InterfaceAddress:  
-This is a new class to resemble Linux's struct in_ifaddr.  It holds IP addressing information, including mask,
-broadcast address, scope, whether primary or secondary, etc.
-<pre>
+
+
+<li><b>Allow multiple IPv4 addresses to be assigned to an interface (bug 188)</b>
+  <ul>
+  <li> Add class Ipv4InterfaceAddress:  
+  This is a new class to resemble Linux's struct in_ifaddr.  It holds IP addressing information, including mask,
+  broadcast address, scope, whether primary or secondary, etc.
+  <pre>
 +  virtual uint32_t AddAddress (uint32_t interface, Ipv4InterfaceAddress address) = 0;
 +  virtual Ipv4InterfaceAddress GetAddress (uint32_t interface, uint32_t addressIndex) const = 0;
 +  virtual uint32_t GetNAddresses (uint32_t interface) const = 0;
-</pre>
-<li>Regarding legacy API usage, typically where you once did the following,
-using the public Ipv4 class interface (e.g.):
-<pre>
+  </pre>
+  <li>Regarding legacy API usage, typically where you once did the following,
+  using the public Ipv4 class interface (e.g.):
+  <pre>
   ipv4A->SetAddress (ifIndexA, Ipv4Address ("172.16.1.1"));
   ipv4A->SetNetworkMask (ifIndexA, Ipv4Mask ("255.255.255.255"));
-</pre>
-you now do:
-<pre>
+  </pre>
+  you now do:
+  <pre>
   Ipv4InterfaceAddress ipv4IfAddrA = Ipv4InterfaceAddress (Ipv4Address ("172.16.1.1"), Ipv4Mask ("255.255.255.255"));
   ipv4A->AddAddress (ifIndexA, ipv4IfAddrA);
-</pre>
-<li> At the helper API level, one often gets an address from an interface
-container.  We preserve the legacy GetAddress (uint32_t i) but it
-is documented that this will return only the first (address index 0)
-address on the interface, if there are multiple such addresses. 
-We provide also an overloaded variant for the multi-address case: 
+  </pre>
+  <li> At the helper API level, one often gets an address from an interface
+  container.  We preserve the legacy GetAddress (uint32_t i) but it
+  is documented that this will return only the first (address index 0)
+  address on the interface, if there are multiple such addresses. 
+  We provide also an overloaded variant for the multi-address case: 
 
-<pre>
+  <pre>
 Ipv4Address Ipv4InterfaceContainer::GetAddress (uint32_t i)
 + Ipv4Address Ipv4InterfaceContainer::GetAddress (uint32_t i, uint32_t j)
-</pre>
-</ul>
+  </pre>
+
+  </ul>
+
+<li><b>New WifiMacHelper objects</b>
+<p>The type of wifi MAC is now set by two new specific helpers, NqosWifiMacHelper for non QoS MACs and QosWifiMacHelper for Qos MACs. They are passed as argument to WifiHelper::Install methods.</li>
+  <pre>
+- void WifiHelper::SetMac (std::string type, std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),...)
+
+- NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &phyHelper, NodeContainer c) const
++ NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &phyHelper, const WifiMacHelper &macHelper, NodeContainer c) const
+
+- NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &phy, Ptr&lt;Node&gt; node) const
++ NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &phy, const WifiMacHelper &mac, Ptr&lt;Node&gt; node) const
+
+- NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &phy, std::string nodeName) const
++ NetDeviceContainer WifiHelper::Install (const WifiPhyHelper &phy, const WifiMacHelper &mac, std::string nodeName) const
+  </pre>
+  See src/helper/nqos-wifi-mac-helper.h and src/helper/qos-wifi-mac-helper.h for more details.
+  </p>
+
+<li><b>Remove Mac48Address::IsMulticast</b>
+  <p>This method was considered buggy and unsafe to call. Its replacement is Mac48Address::IsGroup.
+  </li>
+
 </ul>
 
 <h2>Changed behavior:</h2>
--- a/RELEASE_NOTES	Wed Apr 29 18:59:48 2009 +0400
+++ b/RELEASE_NOTES	Wed Apr 29 18:26:25 2009 +0400
@@ -8,6 +8,23 @@
 including tutorials:
 http://www.nsnam.org/tutorials.html
 
+Release 3.5
+===========
+
+Availability
+------------
+This release is scheduled for June/July 2009
+
+New user-visible features
+-------------------------
+  a) 802.11e EDCA support: Has been added possibilty to manage QoS traffic on wifi stations.
+
+  b) 802.11n initial support: Has been added support for A-MSDU frame aggregation feature.
+ 
+API changes from ns-3.4
+-----------------------
+API changes for this release are documented in the file CHANGES.html
+
 Release 3.4
 ===========
 
--- a/bindings/python/callbacks_list.py	Wed Apr 29 18:59:48 2009 +0400
+++ b/bindings/python/callbacks_list.py	Wed Apr 29 18:26:25 2009 +0400
@@ -1,10 +1,11 @@
 callback_classes = [
     ['void', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
+    ['void', 'ns3::Ptr<ns3::Packet>', 'ns3::Mac48Address', 'ns3::Mac48Address', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::Socket>', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::Socket>', 'unsigned int', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::Socket>', 'ns3::Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['bool', 'ns3::Ptr<ns3::Socket>', 'ns3::Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
-    ['void', 'ns3::Ptr<ns3::Packet>', 'ns3::Mac48Address', 'ns3::Mac48Address', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
+    ['void', 'ns3::WifiMacHeader const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['bool', 'std::string', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['bool', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet const>', 'unsigned short', 'ns3::Address const&', 'ns3::Address const&', 'ns3::NetDevice::PacketType', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['bool', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet const>', 'unsigned short', 'ns3::Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
--- a/bindings/python/ns3_module_bridge.py	Wed Apr 29 18:59:48 2009 +0400
+++ b/bindings/python/ns3_module_bridge.py	Wed Apr 29 18:26:25 2009 +0400
@@ -223,17 +223,17 @@
                    'void', 
                    [], 
                    visibility='protected', is_virtual=True)
-    ## bridge-net-device.h: void ns3::BridgeNetDevice::ReceiveFromDevice(ns3::Ptr<ns3::NetDevice> device, ns3::Ptr<const ns3::Packet> packet, uint16_t protocol, ns3::Address const & source, ns3::Address const & destination, ns3::NetDevice::PacketType packetType) [member function]
+    ## bridge-net-device.h: void ns3::BridgeNetDevice::ReceiveFromDevice(ns3::Ptr<ns3::NetDevice> device, ns3::Ptr<ns3::Packet const> packet, uint16_t protocol, ns3::Address const & source, ns3::Address const & destination, ns3::NetDevice::PacketType packetType) [member function]
     cls.add_method('ReceiveFromDevice', 
                    'void', 
                    [param('ns3::Ptr< ns3::NetDevice >', 'device'), param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Address const &', 'source'), param('ns3::Address const &', 'destination'), param('ns3::NetDevice::PacketType', 'packetType')], 
                    visibility='protected')
-    ## bridge-net-device.h: void ns3::BridgeNetDevice::ForwardUnicast(ns3::Ptr<ns3::NetDevice> incomingPort, ns3::Ptr<const ns3::Packet> packet, uint16_t protocol, ns3::Mac48Address src, ns3::Mac48Address dst) [member function]
+    ## bridge-net-device.h: void ns3::BridgeNetDevice::ForwardUnicast(ns3::Ptr<ns3::NetDevice> incomingPort, ns3::Ptr<ns3::Packet const> packet, uint16_t protocol, ns3::Mac48Address src, ns3::Mac48Address dst) [member function]
     cls.add_method('ForwardUnicast', 
                    'void', 
                    [param('ns3::Ptr< ns3::NetDevice >', 'incomingPort'), param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'src'), param('ns3::Mac48Address', 'dst')], 
                    visibility='protected')
-    ## bridge-net-device.h: void ns3::BridgeNetDevice::ForwardBroadcast(ns3::Ptr<ns3::NetDevice> incomingPort, ns3::Ptr<const ns3::Packet> packet, uint16_t protocol, ns3::Mac48Address src, ns3::Mac48Address dst) [member function]
+    ## bridge-net-device.h: void ns3::BridgeNetDevice::ForwardBroadcast(ns3::Ptr<ns3::NetDevice> incomingPort, ns3::Ptr<ns3::Packet const> packet, uint16_t protocol, ns3::Mac48Address src, ns3::Mac48Address dst) [member function]
     cls.add_method('ForwardBroadcast', 
                    'void', 
                    [param('ns3::Ptr< ns3::NetDevice >', 'incomingPort'), param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'src'), param('ns3::Mac48Address', 'dst')], 
--- a/bindings/python/ns3_module_common.py	Wed Apr 29 18:59:48 2009 +0400
+++ b/bindings/python/ns3_module_common.py	Wed Apr 29 18:26:25 2009 +0400
@@ -493,7 +493,7 @@
     cls.add_constructor([param('uint32_t', 'size')])
     ## packet.h: ns3::Packet::Packet(uint8_t const * buffer, uint32_t size) [constructor]
     cls.add_constructor([param('uint8_t const *', 'buffer'), param('uint32_t', 'size')])
-    ## packet.h: void ns3::Packet::AddAtEnd(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## packet.h: void ns3::Packet::AddAtEnd(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('AddAtEnd', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')])
@@ -1054,7 +1054,7 @@
     cls.add_method('WritePppHeader', 
                    'void', 
                    [])
-    ## pcap-writer.h: void ns3::PcapWriter::WritePacket(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## pcap-writer.h: void ns3::PcapWriter::WritePacket(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('WritePacket', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')])
--- a/bindings/python/ns3_module_contrib.py	Wed Apr 29 18:59:48 2009 +0400
+++ b/bindings/python/ns3_module_contrib.py	Wed Apr 29 18:26:25 2009 +0400
@@ -102,12 +102,12 @@
     cls.add_constructor([param('ns3::DelayJitterEstimation const &', 'arg0')])
     ## delay-jitter-estimation.h: ns3::DelayJitterEstimation::DelayJitterEstimation() [constructor]
     cls.add_constructor([])
-    ## delay-jitter-estimation.h: static void ns3::DelayJitterEstimation::PrepareTx(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## delay-jitter-estimation.h: static void ns3::DelayJitterEstimation::PrepareTx(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('PrepareTx', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')], 
                    is_static=True)
-    ## delay-jitter-estimation.h: void ns3::DelayJitterEstimation::RecordRx(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## delay-jitter-estimation.h: void ns3::DelayJitterEstimation::RecordRx(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('RecordRx', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')])
--- a/bindings/python/ns3_module_core.py	Wed Apr 29 18:59:48 2009 +0400
+++ b/bindings/python/ns3_module_core.py	Wed Apr 29 18:26:25 2009 +0400
@@ -2028,7 +2028,7 @@
     cls.add_method('ConnectWithoutContext', 
                    'void', 
                    [param('ns3::CallbackBase const &', 'cb')])
-    ## traced-value.h: void ns3::TracedValue<unsigned int>::Connect(ns3::CallbackBase const & cb, std::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
+    ## traced-value.h: void ns3::TracedValue<unsigned int>::Connect(ns3::CallbackBase const & cb, std::string path) [member function]
     cls.add_method('Connect', 
                    'void', 
                    [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
@@ -2036,7 +2036,7 @@
     cls.add_method('DisconnectWithoutContext', 
                    'void', 
                    [param('ns3::CallbackBase const &', 'cb')])
-    ## traced-value.h: void ns3::TracedValue<unsigned int>::Disconnect(ns3::CallbackBase const & cb, std::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
+    ## traced-value.h: void ns3::TracedValue<unsigned int>::Disconnect(ns3::CallbackBase const & cb, std::string path) [member function]
     cls.add_method('Disconnect', 
                    'void', 
                    [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
@@ -2184,7 +2184,7 @@
     module.add_function('TypeNameGet', 
                         'std::string', 
                         [], 
-                        template_parameters=['long'])
+                        template_parameters=['long long'])
     ## type-name.h: extern std::string ns3::TypeNameGet() [free function]
     module.add_function('TypeNameGet', 
                         'std::string', 
@@ -2204,7 +2204,7 @@
     module.add_function('TypeNameGet', 
                         'std::string', 
                         [], 
-                        template_parameters=['unsigned long'])
+                        template_parameters=['unsigned long long'])
     ## type-name.h: extern std::string ns3::TypeNameGet() [free function]
     module.add_function('TypeNameGet', 
                         'std::string', 
--- a/bindings/python/ns3_module_helper.py	Wed Apr 29 18:59:48 2009 +0400
+++ b/bindings/python/ns3_module_helper.py	Wed Apr 29 18:26:25 2009 +0400
@@ -47,12 +47,18 @@
     module.add_class('V4PingHelper', allow_subclassing=False)
     ## wifi-helper.h: ns3::WifiHelper [class]
     module.add_class('WifiHelper', allow_subclassing=False)
+    ## wifi-helper.h: ns3::WifiMacHelper [class]
+    module.add_class('WifiMacHelper', allow_subclassing=False)
     ## wifi-helper.h: ns3::WifiPhyHelper [class]
     module.add_class('WifiPhyHelper', allow_subclassing=False)
     ## yans-wifi-helper.h: ns3::YansWifiChannelHelper [class]
     module.add_class('YansWifiChannelHelper', allow_subclassing=False)
     ## yans-wifi-helper.h: ns3::YansWifiPhyHelper [class]
     module.add_class('YansWifiPhyHelper', allow_subclassing=False, parent=root_module['ns3::WifiPhyHelper'])
+    ## nqos-wifi-mac-helper.h: ns3::NqosWifiMacHelper [class]
+    module.add_class('NqosWifiMacHelper', allow_subclassing=False, parent=root_module['ns3::WifiMacHelper'])
+    ## qos-wifi-mac-helper.h: ns3::QosWifiMacHelper [class]
+    module.add_class('QosWifiMacHelper', allow_subclassing=False, parent=root_module['ns3::WifiMacHelper'])
     
     ## Register a nested module for the namespace Config
     
@@ -117,9 +123,12 @@
     register_Ns3UdpEchoServerHelper_methods(root_module, root_module['ns3::UdpEchoServerHelper'])
     register_Ns3V4PingHelper_methods(root_module, root_module['ns3::V4PingHelper'])
     register_Ns3WifiHelper_methods(root_module, root_module['ns3::WifiHelper'])
+    register_Ns3WifiMacHelper_methods(root_module, root_module['ns3::WifiMacHelper'])
     register_Ns3WifiPhyHelper_methods(root_module, root_module['ns3::WifiPhyHelper'])
     register_Ns3YansWifiChannelHelper_methods(root_module, root_module['ns3::YansWifiChannelHelper'])
     register_Ns3YansWifiPhyHelper_methods(root_module, root_module['ns3::YansWifiPhyHelper'])
+    register_Ns3NqosWifiMacHelper_methods(root_module, root_module['ns3::NqosWifiMacHelper'])
+    register_Ns3QosWifiMacHelper_methods(root_module, root_module['ns3::QosWifiMacHelper'])
     return
 
 def register_Ns3ApplicationContainer_methods(root_module, cls):
@@ -1068,25 +1077,33 @@
     cls.add_method('SetRemoteStationManager', 
                    'void', 
                    [param('std::string', 'type'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')])
-    ## wifi-helper.h: void ns3::WifiHelper::SetMac(std::string type, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function]
-    cls.add_method('SetMac', 
-                   'void', 
-                   [param('std::string', 'type'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')])
-    ## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::WifiPhyHelper const & phy, ns3::NodeContainer c) const [member function]
+    ## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::WifiPhyHelper const & phy, ns3::WifiMacHelper const & mac, ns3::NodeContainer c) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::WifiPhyHelper const &', 'phy'), param('ns3::WifiMacHelper const &', 'mac'), param('ns3::NodeContainer', 'c')], 
+                   is_const=True)
+    ## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::WifiPhyHelper const & phy, ns3::WifiMacHelper const & mac, ns3::Ptr<ns3::Node> node) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::WifiPhyHelper const &', 'phy'), param('ns3::WifiMacHelper const &', 'mac'), param('ns3::Ptr< ns3::Node >', 'node')], 
+                   is_const=True)
+    ## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::WifiPhyHelper const & phy, ns3::WifiMacHelper const & mac, std::string nodeName) const [member function]
     cls.add_method('Install', 
                    'ns3::NetDeviceContainer', 
-                   [param('ns3::WifiPhyHelper const &', 'phy'), param('ns3::NodeContainer', 'c')], 
+                   [param('ns3::WifiPhyHelper const &', 'phy'), param('ns3::WifiMacHelper const &', 'mac'), param('std::string', 'nodeName')], 
                    is_const=True)
-    ## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::WifiPhyHelper const & phy, ns3::Ptr<ns3::Node> node) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::WifiPhyHelper const &', 'phy'), param('ns3::Ptr< ns3::Node >', 'node')], 
-                   is_const=True)
-    ## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::WifiPhyHelper const & phy, std::string nodeName) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::WifiPhyHelper const &', 'phy'), param('std::string', 'nodeName')], 
-                   is_const=True)
+    return
+
+def register_Ns3WifiMacHelper_methods(root_module, cls):
+    ## wifi-helper.h: ns3::WifiMacHelper::WifiMacHelper(ns3::WifiMacHelper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::WifiMacHelper const &', 'arg0')])
+    ## wifi-helper.h: ns3::WifiMacHelper::WifiMacHelper() [constructor]
+    cls.add_constructor([])
+    ## wifi-helper.h: ns3::Ptr<ns3::WifiMac> ns3::WifiMacHelper::Create() const [member function]
+    cls.add_method('Create', 
+                   'ns3::Ptr< ns3::WifiMac >', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
     return
 
 def register_Ns3WifiPhyHelper_methods(root_module, cls):
@@ -1209,6 +1226,60 @@
                    is_const=True, visibility='private', is_virtual=True)
     return
 
+def register_Ns3NqosWifiMacHelper_methods(root_module, cls):
+    ## nqos-wifi-mac-helper.h: ns3::NqosWifiMacHelper::NqosWifiMacHelper(ns3::NqosWifiMacHelper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::NqosWifiMacHelper const &', 'arg0')])
+    ## nqos-wifi-mac-helper.h: ns3::NqosWifiMacHelper::NqosWifiMacHelper() [constructor]
+    cls.add_constructor([])
+    ## nqos-wifi-mac-helper.h: static ns3::NqosWifiMacHelper ns3::NqosWifiMacHelper::Default() [member function]
+    cls.add_method('Default', 
+                   'ns3::NqosWifiMacHelper', 
+                   [], 
+                   is_static=True)
+    ## nqos-wifi-mac-helper.h: void ns3::NqosWifiMacHelper::SetType(std::string type, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function]
+    cls.add_method('SetType', 
+                   'void', 
+                   [param('std::string', 'type'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')])
+    ## nqos-wifi-mac-helper.h: void ns3::NqosWifiMacHelper::SetDcaParameters(std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue()) [member function]
+    cls.add_method('SetDcaParameters', 
+                   'void', 
+                   [param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()')])
+    ## nqos-wifi-mac-helper.h: ns3::Ptr<ns3::WifiMac> ns3::NqosWifiMacHelper::Create() const [member function]
+    cls.add_method('Create', 
+                   'ns3::Ptr< ns3::WifiMac >', 
+                   [], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3QosWifiMacHelper_methods(root_module, cls):
+    ## qos-wifi-mac-helper.h: ns3::QosWifiMacHelper::QosWifiMacHelper(ns3::QosWifiMacHelper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::QosWifiMacHelper const &', 'arg0')])
+    ## qos-wifi-mac-helper.h: ns3::QosWifiMacHelper::QosWifiMacHelper() [constructor]
+    cls.add_constructor([])
+    ## qos-wifi-mac-helper.h: static ns3::QosWifiMacHelper ns3::QosWifiMacHelper::Default() [member function]
+    cls.add_method('Default', 
+                   'ns3::QosWifiMacHelper', 
+                   [], 
+                   is_static=True)
+    ## qos-wifi-mac-helper.h: void ns3::QosWifiMacHelper::SetType(std::string type, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function]
+    cls.add_method('SetType', 
+                   'void', 
+                   [param('std::string', 'type'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')])
+    ## qos-wifi-mac-helper.h: void ns3::QosWifiMacHelper::SetMsduAggregatorForAc(ns3::AccessClass accessClass, std::string type, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue()) [member function]
+    cls.add_method('SetMsduAggregatorForAc', 
+                   'void', 
+                   [param('ns3::AccessClass', 'accessClass'), param('std::string', 'type'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()')])
+    ## qos-wifi-mac-helper.h: void ns3::QosWifiMacHelper::SetEdcaParametersForAc(ns3::AccessClass accessClass, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue()) [member function]
+    cls.add_method('SetEdcaParametersForAc', 
+                   'void', 
+                   [param('ns3::AccessClass', 'accessClass'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()')])
+    ## qos-wifi-mac-helper.h: ns3::Ptr<ns3::WifiMac> ns3::QosWifiMacHelper::Create() const [member function]
+    cls.add_method('Create', 
+                   'ns3::Ptr< ns3::WifiMac >', 
+                   [], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
 def register_functions(root_module):
     module = root_module
     register_functions_ns3_Config(module.get_submodule('Config'), root_module)
--- a/bindings/python/ns3_module_internet_stack.py	Wed Apr 29 18:59:48 2009 +0400
+++ b/bindings/python/ns3_module_internet_stack.py	Wed Apr 29 18:26:25 2009 +0400
@@ -95,7 +95,7 @@
                    'uint16_t', 
                    [], 
                    is_const=True)
-    ## icmpv4.h: void ns3::Icmpv4DestinationUnreachable::SetData(ns3::Ptr<const ns3::Packet> data) [member function]
+    ## icmpv4.h: void ns3::Icmpv4DestinationUnreachable::SetData(ns3::Ptr<ns3::Packet const> data) [member function]
     cls.add_method('SetData', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'data')])
@@ -151,7 +151,7 @@
     cls.add_method('SetSequenceNumber', 
                    'void', 
                    [param('uint16_t', 'seq')])
-    ## icmpv4.h: void ns3::Icmpv4Echo::SetData(ns3::Ptr<const ns3::Packet> data) [member function]
+    ## icmpv4.h: void ns3::Icmpv4Echo::SetData(ns3::Ptr<ns3::Packet const> data) [member function]
     cls.add_method('SetData', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'data')])
@@ -165,7 +165,7 @@
                    'uint16_t', 
                    [], 
                    is_const=True)
-    ## icmpv4.h: ns3::Ptr<const ns3::Packet> ns3::Icmpv4Echo::GetData() const [member function]
+    ## icmpv4.h: ns3::Ptr<ns3::Packet const> ns3::Icmpv4Echo::GetData() const [member function]
     cls.add_method('GetData', 
                    'ns3::Ptr< ns3::Packet const >', 
                    [], 
@@ -266,7 +266,7 @@
 def register_Ns3Icmpv4TimeExceeded_methods(root_module, cls):
     ## icmpv4.h: ns3::Icmpv4TimeExceeded::Icmpv4TimeExceeded(ns3::Icmpv4TimeExceeded const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Icmpv4TimeExceeded const &', 'arg0')])
-    ## icmpv4.h: void ns3::Icmpv4TimeExceeded::SetData(ns3::Ptr<const ns3::Packet> data) [member function]
+    ## icmpv4.h: void ns3::Icmpv4TimeExceeded::SetData(ns3::Ptr<ns3::Packet const> data) [member function]
     cls.add_method('SetData', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'data')])
--- a/bindings/python/ns3_module_node.py	Wed Apr 29 18:59:48 2009 +0400
+++ b/bindings/python/ns3_module_node.py	Wed Apr 29 18:26:25 2009 +0400
@@ -1056,11 +1056,6 @@
                    'bool', 
                    [param('ns3::Address const &', 'address')], 
                    is_static=True)
-    ## mac48-address.h: bool ns3::Mac48Address::IsMulticast() const [member function]
-    cls.add_method('IsMulticast', 
-                   'bool', 
-                   [], 
-                   is_const=True)
     return
 
 def register_Ns3Mac64Address_methods(root_module, cls):
@@ -1696,7 +1691,7 @@
     cls.add_method('Dequeue', 
                    'ns3::Ptr< ns3::Packet >', 
                    [])
-    ## queue.h: ns3::Ptr<const ns3::Packet> ns3::Queue::Peek() const [member function]
+    ## queue.h: ns3::Ptr<ns3::Packet const> ns3::Queue::Peek() const [member function]
     cls.add_method('Peek', 
                    'ns3::Ptr< ns3::Packet const >', 
                    [], 
@@ -1754,7 +1749,7 @@
                    'ns3::Ptr< ns3::Packet >', 
                    [], 
                    is_pure_virtual=True, visibility='private', is_virtual=True)
-    ## queue.h: ns3::Ptr<const ns3::Packet> ns3::Queue::DoPeek() const [member function]
+    ## queue.h: ns3::Ptr<ns3::Packet const> ns3::Queue::DoPeek() const [member function]
     cls.add_method('DoPeek', 
                    'ns3::Ptr< ns3::Packet const >', 
                    [], 
@@ -2420,7 +2415,7 @@
                    'ns3::Ptr< ns3::Packet >', 
                    [], 
                    visibility='private', is_virtual=True)
-    ## drop-tail-queue.h: ns3::Ptr<const ns3::Packet> ns3::DropTailQueue::DoPeek() const [member function]
+    ## drop-tail-queue.h: ns3::Ptr<ns3::Packet const> ns3::DropTailQueue::DoPeek() const [member function]
     cls.add_method('DoPeek', 
                    'ns3::Ptr< ns3::Packet const >', 
                    [], 
--- a/bindings/python/ns3_module_stats.py	Wed Apr 29 18:59:48 2009 +0400
+++ b/bindings/python/ns3_module_stats.py	Wed Apr 29 18:26:25 2009 +0400
@@ -303,11 +303,11 @@
     cls.add_constructor([param('ns3::PacketSizeMinMaxAvgTotalCalculator const &', 'arg0')])
     ## packet-data-calculators.h: ns3::PacketSizeMinMaxAvgTotalCalculator::PacketSizeMinMaxAvgTotalCalculator() [constructor]
     cls.add_constructor([])
-    ## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::PacketUpdate(std::string path, ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::PacketUpdate(std::string path, ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('PacketUpdate', 
                    'void', 
                    [param('std::string', 'path'), param('ns3::Ptr< ns3::Packet const >', 'packet')])
-    ## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::FrameUpdate(std::string path, ns3::Ptr<const ns3::Packet> packet, ns3::Mac48Address realto) [member function]
+    ## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::FrameUpdate(std::string path, ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address realto) [member function]
     cls.add_method('FrameUpdate', 
                    'void', 
                    [param('std::string', 'path'), param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'realto')])
@@ -400,11 +400,11 @@
     cls.add_constructor([param('ns3::PacketCounterCalculator const &', 'arg0')])
     ## packet-data-calculators.h: ns3::PacketCounterCalculator::PacketCounterCalculator() [constructor]
     cls.add_constructor([])
-    ## packet-data-calculators.h: void ns3::PacketCounterCalculator::PacketUpdate(std::string path, ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## packet-data-calculators.h: void ns3::PacketCounterCalculator::PacketUpdate(std::string path, ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('PacketUpdate', 
                    'void', 
                    [param('std::string', 'path'), param('ns3::Ptr< ns3::Packet const >', 'packet')])
-    ## packet-data-calculators.h: void ns3::PacketCounterCalculator::FrameUpdate(std::string path, ns3::Ptr<const ns3::Packet> packet, ns3::Mac48Address realto) [member function]
+    ## packet-data-calculators.h: void ns3::PacketCounterCalculator::FrameUpdate(std::string path, ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address realto) [member function]
     cls.add_method('FrameUpdate', 
                    'void', 
                    [param('std::string', 'path'), param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'realto')])
--- a/bindings/python/ns3_module_tap_bridge.py	Wed Apr 29 18:59:48 2009 +0400
+++ b/bindings/python/ns3_module_tap_bridge.py	Wed Apr 29 18:26:25 2009 +0400
@@ -206,7 +206,7 @@
                    'void', 
                    [], 
                    visibility='protected', is_virtual=True)
-    ## tap-bridge.h: void ns3::TapBridge::ReceiveFromBridgedDevice(ns3::Ptr<ns3::NetDevice> device, ns3::Ptr<const ns3::Packet> packet, uint16_t protocol, ns3::Address const & src, ns3::Address const & dst, ns3::NetDevice::PacketType packetType) [member function]
+    ## tap-bridge.h: void ns3::TapBridge::ReceiveFromBridgedDevice(ns3::Ptr<ns3::NetDevice> device, ns3::Ptr<ns3::Packet const> packet, uint16_t protocol, ns3::Address const & src, ns3::Address const & dst, ns3::NetDevice::PacketType packetType) [member function]
     cls.add_method('ReceiveFromBridgedDevice', 
                    'void', 
                    [param('ns3::Ptr< ns3::NetDevice >', 'device'), param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Address const &', 'src'), param('ns3::Address const &', 'dst'), param('ns3::NetDevice::PacketType', 'packetType')], 
--- a/bindings/python/ns3_module_wifi.py	Wed Apr 29 18:59:48 2009 +0400
+++ b/bindings/python/ns3_module_wifi.py	Wed Apr 29 18:26:25 2009 +0400
@@ -3,10 +3,16 @@
 def register_types(module):
     root_module = module.get_root()
     
+    ## wifi-mac-header.h: ns3::WifiMacType [enumeration]
+    module.add_enum('WifiMacType', ['WIFI_MAC_CTL_RTS', 'WIFI_MAC_CTL_CTS', 'WIFI_MAC_CTL_ACK', 'WIFI_MAC_CTL_BACKREQ', 'WIFI_MAC_CTL_BACKRESP', 'WIFI_MAC_MGT_BEACON', 'WIFI_MAC_MGT_ASSOCIATION_REQUEST', 'WIFI_MAC_MGT_ASSOCIATION_RESPONSE', 'WIFI_MAC_MGT_DISASSOCIATION', 'WIFI_MAC_MGT_REASSOCIATION_REQUEST', 'WIFI_MAC_MGT_REASSOCIATION_RESPONSE', 'WIFI_MAC_MGT_PROBE_REQUEST', 'WIFI_MAC_MGT_PROBE_RESPONSE', 'WIFI_MAC_MGT_AUTHENTICATION', 'WIFI_MAC_MGT_DEAUTHENTICATION', 'WIFI_MAC_DATA', 'WIFI_MAC_DATA_CFACK', 'WIFI_MAC_DATA_CFPOLL', 'WIFI_MAC_DATA_CFACK_CFPOLL', 'WIFI_MAC_DATA_NULL', 'WIFI_MAC_DATA_NULL_CFACK', 'WIFI_MAC_DATA_NULL_CFPOLL', 'WIFI_MAC_DATA_NULL_CFACK_CFPOLL', 'WIFI_MAC_QOSDATA', 'WIFI_MAC_QOSDATA_CFACK', 'WIFI_MAC_QOSDATA_CFPOLL', 'WIFI_MAC_QOSDATA_CFACK_CFPOLL', 'WIFI_MAC_QOSDATA_NULL', 'WIFI_MAC_QOSDATA_NULL_CFPOLL', 'WIFI_MAC_QOSDATA_NULL_CFACK_CFPOLL'])
     ## wifi-preamble.h: ns3::WifiPreamble [enumeration]
     module.add_enum('WifiPreamble', ['WIFI_PREAMBLE_LONG', 'WIFI_PREAMBLE_SHORT'])
     ## wifi-phy-standard.h: ns3::WifiPhyStandard [enumeration]
     module.add_enum('WifiPhyStandard', ['WIFI_PHY_STANDARD_80211a', 'WIFI_PHY_STANDARD_holland'])
+    ## qos-utils.h: ns3::AccessClass [enumeration]
+    module.add_enum('AccessClass', ['AC_VO', 'AC_VI', 'AC_BE', 'AC_BK', 'AC_UNDEF'])
+    ## edca-txop-n.h: ns3::TypeOfStation [enumeration]
+    module.add_enum('TypeOfStation', ['STA', 'AP', 'ADHOC_STA'])
     ## interference-helper.h: ns3::InterferenceHelper [class]
     module.add_class('InterferenceHelper', allow_subclassing=False)
     ## interference-helper.h: ns3::InterferenceHelper::SnrPer [struct]
@@ -41,6 +47,8 @@
     module.add_class('PropagationDelayModel', parent=root_module['ns3::Object'])
     ## propagation-loss-model.h: ns3::PropagationLossModel [class]
     module.add_class('PropagationLossModel', parent=root_module['ns3::Object'])
+    ## qos-tag.h: ns3::QosTag [class]
+    module.add_class('QosTag', parent=root_module['ns3::Tag'])
     ## propagation-delay-model.h: ns3::RandomPropagationDelayModel [class]
     module.add_class('RandomPropagationDelayModel', parent=root_module['ns3::PropagationDelayModel'])
     ## propagation-loss-model.h: ns3::RandomPropagationLossModel [class]
@@ -55,6 +63,12 @@
     module.add_class('ThreeLogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## wifi-mac.h: ns3::WifiMac [class]
     module.add_class('WifiMac', parent=root_module['ns3::Object'])
+    ## wifi-mac-header.h: ns3::WifiMacHeader [class]
+    module.add_class('WifiMacHeader', parent=root_module['ns3::Header'])
+    ## wifi-mac-header.h: ns3::WifiMacHeader::QosAckPolicy [enumeration]
+    module.add_enum('QosAckPolicy', ['NORMAL_ACK', 'NO_ACK', 'NO_EXPLICIT_ACK', 'BLOCK_ACK'], outer_class=root_module['ns3::WifiMacHeader'])
+    ## wifi-mac-header.h: ns3::WifiMacHeader::AddressType [enumeration]
+    module.add_enum('AddressType', ['ADDR1', 'ADDR2', 'ADDR3', 'ADDR4'], outer_class=root_module['ns3::WifiMacHeader'])
     ## wifi-mode.h: ns3::WifiModeChecker [class]
     module.add_class('WifiModeChecker', parent=root_module['ns3::AttributeChecker'])
     ## wifi-mode.h: ns3::WifiModeValue [class]
@@ -73,12 +87,18 @@
     module.add_class('AdhocWifiMac', parent=root_module['ns3::WifiMac'])
     ## amrr-wifi-manager.h: ns3::AmrrWifiManager [class]
     module.add_class('AmrrWifiManager', parent=root_module['ns3::WifiRemoteStationManager'])
+    ## amsdu-subframe-header.h: ns3::AmsduSubframeHeader [class]
+    module.add_class('AmsduSubframeHeader', parent=root_module['ns3::Header'])
     ## arf-wifi-manager.h: ns3::ArfWifiManager [class]
     module.add_class('ArfWifiManager', parent=root_module['ns3::WifiRemoteStationManager'])
     ## constant-rate-wifi-manager.h: ns3::ConstantRateWifiManager [class]
     module.add_class('ConstantRateWifiManager', parent=root_module['ns3::WifiRemoteStationManager'])
     ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel [class]
     module.add_class('ConstantSpeedPropagationDelayModel', parent=root_module['ns3::PropagationDelayModel'])
+    ## dca-txop.h: ns3::DcaTxop [class]
+    module.add_class('DcaTxop', parent=root_module['ns3::Object'])
+    ## edca-txop-n.h: ns3::EdcaTxopN [class]
+    module.add_class('EdcaTxopN', parent=root_module['ns3::Object'])
     ## error-rate-model.h: ns3::ErrorRateModel [class]
     module.add_class('ErrorRateModel', parent=root_module['ns3::Object'])
     ## propagation-loss-model.h: ns3::FriisPropagationLossModel [class]
@@ -89,12 +109,20 @@
     module.add_class('JakesPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## propagation-loss-model.h: ns3::LogDistancePropagationLossModel [class]
     module.add_class('LogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
+    ## msdu-aggregator.h: ns3::MsduAggregator [class]
+    module.add_class('MsduAggregator', parent=root_module['ns3::Object'])
     ## nqap-wifi-mac.h: ns3::NqapWifiMac [class]
     module.add_class('NqapWifiMac', parent=root_module['ns3::WifiMac'])
     ## nqsta-wifi-mac.h: ns3::NqstaWifiMac [class]
     module.add_class('NqstaWifiMac', parent=root_module['ns3::WifiMac'])
     ## onoe-wifi-manager.h: ns3::OnoeWifiManager [class]
     module.add_class('OnoeWifiManager', parent=root_module['ns3::WifiRemoteStationManager'])
+    ## qadhoc-wifi-mac.h: ns3::QadhocWifiMac [class]
+    module.add_class('QadhocWifiMac', parent=root_module['ns3::WifiMac'])
+    ## qap-wifi-mac.h: ns3::QapWifiMac [class]
+    module.add_class('QapWifiMac', parent=root_module['ns3::WifiMac'])
+    ## qsta-wifi-mac.h: ns3::QstaWifiMac [class]
+    module.add_class('QstaWifiMac', parent=root_module['ns3::WifiMac'])
     ## rraa-wifi-manager.h: ns3::RraaWifiManager [class]
     module.add_class('RraaWifiManager', parent=root_module['ns3::WifiRemoteStationManager'])
     ## wifi-channel.h: ns3::WifiChannel [class]
@@ -165,6 +193,7 @@
     register_Ns3OnoeWifiRemoteStation_methods(root_module, root_module['ns3::OnoeWifiRemoteStation'])
     register_Ns3PropagationDelayModel_methods(root_module, root_module['ns3::PropagationDelayModel'])
     register_Ns3PropagationLossModel_methods(root_module, root_module['ns3::PropagationLossModel'])
+    register_Ns3QosTag_methods(root_module, root_module['ns3::QosTag'])
     register_Ns3RandomPropagationDelayModel_methods(root_module, root_module['ns3::RandomPropagationDelayModel'])
     register_Ns3RandomPropagationLossModel_methods(root_module, root_module['ns3::RandomPropagationLossModel'])
     register_Ns3RraaWifiRemoteStation_methods(root_module, root_module['ns3::RraaWifiRemoteStation'])
@@ -172,6 +201,7 @@
     register_Ns3SsidValue_methods(root_module, root_module['ns3::SsidValue'])
     register_Ns3ThreeLogDistancePropagationLossModel_methods(root_module, root_module['ns3::ThreeLogDistancePropagationLossModel'])
     register_Ns3WifiMac_methods(root_module, root_module['ns3::WifiMac'])
+    register_Ns3WifiMacHeader_methods(root_module, root_module['ns3::WifiMacHeader'])
     register_Ns3WifiModeChecker_methods(root_module, root_module['ns3::WifiModeChecker'])
     register_Ns3WifiModeValue_methods(root_module, root_module['ns3::WifiModeValue'])
     register_Ns3WifiPhy_methods(root_module, root_module['ns3::WifiPhy'])
@@ -180,17 +210,24 @@
     register_Ns3AarfWifiRemoteStation_methods(root_module, root_module['ns3::AarfWifiRemoteStation'])
     register_Ns3AdhocWifiMac_methods(root_module, root_module['ns3::AdhocWifiMac'])
     register_Ns3AmrrWifiManager_methods(root_module, root_module['ns3::AmrrWifiManager'])
+    register_Ns3AmsduSubframeHeader_methods(root_module, root_module['ns3::AmsduSubframeHeader'])
     register_Ns3ArfWifiManager_methods(root_module, root_module['ns3::ArfWifiManager'])
     register_Ns3ConstantRateWifiManager_methods(root_module, root_module['ns3::ConstantRateWifiManager'])
     register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, root_module['ns3::ConstantSpeedPropagationDelayModel'])
+    register_Ns3DcaTxop_methods(root_module, root_module['ns3::DcaTxop'])
+    register_Ns3EdcaTxopN_methods(root_module, root_module['ns3::EdcaTxopN'])
     register_Ns3ErrorRateModel_methods(root_module, root_module['ns3::ErrorRateModel'])
     register_Ns3FriisPropagationLossModel_methods(root_module, root_module['ns3::FriisPropagationLossModel'])
     register_Ns3IdealWifiManager_methods(root_module, root_module['ns3::IdealWifiManager'])
     register_Ns3JakesPropagationLossModel_methods(root_module, root_module['ns3::JakesPropagationLossModel'])
     register_Ns3LogDistancePropagationLossModel_methods(root_module, root_module['ns3::LogDistancePropagationLossModel'])
+    register_Ns3MsduAggregator_methods(root_module, root_module['ns3::MsduAggregator'])
     register_Ns3NqapWifiMac_methods(root_module, root_module['ns3::NqapWifiMac'])
     register_Ns3NqstaWifiMac_methods(root_module, root_module['ns3::NqstaWifiMac'])
     register_Ns3OnoeWifiManager_methods(root_module, root_module['ns3::OnoeWifiManager'])
+    register_Ns3QadhocWifiMac_methods(root_module, root_module['ns3::QadhocWifiMac'])
+    register_Ns3QapWifiMac_methods(root_module, root_module['ns3::QapWifiMac'])
+    register_Ns3QstaWifiMac_methods(root_module, root_module['ns3::QstaWifiMac'])
     register_Ns3RraaWifiManager_methods(root_module, root_module['ns3::RraaWifiManager'])
     register_Ns3WifiChannel_methods(root_module, root_module['ns3::WifiChannel'])
     register_Ns3WifiNetDevice_methods(root_module, root_module['ns3::WifiNetDevice'])
@@ -522,15 +559,15 @@
     cls.add_method('RecordDisassociated', 
                    'void', 
                    [])
-    ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::PrepareForQueue(ns3::Ptr<const ns3::Packet> packet, uint32_t fullPacketSize) [member function]
+    ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::PrepareForQueue(ns3::Ptr<ns3::Packet const> packet, uint32_t fullPacketSize) [member function]
     cls.add_method('PrepareForQueue', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint32_t', 'fullPacketSize')])
-    ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::GetDataMode(ns3::Ptr<const ns3::Packet> packet, uint32_t fullPacketSize) [member function]
+    ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::GetDataMode(ns3::Ptr<ns3::Packet const> packet, uint32_t fullPacketSize) [member function]
     cls.add_method('GetDataMode', 
                    'ns3::WifiMode', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint32_t', 'fullPacketSize')])
-    ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::GetRtsMode(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStation::GetRtsMode(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('GetRtsMode', 
                    'ns3::WifiMode', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')])
@@ -562,37 +599,37 @@
     cls.add_method('ReportRxOk', 
                    'void', 
                    [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')])
-    ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::NeedRts(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::NeedRts(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NeedRts', 
                    'bool', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')], 
                    is_virtual=True)
-    ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::NeedRtsRetransmission(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::NeedRtsRetransmission(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NeedRtsRetransmission', 
                    'bool', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')], 
                    is_virtual=True)
-    ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::NeedDataRetransmission(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::NeedDataRetransmission(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NeedDataRetransmission', 
                    'bool', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')], 
                    is_virtual=True)
-    ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::NeedFragmentation(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::NeedFragmentation(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NeedFragmentation', 
                    'bool', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')], 
                    is_virtual=True)
-    ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetFragmentSize(ns3::Ptr<const ns3::Packet> packet, uint32_t fragmentNumber) [member function]
+    ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetFragmentSize(ns3::Ptr<ns3::Packet const> packet, uint32_t fragmentNumber) [member function]
     cls.add_method('GetFragmentSize', 
                    'uint32_t', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint32_t', 'fragmentNumber')], 
                    is_virtual=True)
-    ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetFragmentOffset(ns3::Ptr<const ns3::Packet> packet, uint32_t fragmentNumber) [member function]
+    ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetFragmentOffset(ns3::Ptr<ns3::Packet const> packet, uint32_t fragmentNumber) [member function]
     cls.add_method('GetFragmentOffset', 
                    'uint32_t', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint32_t', 'fragmentNumber')], 
                    is_virtual=True)
-    ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::IsLastFragment(ns3::Ptr<const ns3::Packet> packet, uint32_t fragmentNumber) [member function]
+    ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::IsLastFragment(ns3::Ptr<ns3::Packet const> packet, uint32_t fragmentNumber) [member function]
     cls.add_method('IsLastFragment', 
                    'bool', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint32_t', 'fragmentNumber')], 
@@ -1033,6 +1070,52 @@
                    is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
     return
 
+def register_Ns3QosTag_methods(root_module, cls):
+    ## qos-tag.h: ns3::QosTag::QosTag(ns3::QosTag const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::QosTag const &', 'arg0')])
+    ## qos-tag.h: static ns3::TypeId ns3::QosTag::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## qos-tag.h: ns3::TypeId ns3::QosTag::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qos-tag.h: ns3::QosTag::QosTag() [constructor]
+    cls.add_constructor([])
+    ## qos-tag.h: void ns3::QosTag::Serialize(ns3::TagBuffer i) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::TagBuffer', 'i')], 
+                   is_const=True, is_virtual=True)
+    ## qos-tag.h: void ns3::QosTag::Deserialize(ns3::TagBuffer i) [member function]
+    cls.add_method('Deserialize', 
+                   'void', 
+                   [param('ns3::TagBuffer', 'i')], 
+                   is_virtual=True)
+    ## qos-tag.h: uint32_t ns3::QosTag::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qos-tag.h: void ns3::QosTag::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## qos-tag.h: uint8_t ns3::QosTag::Get() const [member function]
+    cls.add_method('Get', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## qos-tag.h: void ns3::QosTag::Set(uint8_t tid) [member function]
+    cls.add_method('Set', 
+                   'void', 
+                   [param('uint8_t', 'tid')])
+    return
+
 def register_Ns3RandomPropagationDelayModel_methods(root_module, cls):
     ## propagation-delay-model.h: ns3::RandomPropagationDelayModel::RandomPropagationDelayModel(ns3::RandomPropagationDelayModel const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::RandomPropagationDelayModel const &', 'arg0')])
@@ -1070,7 +1153,7 @@
     cls.add_constructor([param('ns3::RraaWifiRemoteStation const &', 'arg0')])
     ## rraa-wifi-manager.h: ns3::RraaWifiRemoteStation::RraaWifiRemoteStation(ns3::Ptr<ns3::RraaWifiManager> stations) [constructor]
     cls.add_constructor([param('ns3::Ptr< ns3::RraaWifiManager >', 'stations')])
-    ## rraa-wifi-manager.h: bool ns3::RraaWifiRemoteStation::NeedRts(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## rraa-wifi-manager.h: bool ns3::RraaWifiRemoteStation::NeedRts(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NeedRts', 
                    'bool', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')], 
@@ -1296,12 +1379,12 @@
                    'ns3::Mac48Address', 
                    [], 
                    is_pure_virtual=True, is_const=True, is_virtual=True)
-    ## wifi-mac.h: void ns3::WifiMac::Enqueue(ns3::Ptr<const ns3::Packet> packet, ns3::Mac48Address to, ns3::Mac48Address from) [member function]
+    ## wifi-mac.h: void ns3::WifiMac::Enqueue(ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address to, ns3::Mac48Address from) [member function]
     cls.add_method('Enqueue', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from')], 
                    is_pure_virtual=True, is_virtual=True)
-    ## wifi-mac.h: void ns3::WifiMac::Enqueue(ns3::Ptr<const ns3::Packet> packet, ns3::Mac48Address to) [member function]
+    ## wifi-mac.h: void ns3::WifiMac::Enqueue(ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address to) [member function]
     cls.add_method('Enqueue', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'to')], 
@@ -1336,28 +1419,399 @@
                    'void', 
                    [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], 
                    is_pure_virtual=True, is_virtual=True)
-    ## wifi-mac.h: void ns3::WifiMac::NotifyTx(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-mac.h: void ns3::WifiMac::NotifyTx(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NotifyTx', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')])
-    ## wifi-mac.h: void ns3::WifiMac::NotifyTxDrop(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-mac.h: void ns3::WifiMac::NotifyTxDrop(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NotifyTxDrop', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')])
-    ## wifi-mac.h: void ns3::WifiMac::NotifyRx(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-mac.h: void ns3::WifiMac::NotifyRx(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NotifyRx', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')])
-    ## wifi-mac.h: void ns3::WifiMac::NotifyPromiscRx(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-mac.h: void ns3::WifiMac::NotifyPromiscRx(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NotifyPromiscRx', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')])
-    ## wifi-mac.h: void ns3::WifiMac::NotifyRxDrop(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-mac.h: void ns3::WifiMac::NotifyRxDrop(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NotifyRxDrop', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')])
     return
 
+def register_Ns3WifiMacHeader_methods(root_module, cls):
+    ## wifi-mac-header.h: ns3::WifiMacHeader::WifiMacHeader(ns3::WifiMacHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::WifiMacHeader const &', 'arg0')])
+    ## wifi-mac-header.h: ns3::WifiMacHeader::WifiMacHeader() [constructor]
+    cls.add_constructor([])
+    ## wifi-mac-header.h: static ns3::TypeId ns3::WifiMacHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## wifi-mac-header.h: ns3::TypeId ns3::WifiMacHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## wifi-mac-header.h: uint32_t ns3::WifiMacHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    ## wifi-mac-header.h: uint32_t ns3::WifiMacHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetAssocReq() [member function]
+    cls.add_method('SetAssocReq', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetAssocResp() [member function]
+    cls.add_method('SetAssocResp', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetProbeReq() [member function]
+    cls.add_method('SetProbeReq', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetProbeResp() [member function]
+    cls.add_method('SetProbeResp', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetBeacon() [member function]
+    cls.add_method('SetBeacon', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetTypeData() [member function]
+    cls.add_method('SetTypeData', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetDsFrom() [member function]
+    cls.add_method('SetDsFrom', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetDsNotFrom() [member function]
+    cls.add_method('SetDsNotFrom', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetDsTo() [member function]
+    cls.add_method('SetDsTo', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetDsNotTo() [member function]
+    cls.add_method('SetDsNotTo', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetAddr1(ns3::Mac48Address address) [member function]
+    cls.add_method('SetAddr1', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'address')])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetAddr2(ns3::Mac48Address address) [member function]
+    cls.add_method('SetAddr2', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'address')])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetAddr3(ns3::Mac48Address address) [member function]
+    cls.add_method('SetAddr3', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'address')])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetAddr4(ns3::Mac48Address address) [member function]
+    cls.add_method('SetAddr4', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'address')])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetType(ns3::WifiMacType type) [member function]
+    cls.add_method('SetType', 
+                   'void', 
+                   [param('ns3::WifiMacType', 'type')])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetRawDuration(uint16_t duration) [member function]
+    cls.add_method('SetRawDuration', 
+                   'void', 
+                   [param('uint16_t', 'duration')])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetDuration(ns3::Time duration) [member function]
+    cls.add_method('SetDuration', 
+                   'void', 
+                   [param('ns3::Time', 'duration')])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetId(uint16_t id) [member function]
+    cls.add_method('SetId', 
+                   'void', 
+                   [param('uint16_t', 'id')])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetSequenceNumber(uint16_t seq) [member function]
+    cls.add_method('SetSequenceNumber', 
+                   'void', 
+                   [param('uint16_t', 'seq')])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetFragmentNumber(uint8_t frag) [member function]
+    cls.add_method('SetFragmentNumber', 
+                   'void', 
+                   [param('uint8_t', 'frag')])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetNoMoreFragments() [member function]
+    cls.add_method('SetNoMoreFragments', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetMoreFragments() [member function]
+    cls.add_method('SetMoreFragments', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetRetry() [member function]
+    cls.add_method('SetRetry', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetNoRetry() [member function]
+    cls.add_method('SetNoRetry', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosTid(uint8_t tid) [member function]
+    cls.add_method('SetQosTid', 
+                   'void', 
+                   [param('uint8_t', 'tid')])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosEosp() [member function]
+    cls.add_method('SetQosEosp', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosNoEosp() [member function]
+    cls.add_method('SetQosNoEosp', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosAckPolicy(ns3::WifiMacHeader::QosAckPolicy arg0) [member function]
+    cls.add_method('SetQosAckPolicy', 
+                   'void', 
+                   [param('ns3::WifiMacHeader::QosAckPolicy', 'arg0')])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosAmsdu() [member function]
+    cls.add_method('SetQosAmsdu', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosNoAmsdu() [member function]
+    cls.add_method('SetQosNoAmsdu', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosTxopLimit(uint8_t txop) [member function]
+    cls.add_method('SetQosTxopLimit', 
+                   'void', 
+                   [param('uint8_t', 'txop')])
+    ## wifi-mac-header.h: ns3::Mac48Address ns3::WifiMacHeader::GetAddr1() const [member function]
+    cls.add_method('GetAddr1', 
+                   'ns3::Mac48Address', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: ns3::Mac48Address ns3::WifiMacHeader::GetAddr2() const [member function]
+    cls.add_method('GetAddr2', 
+                   'ns3::Mac48Address', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: ns3::Mac48Address ns3::WifiMacHeader::GetAddr3() const [member function]
+    cls.add_method('GetAddr3', 
+                   'ns3::Mac48Address', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: ns3::Mac48Address ns3::WifiMacHeader::GetAddr4() const [member function]
+    cls.add_method('GetAddr4', 
+                   'ns3::Mac48Address', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: ns3::WifiMacType ns3::WifiMacHeader::GetType() const [member function]
+    cls.add_method('GetType', 
+                   'ns3::WifiMacType', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsFromDs() const [member function]
+    cls.add_method('IsFromDs', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsToDs() const [member function]
+    cls.add_method('IsToDs', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsData() const [member function]
+    cls.add_method('IsData', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsQosData() const [member function]
+    cls.add_method('IsQosData', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsCtl() const [member function]
+    cls.add_method('IsCtl', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsMgt() const [member function]
+    cls.add_method('IsMgt', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsCfpoll() const [member function]
+    cls.add_method('IsCfpoll', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsRts() const [member function]
+    cls.add_method('IsRts', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsCts() const [member function]
+    cls.add_method('IsCts', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsAck() const [member function]
+    cls.add_method('IsAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsAssocReq() const [member function]
+    cls.add_method('IsAssocReq', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsAssocResp() const [member function]
+    cls.add_method('IsAssocResp', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsReassocReq() const [member function]
+    cls.add_method('IsReassocReq', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsReassocResp() const [member function]
+    cls.add_method('IsReassocResp', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsProbeReq() const [member function]
+    cls.add_method('IsProbeReq', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsProbeResp() const [member function]
+    cls.add_method('IsProbeResp', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsBeacon() const [member function]
+    cls.add_method('IsBeacon', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsDisassociation() const [member function]
+    cls.add_method('IsDisassociation', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsAuthentication() const [member function]
+    cls.add_method('IsAuthentication', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsDeauthentication() const [member function]
+    cls.add_method('IsDeauthentication', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: uint16_t ns3::WifiMacHeader::GetRawDuration() const [member function]
+    cls.add_method('GetRawDuration', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: ns3::Time ns3::WifiMacHeader::GetDuration() const [member function]
+    cls.add_method('GetDuration', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: uint16_t ns3::WifiMacHeader::GetSequenceControl() const [member function]
+    cls.add_method('GetSequenceControl', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: uint16_t ns3::WifiMacHeader::GetSequenceNumber() const [member function]
+    cls.add_method('GetSequenceNumber', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: uint16_t ns3::WifiMacHeader::GetFragmentNumber() const [member function]
+    cls.add_method('GetFragmentNumber', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsRetry() const [member function]
+    cls.add_method('IsRetry', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsMoreFragments() const [member function]
+    cls.add_method('IsMoreFragments', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsQosBlockAck() const [member function]
+    cls.add_method('IsQosBlockAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsQosNoAck() const [member function]
+    cls.add_method('IsQosNoAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsQosAck() const [member function]
+    cls.add_method('IsQosAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsQosEosp() const [member function]
+    cls.add_method('IsQosEosp', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsQosAmsdu() const [member function]
+    cls.add_method('IsQosAmsdu', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: uint8_t ns3::WifiMacHeader::GetQosTid() const [member function]
+    cls.add_method('GetQosTid', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: ns3::WifiMacHeader::QosAckPolicy ns3::WifiMacHeader::GetQosAckPolicy() const [member function]
+    cls.add_method('GetQosAckPolicy', 
+                   'ns3::WifiMacHeader::QosAckPolicy', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: uint8_t ns3::WifiMacHeader::GetQosTxopLimit() const [member function]
+    cls.add_method('GetQosTxopLimit', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: uint32_t ns3::WifiMacHeader::GetSize() const [member function]
+    cls.add_method('GetSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: char const * ns3::WifiMacHeader::GetTypeString() const [member function]
+    cls.add_method('GetTypeString', 
+                   'char const *', 
+                   [], 
+                   is_const=True)
+    return
+
 def register_Ns3WifiModeChecker_methods(root_module, cls):
     ## wifi-mode.h: ns3::WifiModeChecker::WifiModeChecker(ns3::WifiModeChecker const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::WifiModeChecker const &', 'arg0')])
@@ -1433,7 +1887,7 @@
                    'void', 
                    [param('ns3::Callback< void, ns3::Ptr< ns3::Packet const >, double, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], 
                    is_pure_virtual=True, is_virtual=True)
-    ## wifi-phy.h: void ns3::WifiPhy::SendPacket(ns3::Ptr<const ns3::Packet> packet, ns3::WifiMode mode, ns3::WifiPreamble preamble, uint8_t txPowerLevel) [member function]
+    ## wifi-phy.h: void ns3::WifiPhy::SendPacket(ns3::Ptr<ns3::Packet const> packet, ns3::WifiMode mode, ns3::WifiPreamble preamble, uint8_t txPowerLevel) [member function]
     cls.add_method('SendPacket', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMode', 'mode'), param('ns3::WifiPreamble', 'preamble'), param('uint8_t', 'txPowerLevel')], 
@@ -1548,31 +2002,31 @@
                    'ns3::WifiMode', 
                    [], 
                    is_static=True)
-    ## wifi-phy.h: void ns3::WifiPhy::NotifyTxBegin(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-phy.h: void ns3::WifiPhy::NotifyTxBegin(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NotifyTxBegin', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')])
-    ## wifi-phy.h: void ns3::WifiPhy::NotifyTxEnd(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-phy.h: void ns3::WifiPhy::NotifyTxEnd(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NotifyTxEnd', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')])
-    ## wifi-phy.h: void ns3::WifiPhy::NotifyTxDrop(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-phy.h: void ns3::WifiPhy::NotifyTxDrop(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NotifyTxDrop', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')])
-    ## wifi-phy.h: void ns3::WifiPhy::NotifyRxBegin(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-phy.h: void ns3::WifiPhy::NotifyRxBegin(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NotifyRxBegin', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')])
-    ## wifi-phy.h: void ns3::WifiPhy::NotifyRxEnd(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-phy.h: void ns3::WifiPhy::NotifyRxEnd(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NotifyRxEnd', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')])
-    ## wifi-phy.h: void ns3::WifiPhy::NotifyRxDrop(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-phy.h: void ns3::WifiPhy::NotifyRxDrop(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NotifyRxDrop', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')])
-    ## wifi-phy.h: void ns3::WifiPhy::NotifyPromiscSniff(ns3::Ptr<const ns3::Packet> packet) [member function]
+    ## wifi-phy.h: void ns3::WifiPhy::NotifyPromiscSniff(ns3::Ptr<ns3::Packet const> packet) [member function]
     cls.add_method('NotifyPromiscSniff', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')])
@@ -1820,7 +2274,7 @@
                    'void', 
                    [param('ns3::Callback< void, ns3::Ptr< ns3::Packet const >, double, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], 
                    is_virtual=True)
-    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SendPacket(ns3::Ptr<const ns3::Packet> packet, ns3::WifiMode mode, ns3::WifiPreamble preamble, uint8_t txPowerLevel) [member function]
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SendPacket(ns3::Ptr<ns3::Packet const> packet, ns3::WifiMode mode, ns3::WifiPreamble preamble, uint8_t txPowerLevel) [member function]
     cls.add_method('SendPacket', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMode', 'mode'), param('ns3::WifiPreamble', 'preamble'), param('uint8_t', 'txPowerLevel')], 
@@ -2002,12 +2456,12 @@
                    'void', 
                    [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], 
                    is_virtual=True)
-    ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::Enqueue(ns3::Ptr<const ns3::Packet> packet, ns3::Mac48Address to, ns3::Mac48Address from) [member function]
+    ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::Enqueue(ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address to, ns3::Mac48Address from) [member function]
     cls.add_method('Enqueue', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from')], 
                    is_virtual=True)
-    ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::Enqueue(ns3::Ptr<const ns3::Packet> packet, ns3::Mac48Address to) [member function]
+    ## adhoc-wifi-mac.h: void ns3::AdhocWifiMac::Enqueue(ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address to) [member function]
     cls.add_method('Enqueue', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'to')], 
@@ -2081,6 +2535,70 @@
                    visibility='private', is_virtual=True)
     return
 
+def register_Ns3AmsduSubframeHeader_methods(root_module, cls):
+    ## amsdu-subframe-header.h: ns3::AmsduSubframeHeader::AmsduSubframeHeader(ns3::AmsduSubframeHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::AmsduSubframeHeader const &', 'arg0')])
+    ## amsdu-subframe-header.h: ns3::AmsduSubframeHeader::AmsduSubframeHeader() [constructor]
+    cls.add_constructor([])
+    ## amsdu-subframe-header.h: static ns3::TypeId ns3::AmsduSubframeHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## amsdu-subframe-header.h: ns3::TypeId ns3::AmsduSubframeHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## amsdu-subframe-header.h: void ns3::AmsduSubframeHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## amsdu-subframe-header.h: uint32_t ns3::AmsduSubframeHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## amsdu-subframe-header.h: void ns3::AmsduSubframeHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    ## amsdu-subframe-header.h: uint32_t ns3::AmsduSubframeHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## amsdu-subframe-header.h: void ns3::AmsduSubframeHeader::SetDestinationAddr(ns3::Mac48Address to) [member function]
+    cls.add_method('SetDestinationAddr', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'to')])
+    ## amsdu-subframe-header.h: void ns3::AmsduSubframeHeader::SetSourceAddr(ns3::Mac48Address to) [member function]
+    cls.add_method('SetSourceAddr', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'to')])
+    ## amsdu-subframe-header.h: void ns3::AmsduSubframeHeader::SetLength(uint16_t arg0) [member function]
+    cls.add_method('SetLength', 
+                   'void', 
+                   [param('uint16_t', 'arg0')])
+    ## amsdu-subframe-header.h: ns3::Mac48Address ns3::AmsduSubframeHeader::GetDestinationAddr() const [member function]
+    cls.add_method('GetDestinationAddr', 
+                   'ns3::Mac48Address', 
+                   [], 
+                   is_const=True)
+    ## amsdu-subframe-header.h: ns3::Mac48Address ns3::AmsduSubframeHeader::GetSourceAddr() const [member function]
+    cls.add_method('GetSourceAddr', 
+                   'ns3::Mac48Address', 
+                   [], 
+                   is_const=True)
+    ## amsdu-subframe-header.h: uint16_t ns3::AmsduSubframeHeader::GetLength() const [member function]
+    cls.add_method('GetLength', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    return
+
 def register_Ns3ArfWifiManager_methods(root_module, cls):
     ## arf-wifi-manager.h: ns3::ArfWifiManager::ArfWifiManager(ns3::ArfWifiManager const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::ArfWifiManager const &', 'arg0')])
@@ -2151,6 +2669,276 @@
                    is_const=True)
     return
 
+def register_Ns3DcaTxop_methods(root_module, cls):
+    ## dca-txop.h: static ns3::TypeId ns3::DcaTxop::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## dca-txop.h: ns3::DcaTxop::DcaTxop() [constructor]
+    cls.add_constructor([])
+    ## dca-txop.h: void ns3::DcaTxop::SetLow(ns3::Ptr<ns3::MacLow> low) [member function]
+    cls.add_method('SetLow', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::MacLow >', 'low')])
+    ## dca-txop.h: void ns3::DcaTxop::SetManager(ns3::DcfManager * manager) [member function]
+    cls.add_method('SetManager', 
+                   'void', 
+                   [param('ns3::DcfManager *', 'manager')])
+    ## dca-txop.h: void ns3::DcaTxop::SetWifiRemoteStationManager(ns3::Ptr<ns3::WifiRemoteStationManager> remoteManager) [member function]
+    cls.add_method('SetWifiRemoteStationManager', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'remoteManager')])
+    ## dca-txop.h: void ns3::DcaTxop::SetTxOkCallback(ns3::Callback<void, ns3::WifiMacHeader const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
+    cls.add_method('SetTxOkCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::WifiMacHeader const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
+    ## dca-txop.h: void ns3::DcaTxop::SetTxFailedCallback(ns3::Callback<void, ns3::WifiMacHeader const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
+    cls.add_method('SetTxFailedCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::WifiMacHeader const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
+    ## dca-txop.h: void ns3::DcaTxop::SetMaxQueueSize(uint32_t size) [member function]
+    cls.add_method('SetMaxQueueSize', 
+                   'void', 
+                   [param('uint32_t', 'size')])
+    ## dca-txop.h: void ns3::DcaTxop::SetMaxQueueDelay(ns3::Time delay) [member function]
+    cls.add_method('SetMaxQueueDelay', 
+                   'void', 
+                   [param('ns3::Time', 'delay')])
+    ## dca-txop.h: void ns3::DcaTxop::SetMinCw(uint32_t minCw) [member function]
+    cls.add_method('SetMinCw', 
+                   'void', 
+                   [param('uint32_t', 'minCw')])
+    ## dca-txop.h: void ns3::DcaTxop::SetMaxCw(uint32_t maxCw) [member function]
+    cls.add_method('SetMaxCw', 
+                   'void', 
+                   [param('uint32_t', 'maxCw')])
+    ## dca-txop.h: void ns3::DcaTxop::SetAifsn(uint32_t aifsn) [member function]
+    cls.add_method('SetAifsn', 
+                   'void', 
+                   [param('uint32_t', 'aifsn')])
+    ## dca-txop.h: uint32_t ns3::DcaTxop::GetMinCw() const [member function]
+    cls.add_method('GetMinCw', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True)
+    ## dca-txop.h: uint32_t ns3::DcaTxop::GetMaxCw() const [member function]
+    cls.add_method('GetMaxCw', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True)
+    ## dca-txop.h: uint32_t ns3::DcaTxop::GetAifsn() const [member function]
+    cls.add_method('GetAifsn', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True)
+    ## dca-txop.h: void ns3::DcaTxop::Queue(ns3::Ptr<ns3::Packet const> packet, ns3::WifiMacHeader const & hdr) [member function]
+    cls.add_method('Queue', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const &', 'hdr')])
+    ## dca-txop.h: void ns3::DcaTxop::DoDispose() [member function]
+    cls.add_method('DoDispose', 
+                   'void', 
+                   [], 
+                   visibility='private', is_virtual=True)
+    return
+
+def register_Ns3EdcaTxopN_methods(root_module, cls):
+    ## edca-txop-n.h: static ns3::TypeId ns3::EdcaTxopN::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## edca-txop-n.h: ns3::EdcaTxopN::EdcaTxopN() [constructor]
+    cls.add_constructor([])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::DoDispose() [member function]
+    cls.add_method('DoDispose', 
+                   'void', 
+                   [], 
+                   is_virtual=True)
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetLow(ns3::Ptr<ns3::MacLow> low) [member function]
+    cls.add_method('SetLow', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::MacLow >', 'low')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetTxMiddle(ns3::MacTxMiddle * txMiddle) [member function]
+    cls.add_method('SetTxMiddle', 
+                   'void', 
+                   [param('ns3::MacTxMiddle *', 'txMiddle')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetManager(ns3::DcfManager * manager) [member function]
+    cls.add_method('SetManager', 
+                   'void', 
+                   [param('ns3::DcfManager *', 'manager')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetTxOkCallback(ns3::Callback<void, ns3::WifiMacHeader const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
+    cls.add_method('SetTxOkCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::WifiMacHeader const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetTxFailedCallback(ns3::Callback<void, ns3::WifiMacHeader const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
+    cls.add_method('SetTxFailedCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::WifiMacHeader const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetWifiRemoteStationManager(ns3::Ptr<ns3::WifiRemoteStationManager> remoteManager) [member function]
+    cls.add_method('SetWifiRemoteStationManager', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'remoteManager')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetTypeOfStation(ns3::TypeOfStation type) [member function]
+    cls.add_method('SetTypeOfStation', 
+                   'void', 
+                   [param('ns3::TypeOfStation', 'type')])
+    ## edca-txop-n.h: ns3::TypeOfStation ns3::EdcaTxopN::GetTypeOfStation() const [member function]
+    cls.add_method('GetTypeOfStation', 
+                   'ns3::TypeOfStation', 
+                   [], 
+                   is_const=True)
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetMaxQueueSize(uint32_t size) [member function]
+    cls.add_method('SetMaxQueueSize', 
+                   'void', 
+                   [param('uint32_t', 'size')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetMaxQueueDelay(ns3::Time delay) [member function]
+    cls.add_method('SetMaxQueueDelay', 
+                   'void', 
+                   [param('ns3::Time', 'delay')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetMinCw(uint32_t minCw) [member function]
+    cls.add_method('SetMinCw', 
+                   'void', 
+                   [param('uint32_t', 'minCw')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetMaxCw(uint32_t maxCw) [member function]
+    cls.add_method('SetMaxCw', 
+                   'void', 
+                   [param('uint32_t', 'maxCw')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetAifsn(uint32_t aifsn) [member function]
+    cls.add_method('SetAifsn', 
+                   'void', 
+                   [param('uint32_t', 'aifsn')])
+    ## edca-txop-n.h: uint32_t ns3::EdcaTxopN::GetMinCw() const [member function]
+    cls.add_method('GetMinCw', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True)
+    ## edca-txop-n.h: uint32_t ns3::EdcaTxopN::GetMaxCw() const [member function]
+    cls.add_method('GetMaxCw', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True)
+    ## edca-txop-n.h: uint32_t ns3::EdcaTxopN::GetAifsn() const [member function]
+    cls.add_method('GetAifsn', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True)
+    ## edca-txop-n.h: ns3::Ptr<ns3::MacLow> ns3::EdcaTxopN::Low() [member function]
+    cls.add_method('Low', 
+                   'ns3::Ptr< ns3::MacLow >', 
+                   [])
+    ## edca-txop-n.h: ns3::Ptr<ns3::MsduAggregator> ns3::EdcaTxopN::GetMsduAggregator() const [member function]
+    cls.add_method('GetMsduAggregator', 
+                   'ns3::Ptr< ns3::MsduAggregator >', 
+                   [], 
+                   is_const=True)
+    ## edca-txop-n.h: bool ns3::EdcaTxopN::NeedsAccess() const [member function]
+    cls.add_method('NeedsAccess', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## edca-txop-n.h: void ns3::EdcaTxopN::NotifyAccessGranted() [member function]
+    cls.add_method('NotifyAccessGranted', 
+                   'void', 
+                   [])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::NotifyInternalCollision() [member function]
+    cls.add_method('NotifyInternalCollision', 
+                   'void', 
+                   [])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::NotifyCollision() [member function]
+    cls.add_method('NotifyCollision', 
+                   'void', 
+                   [])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::GotCts(double snr, ns3::WifiMode txMode) [member function]
+    cls.add_method('GotCts', 
+                   'void', 
+                   [param('double', 'snr'), param('ns3::WifiMode', 'txMode')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::MissedCts() [member function]
+    cls.add_method('MissedCts', 
+                   'void', 
+                   [])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::GotAck(double snr, ns3::WifiMode txMode) [member function]
+    cls.add_method('GotAck', 
+                   'void', 
+                   [param('double', 'snr'), param('ns3::WifiMode', 'txMode')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::MissedAck() [member function]
+    cls.add_method('MissedAck', 
+                   'void', 
+                   [])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::StartNext() [member function]
+    cls.add_method('StartNext', 
+                   'void', 
+                   [])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::Cancel() [member function]
+    cls.add_method('Cancel', 
+                   'void', 
+                   [])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::RestartAccessIfNeeded() [member function]
+    cls.add_method('RestartAccessIfNeeded', 
+                   'void', 
+                   [])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::StartAccessIfNeeded() [member function]
+    cls.add_method('StartAccessIfNeeded', 
+                   'void', 
+                   [])
+    ## edca-txop-n.h: bool ns3::EdcaTxopN::NeedRts() [member function]
+    cls.add_method('NeedRts', 
+                   'bool', 
+                   [])
+    ## edca-txop-n.h: bool ns3::EdcaTxopN::NeedRtsRetransmission() [member function]
+    cls.add_method('NeedRtsRetransmission', 
+                   'bool', 
+                   [])
+    ## edca-txop-n.h: bool ns3::EdcaTxopN::NeedDataRetransmission() [member function]
+    cls.add_method('NeedDataRetransmission', 
+                   'bool', 
+                   [])
+    ## edca-txop-n.h: bool ns3::EdcaTxopN::NeedFragmentation() const [member function]
+    cls.add_method('NeedFragmentation', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## edca-txop-n.h: uint32_t ns3::EdcaTxopN::GetNextFragmentSize() [member function]
+    cls.add_method('GetNextFragmentSize', 
+                   'uint32_t', 
+                   [])
+    ## edca-txop-n.h: uint32_t ns3::EdcaTxopN::GetFragmentSize() [member function]
+    cls.add_method('GetFragmentSize', 
+                   'uint32_t', 
+                   [])
+    ## edca-txop-n.h: uint32_t ns3::EdcaTxopN::GetFragmentOffset() [member function]
+    cls.add_method('GetFragmentOffset', 
+                   'uint32_t', 
+                   [])
+    ## edca-txop-n.h: ns3::WifiRemoteStation * ns3::EdcaTxopN::GetStation(ns3::Mac48Address to) const [member function]
+    cls.add_method('GetStation', 
+                   'ns3::WifiRemoteStation *', 
+                   [param('ns3::Mac48Address', 'to')], 
+                   is_const=True)
+    ## edca-txop-n.h: bool ns3::EdcaTxopN::IsLastFragment() const [member function]
+    cls.add_method('IsLastFragment', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## edca-txop-n.h: void ns3::EdcaTxopN::NextFragment() [member function]
+    cls.add_method('NextFragment', 
+                   'void', 
+                   [])
+    ## edca-txop-n.h: ns3::Ptr<ns3::Packet> ns3::EdcaTxopN::GetFragmentPacket(ns3::WifiMacHeader * hdr) [member function]
+    cls.add_method('GetFragmentPacket', 
+                   'ns3::Ptr< ns3::Packet >', 
+                   [param('ns3::WifiMacHeader *', 'hdr')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::Queue(ns3::Ptr<ns3::Packet const> packet, ns3::WifiMacHeader const & hdr) [member function]
+    cls.add_method('Queue', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const &', 'hdr')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetMsduAggregator(ns3::Ptr<ns3::MsduAggregator> aggr) [member function]
+    cls.add_method('SetMsduAggregator', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::MsduAggregator >', 'aggr')])
+    return
+
 def register_Ns3ErrorRateModel_methods(root_module, cls):
     ## error-rate-model.h: ns3::ErrorRateModel::ErrorRateModel(ns3::ErrorRateModel const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::ErrorRateModel const &', 'arg0')])
@@ -2301,6 +3089,28 @@
                    is_const=True, visibility='private', is_virtual=True)
     return
 
+def register_Ns3MsduAggregator_methods(root_module, cls):
+    ## msdu-aggregator.h: ns3::MsduAggregator::MsduAggregator(ns3::MsduAggregator const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::MsduAggregator const &', 'arg0')])
+    ## msdu-aggregator.h: ns3::MsduAggregator::MsduAggregator() [constructor]
+    cls.add_constructor([])
+    ## msdu-aggregator.h: static ns3::TypeId ns3::MsduAggregator::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## msdu-aggregator.h: bool ns3::MsduAggregator::Aggregate(ns3::Ptr<ns3::Packet const> packet, ns3::Ptr<ns3::Packet> aggregatedPacket, ns3::Mac48Address src, ns3::Mac48Address dest) [member function]
+    cls.add_method('Aggregate', 
+                   'bool', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Ptr< ns3::Packet >', 'aggregatedPacket'), param('ns3::Mac48Address', 'src'), param('ns3::Mac48Address', 'dest')], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## msdu-aggregator.h: static std::list<std::pair<ns3::Ptr<ns3::Packet>, ns3::AmsduSubframeHeader>, std::allocator<std::pair<ns3::Ptr<ns3::Packet>, ns3::AmsduSubframeHeader> > > ns3::MsduAggregator::Deaggregate(ns3::Ptr<ns3::Packet> aggregatedPacket) [member function]
+    cls.add_method('Deaggregate', 
+                   'std::list< std::pair< ns3::Ptr< ns3::Packet >, ns3::AmsduSubframeHeader > >', 
+                   [param('ns3::Ptr< ns3::Packet >', 'aggregatedPacket')], 
+                   is_static=True)
+    return
+
 def register_Ns3NqapWifiMac_methods(root_module, cls):
     ## nqap-wifi-mac.h: static ns3::TypeId ns3::NqapWifiMac::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
@@ -2379,12 +3189,12 @@
                    'void', 
                    [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], 
                    is_virtual=True)
-    ## nqap-wifi-mac.h: void ns3::NqapWifiMac::Enqueue(ns3::Ptr<const ns3::Packet> packet, ns3::Mac48Address to, ns3::Mac48Address from) [member function]
+    ## nqap-wifi-mac.h: void ns3::NqapWifiMac::Enqueue(ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address to, ns3::Mac48Address from) [member function]
     cls.add_method('Enqueue', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from')], 
                    is_virtual=True)
-    ## nqap-wifi-mac.h: void ns3::NqapWifiMac::Enqueue(ns3::Ptr<const ns3::Packet> packet, ns3::Mac48Address to) [member function]
+    ## nqap-wifi-mac.h: void ns3::NqapWifiMac::Enqueue(ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address to) [member function]
     cls.add_method('Enqueue', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'to')], 
@@ -2532,12 +3342,12 @@
                    'void', 
                    [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], 
                    is_virtual=True)
-    ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::Enqueue(ns3::Ptr<const ns3::Packet> packet, ns3::Mac48Address to, ns3::Mac48Address from) [member function]
+    ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::Enqueue(ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address to, ns3::Mac48Address from) [member function]
     cls.add_method('Enqueue', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from')], 
                    is_virtual=True)
-    ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::Enqueue(ns3::Ptr<const ns3::Packet> packet, ns3::Mac48Address to) [member function]
+    ## nqsta-wifi-mac.h: void ns3::NqstaWifiMac::Enqueue(ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address to) [member function]
     cls.add_method('Enqueue', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'to')], 
@@ -2627,6 +3437,455 @@
                    visibility='private', is_virtual=True)
     return
 
+def register_Ns3QadhocWifiMac_methods(root_module, cls):
+    ## qadhoc-wifi-mac.h: static ns3::TypeId ns3::QadhocWifiMac::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## qadhoc-wifi-mac.h: ns3::QadhocWifiMac::QadhocWifiMac() [constructor]
+    cls.add_constructor([])
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetSlot(ns3::Time slotTime) [member function]
+    cls.add_method('SetSlot', 
+                   'void', 
+                   [param('ns3::Time', 'slotTime')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetSifs(ns3::Time sifs) [member function]
+    cls.add_method('SetSifs', 
+                   'void', 
+                   [param('ns3::Time', 'sifs')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetEifsNoDifs(ns3::Time eifsNoDifs) [member function]
+    cls.add_method('SetEifsNoDifs', 
+                   'void', 
+                   [param('ns3::Time', 'eifsNoDifs')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetAckTimeout(ns3::Time ackTimeout) [member function]
+    cls.add_method('SetAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'ackTimeout')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetCtsTimeout(ns3::Time ctsTimeout) [member function]
+    cls.add_method('SetCtsTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'ctsTimeout')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetPifs(ns3::Time pifs) [member function]
+    cls.add_method('SetPifs', 
+                   'void', 
+                   [param('ns3::Time', 'pifs')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: ns3::Time ns3::QadhocWifiMac::GetSlot() const [member function]
+    cls.add_method('GetSlot', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qadhoc-wifi-mac.h: ns3::Time ns3::QadhocWifiMac::GetSifs() const [member function]
+    cls.add_method('GetSifs', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qadhoc-wifi-mac.h: ns3::Time ns3::QadhocWifiMac::GetEifsNoDifs() const [member function]
+    cls.add_method('GetEifsNoDifs', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qadhoc-wifi-mac.h: ns3::Time ns3::QadhocWifiMac::GetAckTimeout() const [member function]
+    cls.add_method('GetAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qadhoc-wifi-mac.h: ns3::Time ns3::QadhocWifiMac::GetCtsTimeout() const [member function]
+    cls.add_method('GetCtsTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qadhoc-wifi-mac.h: ns3::Time ns3::QadhocWifiMac::GetPifs() const [member function]
+    cls.add_method('GetPifs', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetWifiPhy(ns3::Ptr<ns3::WifiPhy> phy) [member function]
+    cls.add_method('SetWifiPhy', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetWifiRemoteStationManager(ns3::Ptr<ns3::WifiRemoteStationManager> stationManager) [member function]
+    cls.add_method('SetWifiRemoteStationManager', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::Enqueue(ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address to, ns3::Mac48Address from) [member function]
+    cls.add_method('Enqueue', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::Enqueue(ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address to) [member function]
+    cls.add_method('Enqueue', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'to')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: bool ns3::QadhocWifiMac::SupportsSendFrom() const [member function]
+    cls.add_method('SupportsSendFrom', 
+                   'bool', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetForwardUpCallback(ns3::Callback<void, ns3::Ptr<ns3::Packet>, ns3::Mac48Address, ns3::Mac48Address, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> upCallback) [member function]
+    cls.add_method('SetForwardUpCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address, ns3::Mac48Address, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetLinkUpCallback(ns3::Callback<void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> linkUp) [member function]
+    cls.add_method('SetLinkUpCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetLinkDownCallback(ns3::Callback<void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> linkDown) [member function]
+    cls.add_method('SetLinkDownCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: ns3::Mac48Address ns3::QadhocWifiMac::GetAddress() const [member function]
+    cls.add_method('GetAddress', 
+                   'ns3::Mac48Address', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qadhoc-wifi-mac.h: ns3::Ssid ns3::QadhocWifiMac::GetSsid() const [member function]
+    cls.add_method('GetSsid', 
+                   'ns3::Ssid', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetAddress(ns3::Mac48Address address) [member function]
+    cls.add_method('SetAddress', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'address')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetSsid(ns3::Ssid ssid) [member function]
+    cls.add_method('SetSsid', 
+                   'void', 
+                   [param('ns3::Ssid', 'ssid')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: ns3::Mac48Address ns3::QadhocWifiMac::GetBssid() const [member function]
+    cls.add_method('GetBssid', 
+                   'ns3::Mac48Address', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::DoDispose() [member function]
+    cls.add_method('DoDispose', 
+                   'void', 
+                   [], 
+                   visibility='private', is_virtual=True)
+    return
+
+def register_Ns3QapWifiMac_methods(root_module, cls):
+    ## qap-wifi-mac.h: static ns3::TypeId ns3::QapWifiMac::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## qap-wifi-mac.h: ns3::QapWifiMac::QapWifiMac() [constructor]
+    cls.add_constructor([])
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetSlot(ns3::Time slotTime) [member function]
+    cls.add_method('SetSlot', 
+                   'void', 
+                   [param('ns3::Time', 'slotTime')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetSifs(ns3::Time sifs) [member function]
+    cls.add_method('SetSifs', 
+                   'void', 
+                   [param('ns3::Time', 'sifs')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetEifsNoDifs(ns3::Time eifsNoDifs) [member function]
+    cls.add_method('SetEifsNoDifs', 
+                   'void', 
+                   [param('ns3::Time', 'eifsNoDifs')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetAckTimeout(ns3::Time ackTimeout) [member function]
+    cls.add_method('SetAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'ackTimeout')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetCtsTimeout(ns3::Time ctsTimeout) [member function]
+    cls.add_method('SetCtsTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'ctsTimeout')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetPifs(ns3::Time pifs) [member function]
+    cls.add_method('SetPifs', 
+                   'void', 
+                   [param('ns3::Time', 'pifs')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: ns3::Time ns3::QapWifiMac::GetSlot() const [member function]
+    cls.add_method('GetSlot', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qap-wifi-mac.h: ns3::Time ns3::QapWifiMac::GetSifs() const [member function]
+    cls.add_method('GetSifs', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qap-wifi-mac.h: ns3::Time ns3::QapWifiMac::GetEifsNoDifs() const [member function]
+    cls.add_method('GetEifsNoDifs', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qap-wifi-mac.h: ns3::Time ns3::QapWifiMac::GetAckTimeout() const [member function]
+    cls.add_method('GetAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qap-wifi-mac.h: ns3::Time ns3::QapWifiMac::GetCtsTimeout() const [member function]
+    cls.add_method('GetCtsTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qap-wifi-mac.h: ns3::Time ns3::QapWifiMac::GetPifs() const [member function]
+    cls.add_method('GetPifs', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetWifiPhy(ns3::Ptr<ns3::WifiPhy> phy) [member function]
+    cls.add_method('SetWifiPhy', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetWifiRemoteStationManager(ns3::Ptr<ns3::WifiRemoteStationManager> stationManager) [member function]
+    cls.add_method('SetWifiRemoteStationManager', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::Enqueue(ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address to, ns3::Mac48Address from) [member function]
+    cls.add_method('Enqueue', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::Enqueue(ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address to) [member function]
+    cls.add_method('Enqueue', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'to')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: bool ns3::QapWifiMac::SupportsSendFrom() const [member function]
+    cls.add_method('SupportsSendFrom', 
+                   'bool', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetForwardUpCallback(ns3::Callback<void, ns3::Ptr<ns3::Packet>, ns3::Mac48Address, ns3::Mac48Address, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> upCallback) [member function]
+    cls.add_method('SetForwardUpCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address, ns3::Mac48Address, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetLinkUpCallback(ns3::Callback<void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> linkUp) [member function]
+    cls.add_method('SetLinkUpCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetLinkDownCallback(ns3::Callback<void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> linkDown) [member function]
+    cls.add_method('SetLinkDownCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: ns3::Mac48Address ns3::QapWifiMac::GetAddress() const [member function]
+    cls.add_method('GetAddress', 
+                   'ns3::Mac48Address', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qap-wifi-mac.h: ns3::Ssid ns3::QapWifiMac::GetSsid() const [member function]
+    cls.add_method('GetSsid', 
+                   'ns3::Ssid', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetAddress(ns3::Mac48Address address) [member function]
+    cls.add_method('SetAddress', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'address')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetSsid(ns3::Ssid ssid) [member function]
+    cls.add_method('SetSsid', 
+                   'void', 
+                   [param('ns3::Ssid', 'ssid')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: ns3::Mac48Address ns3::QapWifiMac::GetBssid() const [member function]
+    cls.add_method('GetBssid', 
+                   'ns3::Mac48Address', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetBeaconInterval(ns3::Time interval) [member function]
+    cls.add_method('SetBeaconInterval', 
+                   'void', 
+                   [param('ns3::Time', 'interval')])
+    ## qap-wifi-mac.h: ns3::Time ns3::QapWifiMac::GetBeaconInterval() const [member function]
+    cls.add_method('GetBeaconInterval', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::StartBeaconing() [member function]
+    cls.add_method('StartBeaconing', 
+                   'void', 
+                   [])
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::DoDispose() [member function]
+    cls.add_method('DoDispose', 
+                   'void', 
+                   [], 
+                   visibility='private', is_virtual=True)
+    return
+
+def register_Ns3QstaWifiMac_methods(root_module, cls):
+    ## qsta-wifi-mac.h: static ns3::TypeId ns3::QstaWifiMac::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## qsta-wifi-mac.h: ns3::QstaWifiMac::QstaWifiMac() [constructor]
+    cls.add_constructor([])
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetSlot(ns3::Time slotTime) [member function]
+    cls.add_method('SetSlot', 
+                   'void', 
+                   [param('ns3::Time', 'slotTime')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetSifs(ns3::Time sifs) [member function]
+    cls.add_method('SetSifs', 
+                   'void', 
+                   [param('ns3::Time', 'sifs')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetEifsNoDifs(ns3::Time eifsNoDifs) [member function]
+    cls.add_method('SetEifsNoDifs', 
+                   'void', 
+                   [param('ns3::Time', 'eifsNoDifs')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetAckTimeout(ns3::Time ackTimeout) [member function]
+    cls.add_method('SetAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'ackTimeout')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetCtsTimeout(ns3::Time ctsTimeout) [member function]
+    cls.add_method('SetCtsTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'ctsTimeout')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetPifs(ns3::Time pifs) [member function]
+    cls.add_method('SetPifs', 
+                   'void', 
+                   [param('ns3::Time', 'pifs')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: ns3::Time ns3::QstaWifiMac::GetSlot() const [member function]
+    cls.add_method('GetSlot', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qsta-wifi-mac.h: ns3::Time ns3::QstaWifiMac::GetSifs() const [member function]
+    cls.add_method('GetSifs', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qsta-wifi-mac.h: ns3::Time ns3::QstaWifiMac::GetEifsNoDifs() const [member function]
+    cls.add_method('GetEifsNoDifs', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qsta-wifi-mac.h: ns3::Time ns3::QstaWifiMac::GetAckTimeout() const [member function]
+    cls.add_method('GetAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qsta-wifi-mac.h: ns3::Time ns3::QstaWifiMac::GetCtsTimeout() const [member function]
+    cls.add_method('GetCtsTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qsta-wifi-mac.h: ns3::Time ns3::QstaWifiMac::GetPifs() const [member function]
+    cls.add_method('GetPifs', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetWifiPhy(ns3::Ptr<ns3::WifiPhy> phy) [member function]
+    cls.add_method('SetWifiPhy', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetWifiRemoteStationManager(ns3::Ptr<ns3::WifiRemoteStationManager> stationManager) [member function]
+    cls.add_method('SetWifiRemoteStationManager', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::Enqueue(ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address to, ns3::Mac48Address from) [member function]
+    cls.add_method('Enqueue', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::Enqueue(ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address to) [member function]
+    cls.add_method('Enqueue', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'to')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: bool ns3::QstaWifiMac::SupportsSendFrom() const [member function]
+    cls.add_method('SupportsSendFrom', 
+                   'bool', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetForwardUpCallback(ns3::Callback<void, ns3::Ptr<ns3::Packet>, ns3::Mac48Address, ns3::Mac48Address, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> upCallback) [member function]
+    cls.add_method('SetForwardUpCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::Mac48Address, ns3::Mac48Address, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'upCallback')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetLinkUpCallback(ns3::Callback<void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> linkUp) [member function]
+    cls.add_method('SetLinkUpCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkUp')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetLinkDownCallback(ns3::Callback<void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> linkDown) [member function]
+    cls.add_method('SetLinkDownCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: ns3::Mac48Address ns3::QstaWifiMac::GetAddress() const [member function]
+    cls.add_method('GetAddress', 
+                   'ns3::Mac48Address', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qsta-wifi-mac.h: ns3::Ssid ns3::QstaWifiMac::GetSsid() const [member function]
+    cls.add_method('GetSsid', 
+                   'ns3::Ssid', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetAddress(ns3::Mac48Address address) [member function]
+    cls.add_method('SetAddress', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'address')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetSsid(ns3::Ssid ssid) [member function]
+    cls.add_method('SetSsid', 
+                   'void', 
+                   [param('ns3::Ssid', 'ssid')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: ns3::Mac48Address ns3::QstaWifiMac::GetBssid() const [member function]
+    cls.add_method('GetBssid', 
+                   'ns3::Mac48Address', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetMaxMissedBeacons(uint32_t missed) [member function]
+    cls.add_method('SetMaxMissedBeacons', 
+                   'void', 
+                   [param('uint32_t', 'missed')])
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetProbeRequestTimeout(ns3::Time timeout) [member function]
+    cls.add_method('SetProbeRequestTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'timeout')])
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetAssocRequestTimeout(ns3::Time timeout) [member function]
+    cls.add_method('SetAssocRequestTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'timeout')])
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::StartActiveAssociation() [member function]
+    cls.add_method('StartActiveAssociation', 
+                   'void', 
+                   [])
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::DoDispose() [member function]
+    cls.add_method('DoDispose', 
+                   'void', 
+                   [], 
+                   visibility='private', is_virtual=True)
+    return
+
 def register_Ns3RraaWifiManager_methods(root_module, cls):
     ## rraa-wifi-manager.h: ns3::RraaWifiManager::RraaWifiManager(ns3::RraaWifiManager const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::RraaWifiManager const &', 'arg0')])
@@ -2878,7 +4137,7 @@
     cls.add_method('SetPropagationDelayModel', 
                    'void', 
                    [param('ns3::Ptr< ns3::PropagationDelayModel >', 'delay')])
-    ## yans-wifi-channel.h: void ns3::YansWifiChannel::Send(ns3::Ptr<ns3::YansWifiPhy> sender, ns3::Ptr<const ns3::Packet> packet, double txPowerDbm, ns3::WifiMode wifiMode, ns3::WifiPreamble preamble) const [member function]
+    ## yans-wifi-channel.h: void ns3::YansWifiChannel::Send(ns3::Ptr<ns3::YansWifiPhy> sender, ns3::Ptr<ns3::Packet const> packet, double txPowerDbm, ns3::WifiMode wifiMode, ns3::WifiPreamble preamble) const [member function]
     cls.add_method('Send', 
                    'void', 
                    [param('ns3::Ptr< ns3::YansWifiPhy >', 'sender'), param('ns3::Ptr< ns3::Packet const >', 'packet'), param('double', 'txPowerDbm'), param('ns3::WifiMode', 'wifiMode'), param('ns3::WifiPreamble', 'preamble')], 
@@ -2912,6 +4171,14 @@
     module.add_function('MakeWifiModeChecker', 
                         'ns3::Ptr< ns3::AttributeChecker const >', 
                         [])
+    ## qos-utils.h: extern uint8_t ns3::QosUtilsGetTidForPacket(ns3::Ptr<ns3::Packet const> packet) [free function]
+    module.add_function('QosUtilsGetTidForPacket', 
+                        'uint8_t', 
+                        [param('ns3::Ptr< ns3::Packet const >', 'packet')])
+    ## qos-utils.h: extern ns3::AccessClass ns3::QosUtilsMapTidToAc(uint8_t tid) [free function]
+    module.add_function('QosUtilsMapTidToAc', 
+                        'ns3::AccessClass', 
+                        [param('uint8_t', 'tid')])
     register_functions_ns3_Config(module.get_submodule('Config'), root_module)
     register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
     register_functions_ns3_internal(module.get_submodule('internal'), root_module)
--- a/bindings/python/ns3modulegen_generated.py	Wed Apr 29 18:59:48 2009 +0400
+++ b/bindings/python/ns3modulegen_generated.py	Wed Apr 29 18:26:25 2009 +0400
@@ -274,6 +274,7 @@
     root_module.end_section('ns3_module_helper')
     module.add_container('std::vector< unsigned int >', 'unsigned int', container_type='vector')
     module.add_container('std::list< unsigned int >', 'unsigned int', container_type='list')
+    module.add_container('std::list< std::pair< ns3::Ptr< ns3::Packet >, ns3::AmsduSubframeHeader > >', 'std::pair< ns3::Ptr< ns3::Packet >, ns3::AmsduSubframeHeader >', container_type='list')
     
     ## Register a nested module for the namespace Config
     
--- a/bindings/python/wscript	Wed Apr 29 18:59:48 2009 +0400
+++ b/bindings/python/wscript	Wed Apr 29 18:26:25 2009 +0400
@@ -445,6 +445,10 @@
         pymod.target = 'ns3/_ns3'
         pymod.name = 'ns3module'
         pymod.uselib_local = "ns3"
+        if pymod.env['ENABLE_STATIC_NS3']:
+            pymod.env.append_value('LINKFLAGS', '-Wl,--whole-archive,-Bstatic')
+            pymod.env.append_value('LINKFLAGS', '-lns3')
+            pymod.env.append_value('LINKFLAGS', '-Wl,-Bdynamic,--no-whole-archive')
 
         defines = list(pymod.env['CXXDEFINES'])
         defines.extend(['NS_DEPRECATED=', 'NS3_DEPRECATED_H'])
--- a/doc/manual/attributes.texi	Wed Apr 29 18:59:48 2009 +0400
+++ b/doc/manual/attributes.texi	Wed Apr 29 18:26:25 2009 +0400
@@ -3,7 +3,7 @@
 @anchor{chap:Attributes}
 
 @menu
-* Object Overview::
+* Object Overview::::
 * Attribute Overview::
 * Extending attributes::
 * Adding new class type::
@@ -54,7 +54,6 @@
 
 Let's review a couple of properties of these objects.
 
-@node Smart pointers
 @subsection Smart pointers
 
 As introduced in the ns-3 tutorial, ns-3 objects are memory managed by a 
@@ -69,10 +68,9 @@
   // etc.
 @end verbatim
 
-@node CreateObject
 @subsection CreateObject
 
-As we discussed above in @ref{Object Creation}, 
+As we discussed above in @ref{Memory management and class Ptr},
 at the lowest-level API, objects of type @code{ns3::Object} are 
 not instantiated using @code{operator new} as usual but instead by
 a templated function called @code{CreateObject()}.
@@ -97,7 +95,6 @@
 this is because there are some helper objects in effect that 
 are doing the CreateObject()s for you.
 
-@node TypeId
 @subsection TypeId
 
 ns-3 classes that derive from class ns3::Object can include
@@ -110,7 +107,6 @@
  @item the set of accessible constructors in the subclass
 @end itemize
 
-@node Object Summary
 @subsection Object Summary
 
 Putting all of these concepts together, let's look at a specific
@@ -175,7 +171,6 @@
 constituent member objects, and help text and default values for
 each parameter.
 
-@node Functional overview
 @subsection Functional overview
 
 We provide a way for users to access values deep in the system, without
@@ -244,7 +239,6 @@
 section, we will provide an example script that shows how users
 may manipulate these values.
 
-@node Basic usage
 @subsection Basic usage
 
 Let's look at how a user script might access these values.  
@@ -379,7 +373,6 @@
     limit.Get () << " packets");
 @end verbatim
 
-@node Setting through constructors and helper classes
 @subsection Setting through constructors helper classes
 
 Arbitrary combinations of attributes can be set and fetched from
@@ -398,7 +391,6 @@
                                  "LayoutType", StringValue ("RowFirst"));
 @end verbatim
 
-@node Value classes
 @subsection Value classes
 Readers will note the new FooValue classes which are subclasses of the
 AttributeValue base class.  These can be thought of as
--- a/doc/manual/callbacks.texi	Wed Apr 29 18:59:48 2009 +0400
+++ b/doc/manual/callbacks.texi	Wed Apr 29 18:26:25 2009 +0400
@@ -129,7 +129,6 @@
 This is best observed via walking through an example, based on
 @code{samples/main-callback.cc}.
 
-@node Using the Callback API with static functions
 @subsection Using the Callback API with static functions
 
 Consider a function:
@@ -205,7 +204,6 @@
 same result as if @code{CbOne()} had been called directly.
 
 
-@node Using the Callback API with member functions
 @subsection Using the Callback API with member functions
 
 Generally, you will not be calling static functions but instead
@@ -267,7 +265,6 @@
 }
 @end verbatim
 
-@node Building Null Callbacks
 @subsection Building Null Callbacks
 
 It is possible for callbacks to be null; hence it may be wise to
--- a/doc/manual/csma.texi	Wed Apr 29 18:59:48 2009 +0400
+++ b/doc/manual/csma.texi	Wed Apr 29 18:26:25 2009 +0400
@@ -5,13 +5,13 @@
 Csma model doxygen.
 
 @menu
-* Overview of the model::
+* Overview of the CSMA model::
 * Using the CsmaNetDevice::
 * CSMA Tracing::
 @end menu
 
-@node Overview of the model
-@section Overview of the model
+@node Overview of the CSMA model
+@section Overview of the CSMA model
 
 The ns-3 CSMA device models a simple bus network in the spirit of Ethernet.
 Although it does not model any real physical network you could ever build 
@@ -254,7 +254,7 @@
   NetDeviceContainer csmaDevices = csma.Install (csmaNodes);
 @end verbatim
 
-@node Csma Tracing
+@node CSMA Tracing
 @section CSMA Tracing
 
 Like all ns-3 devices, the CSMA Model provides a number of trace sources.
--- a/doc/manual/emulation.texi	Wed Apr 29 18:59:48 2009 +0400
+++ b/doc/manual/emulation.texi	Wed Apr 29 18:26:25 2009 +0400
@@ -4,7 +4,7 @@
 
 ns-3 has been designed for integration into testbed and virtual machine
 environments.  We have addressed this need by providing two kinds of 
-net devices.  The first kind, which we call an @code{Emu} @code {NetDevice}
+net devices.  The first kind, which we call an @code{Emu} @code{NetDevice}
 allows ns-3 simulations to send data on a ``real'' network.  The second kind,
 called a @code{Tap} @code{NetDevice} allows a ``real'' host to participate 
 in an ns-3 simulation as if it were one of the simulated nodes.  An ns-3 
--- a/doc/manual/manual.texi	Wed Apr 29 18:59:48 2009 +0400
+++ b/doc/manual/manual.texi	Wed Apr 29 18:26:25 2009 +0400
@@ -64,11 +64,13 @@
 @end titlepage
 
 @c So the toc is printed at the start.
+@ifnottex
 @anchor{Full Table of Contents}
-@contents
+@end ifnottex
+@shortcontents
 
 @ifnottex
-@node Top, Overview, Full Table of Contents 
+@node Top
 @top ns-3 Manual (html version)
 
 For a pdf version of this manual, 
--- a/doc/manual/new-models.texi	Wed Apr 29 18:59:48 2009 +0400
+++ b/doc/manual/new-models.texi	Wed Apr 29 18:26:25 2009 +0400
@@ -1,6 +1,14 @@
 @node Creating a new ns-3 model
 @chapter Creating a new ns-3 model 
 
+@menu
+* Design-approach::
+* Scaffolding::
+* Initial Implementation::
+* Adding-a-sample-script::
+* Build-core-functions-and-unit-tests::
+@end menu
+
 This chapter walks through the design process of an @command{ns-3} model.
 In many research cases, users will not be satisfied to merely adapt
 existing models, but may want to extend the core of the simulator in
@@ -399,7 +407,7 @@
 
 
 @subsection Object Framework
-
+@verbatim
   static const ClassId cid;
 
 
--- a/doc/manual/objects.texi	Wed Apr 29 18:59:48 2009 +0400
+++ b/doc/manual/objects.texi	Wed Apr 29 18:26:25 2009 +0400
@@ -5,6 +5,14 @@
 @node Object model
 @chapter Object model
 
+@menu
+* Object model::
+* Object-oriented behavior::
+* Object base classes::
+* Memory management and class Ptr::
+* Downcasting::
+@end menu
+
 @command{ns-3} is fundamentally a C++ object system.  Objects can
 be declared and instantiated as usual, per C++ rules.  ns-3 also
 adds some features to traditional C++ objects, as described below,
@@ -129,7 +137,6 @@
 functions and their goal is just is save you a small
 bit of typing.
 
-@node CreateObject and Create
 @subsection CreateObject and Create
 
 Objects in C++ may be statically, dynamically, or automatically created.
@@ -155,7 +162,6 @@
 This is simply a wrapper around operator new that correctly handles
 the reference counting system.
 
-@node Aggregation
 @subsection Aggregation
 
 The ns-3 object aggregation system is motivated in strong part by 
--- a/doc/manual/point-to-point.texi	Wed Apr 29 18:59:48 2009 +0400
+++ b/doc/manual/point-to-point.texi	Wed Apr 29 18:26:25 2009 +0400
@@ -5,13 +5,13 @@
 PointToPoint model doxygen.
 
 @menu
-* Overview of the model::
+* Overview of the PointToPoint model::
 * Using the PointToPointNetDevice::
 * PointToPoint Tracing::
 @end menu
 
-@node Overview of the model
-@section Overview of the model
+@node Overview of the PointToPoint model
+@section Overview of the PointToPoint model
 
 The ns-3 point-to-point model is of a very simple point to point data link
 connecting exactly two PointToPointNetDevice devices over an
--- a/doc/manual/random.texi	Wed Apr 29 18:59:48 2009 +0400
+++ b/doc/manual/random.texi	Wed Apr 29 18:26:25 2009 +0400
@@ -2,6 +2,20 @@
 @node Random variables
 @chapter Random variables
 
+@menu
+* Quick Overview::
+* Background::
+* Seeding and independent replications::
+* class RandomVariable::
+* Base class public API::
+* Types of RandomVariables::
+* Semantics of RandomVariable objects::
+* Using other PRNG::
+* More advanced usage::
+* Publishing your results::
+* Summary::
+@end menu
+
 ns-3 contains a built-in pseudo-random number generator (PRNG).
 It is important for serious users of the simulator to understand
 the functionality, configuration, and usage of this PRNG, and
--- a/doc/manual/realtime.texi	Wed Apr 29 18:59:48 2009 +0400
+++ b/doc/manual/realtime.texi	Wed Apr 29 18:26:25 2009 +0400
@@ -77,8 +77,8 @@
 
 The implementation is contained in the following files:
 @itemize @bullet
-@item @code{src/simulator/realtime-simulator-impl.{cc,h}}
-@item @code{src/simulator/wall-clock-synchronizer.{cc,h}}
+@item @code{src/simulator/realtime-simulator-impl.@{cc,h@}}
+@item @code{src/simulator/wall-clock-synchronizer.@{cc,h@}}
 @end itemize
 
 In order to create a realtime scheduler, to a first approximation you 
--- a/doc/manual/routing.texi	Wed Apr 29 18:59:48 2009 +0400
+++ b/doc/manual/routing.texi	Wed Apr 29 18:26:25 2009 +0400
@@ -1,6 +1,19 @@
 @node Routing overview
 @chapter Routing overview
 
+@menu
+* Routing-Overview::
+* Support for multiple routing protocols::
+* Roadmap and Future work::
+* Static routing::
+* Unicast routing::
+* Multicast routing::
+* Global centralized routing::
+* Global Unicast Routing API::
+* Global Routing Implementation::
+* Optimized Link State Routing (OLSR)::
+@end menu
+
 This chapter describes the overall design of routing in the 
 @code{src/internet-stack}
 module, and some details about the routing approachs currently
--- a/doc/manual/tcp.texi	Wed Apr 29 18:59:48 2009 +0400
+++ b/doc/manual/tcp.texi	Wed Apr 29 18:26:25 2009 +0400
@@ -13,7 +13,7 @@
 
 There are two important abstract base classes:
 @itemize @bullet
-@item @code{class TcpSocket}:  This is defined in @code{src/node/tcp-socket.{cc,h}}.  This class exists for hosting TcpSocket attributes that can be
+@item @code{class TcpSocket}:  This is defined in @code{src/node/tcp-socket.@{cc,h@}}.  This class exists for hosting TcpSocket attributes that can be
 reused across different implementations.  For instance, 
 @code{TcpSocket::SetInitialCwnd()} can be used for any of the implementations
 that derive from @code{class TcpSocket}.
--- a/doc/manual/troubleshoot.texi	Wed Apr 29 18:59:48 2009 +0400
+++ b/doc/manual/troubleshoot.texi	Wed Apr 29 18:26:25 2009 +0400
@@ -4,6 +4,11 @@
 This chapter posts some information about possibly common errors in building
 or running ns-3 programs.
 
+@menu
+* Build errors::
+* Run-time errors::
+@end menu
+
 Please note that the wiki (@uref{http://www.nsnam.org/wiki/index.php/Troubleshooting}) may have contributed items.
 
 @node Build errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/emu-ping.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,217 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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
+ */
+
+// Allow ns-3 to ping a real host somewhere, using emulation mode
+//
+//   ------------
+//   |  node n0 |
+//   |          |
+//   |  ---     |
+//   | |   |    |
+//   | |emu|    |
+//   | |   |    |
+//   |  ---     |
+//   |   |      |
+//   ----|-------
+//       |
+//     (device on host system, set to promiscuous mode)
+//       |
+//      --------- (Internet) -------
+//
+// To use this example:
+//  1) You need to decide on a physical device on your real system, and either
+//     overwrite the hard-configured device name below (eth0) or pass this 
+//     device name in as a command-line argument
+//  2) The host device must be set to promiscuous mode 
+//     (e.g. "sudo ifconfig eth0 promisc")
+//  3) Be aware that ns-3 will generate a fake mac address, and that in
+//     some enterprise networks, this may be considered bad form to be
+//     sending packets out of your device with "unauthorized" mac addresses
+//  4) You will need to assign an IP address to the ns-3 simulation node that
+//     is consistent with the subnet that is active on the host device's link.
+//     That is, you will have to assign an IP address to the ns-3 node as if
+//     it were on your real subnet.  Search for "Ipv4Address localIp" and 
+//     replace the string "1.2.3.4" with a valid IP address.
+//  5) You will need to configure a default route in the ns-3 node to tell it
+//     how to get off of your subnet. One thing you could do is a 
+//     'netstat -rn' command and find the IP address of the default gateway
+//     on your host.  Search for "Ipv4Address gateway" and replace the string
+//     "1.2.3.4" string with the gateway IP address.
+
+#include "ns3/abort.h"
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/internet-stack-module.h"
+#include "ns3/emu-module.h"
+#include "ns3/v4ping-module.h"
+#include "ns3/helper-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("PingEmulationExample");
+
+static void 
+PingRtt (std::string context, Time rtt)
+{
+  NS_LOG_UNCOND ("Received Response with RTT = " << rtt);
+}
+
+int 
+main (int argc, char *argv[])
+{
+  NS_LOG_INFO ("Ping Emulation Example");
+
+  std::string deviceName ("eth0");
+  std::string remote ("208.77.188.166"); // example.com
+
+  //
+  // Allow the user to override any of the defaults at run-time, via 
+  // command-line arguments
+  //
+  CommandLine cmd;
+  cmd.AddValue("deviceName", "Device name", deviceName);
+  cmd.AddValue("remote", "Remote IP address (dotted decimal only please)", remote);
+  cmd.Parse (argc, argv);
+
+  Ipv4Address remoteIp (remote.c_str ());
+  Ipv4Address localIp ("1.2.3.4");
+  NS_ABORT_MSG_IF (localIp == "1.2.3.4", "You must change the local IP address before running this example");
+
+  Ipv4Mask localMask ("255.255.255.0");
+
+  //
+  // Since we are using a real piece of hardware we need to use the realtime
+  // simulator.
+  //
+  GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
+
+  //
+  // Since we are going to be talking to real-world machines, we need to enable
+  // calculation of checksums in our protocols.
+  //
+  Config::SetDefault ("ns3::Ipv4L3Protocol::CalcChecksum", BooleanValue (true)); 
+  Config::SetDefault ("ns3::Icmpv4L4Protocol::CalcChecksum", BooleanValue (true)); 
+  Config::SetDefault ("ns3::TcpL4Protocol::CalcChecksum", BooleanValue (true)); 
+  Config::SetDefault ("ns3::UdpL4Protocol::CalcChecksum", BooleanValue (true)); 
+
+  //
+  // In such a simple topology, the use of the helper API can be a hindrance
+  // so we drop down into the low level API and do it manually.
+  //
+  // First we need a single node.
+  //
+  NS_LOG_INFO ("Create Node");
+  Ptr<Node> node = CreateObject<Node> ();
+
+  //
+  // Create an emu device, allocate a MAC address and point the device to the 
+  // Linux device name.  The device needs a transmit queueing discipline so
+  // create a droptail queue and give it to the device.  Finally, "install" 
+  // the device into the node.
+  //
+  // Do understand that the ns-3 allocated MAC address will be sent out over 
+  // your network since the emu net device will spoof it.  By default, this 
+  // address will have an Organizationally Unique Identifier (OUI) of zero.
+  // The Internet Assigned Number Authority IANA
+  // 
+  //  http://www.iana.org/assignments/ethernet-numbers
+  //
+  // reports that this OUI is unassigned, and so should not conflict with
+  // real hardware on your net.  It may raise all kinds of red flags in a
+  // real environment to have packets from a device with an obviously bogus
+  // OUI flying around.  Be aware.
+  // 
+  NS_LOG_INFO ("Create Device");
+  Ptr<EmuNetDevice> device = CreateObject<EmuNetDevice> ();
+  device->SetAttribute ("Address", Mac48AddressValue (Mac48Address::Allocate ()));
+  device->SetAttribute ("DeviceName", StringValue (deviceName));
+
+  Ptr<Queue> queue = CreateObject<DropTailQueue> ();
+  device->SetQueue (queue);
+  node->AddDevice (device);
+
+  //
+  // Add a default internet stack to the node.  This gets us the ns-3 versions
+  // of ARP, IPv4, ICMP, UDP and TCP.
+  //
+  NS_LOG_INFO ("Add Internet Stack");
+  AddInternetStack (node);
+
+  NS_LOG_INFO ("Create IPv4 Interface");
+  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+  uint32_t interface = ipv4->AddInterface (device);
+  Ipv4InterfaceAddress address = Ipv4InterfaceAddress (localIp, localMask);
+  ipv4->AddAddress (interface, address);
+  ipv4->SetMetric (interface, 1);
+  ipv4->SetUp (interface);
+
+  //
+  // When the ping appliation sends its ICMP packet, it will happily send it
+  // down the ns-3 protocol stack.  We set the IP address of the destination
+  // to the address corresponding to example.com above.  This address is off 
+  // our local network so we have got to provide some kind of default route 
+  // to ns-3 to be able to get that ICMP packet forwarded off of our network.
+  //
+  // You have got to provide an IP address of a real host that you can send
+  // real packets to and have them forwarded off of your local network.  One
+  // thing you could do is a 'netstat -rn' command and find the IP address of
+  // the default gateway on your host and add it below, replacing the 
+  // "1.2.3.4" string.
+  //
+  Ipv4Address gateway ("1.2.3.4");
+  NS_ABORT_MSG_IF (gateway == "1.2.3.4", "You must change the gateway IP address before running this example");
+
+  ipv4->SetDefaultRoute (gateway, interface);
+
+  //
+  // Create the ping application.  This application knows how to send
+  // ICMP echo requests.  Setting up the packet sink manually is a bit
+  // of a hassle and since there is no law that says we cannot mix the
+  // helper API with the low level API, let's just use the helper.
+  //
+  NS_LOG_INFO ("Create V4Ping Appliation");
+  Ptr<V4Ping> app = CreateObject<V4Ping> ();
+  app->SetAttribute ("Remote", Ipv4AddressValue (remoteIp));
+  node->AddApplication (app);
+  app->Start (Seconds (1.0));
+  app->Stop (Seconds (5.0));
+
+  //
+  // Give the application a name.  This makes life much easier when constructing
+  // config paths.
+  //
+  Names::Add ("app", app);
+
+  //
+  // Hook a trace to print something when the response comes back.
+  //
+  Config::Connect ("/Names/app/Rtt", MakeCallback (&PingRtt));
+
+  //
+  // Enable a promiscuous pcap trace to see what is coming and going on our device.
+  //
+  EmuHelper::EnablePcap ("emu-ping", device, true);
+
+  //
+  // Now, do the actual emulation.
+  //
+  NS_LOG_INFO ("Run Emulation.");
+  Simulator::Stop (Seconds (5.0));
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+}
--- a/examples/mesh.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/examples/mesh.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -44,7 +44,7 @@
   double    step            = 100.0;
   double    randomStart     = 0.1;
   double    totalTime       = 100.0;
-  double    packetInterval  = 0.001;
+  double    packetInterval  = 0.1;
   uint16_t  packetSize      = 1024;
   uint32_t  nIfaces         = 1;
   bool      chan            = true;
--- a/examples/mixed-wireless.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/examples/mixed-wireless.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -144,13 +144,14 @@
   // our container
   //
   WifiHelper wifi;
-  wifi.SetMac ("ns3::AdhocWifiMac");
+  NqosWifiMacHelper mac = NqosWifiMacHelper::Default ();
+  mac.SetType ("ns3::AdhocWifiMac");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-54mbs"));
   YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
   YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
   wifiPhy.SetChannel (wifiChannel.Create ());
-  NetDeviceContainer backboneDevices = wifi.Install (wifiPhy, backbone);
+  NetDeviceContainer backboneDevices = wifi.Install (wifiPhy, mac, backbone);
   //
   // Add the IPv4 protocol stack to the nodes in our container
   //
@@ -258,6 +259,7 @@
       // Create an infrastructure network
       //
       WifiHelper wifiInfra = WifiHelper::Default ();
+      NqosWifiMacHelper macInfra = NqosWifiMacHelper::Default ();
       wifiPhy.SetChannel (wifiChannel.Create ());
       // Create unique ssids for these networks
       std::string ssidString("wifi-infra");
@@ -267,15 +269,15 @@
       Ssid ssid = Ssid (ssidString);
       wifiInfra.SetRemoteStationManager ("ns3::ArfWifiManager");
       // setup stas
-      wifiInfra.SetMac ("ns3::NqstaWifiMac",
+      macInfra.SetType ("ns3::NqstaWifiMac",
                "Ssid", SsidValue (ssid),
                "ActiveProbing", BooleanValue (false));
-      NetDeviceContainer staDevices = wifiInfra.Install (wifiPhy, stas);
+      NetDeviceContainer staDevices = wifiInfra.Install (wifiPhy, macInfra, stas);
       // setup ap.
-      wifiInfra.SetMac ("ns3::NqapWifiMac", "Ssid", SsidValue (ssid),
+      macInfra.SetType ("ns3::NqapWifiMac", "Ssid", SsidValue (ssid),
                "BeaconGeneration", BooleanValue (true),
                "BeaconInterval", TimeValue (Seconds (2.5)));
-      NetDeviceContainer apDevices = wifiInfra.Install (wifiPhy, backbone.Get (i));
+      NetDeviceContainer apDevices = wifiInfra.Install (wifiPhy, macInfra, backbone.Get (i));
       // Collect all of these new devices
       NetDeviceContainer infraDevices (apDevices, staDevices);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/simple-wifi-frame-aggregation.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,151 @@
+/* -*-  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/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/global-routing-module.h"
+#include "ns3/wifi-module.h"
+#include "ns3/mobility-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 ("SimpleWifiFrameAggregation");
+
+int main (int argc, char *argv[])
+{
+  //LogComponentEnable ("EdcaTxopN", LOG_LEVEL_DEBUG);
+  LogComponentEnable ("MsduAggregator", LOG_LEVEL_INFO);
+  LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
+  LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
+  
+  uint32_t nWifi = 1;
+  CommandLine cmd;
+  cmd.AddValue ("nWifi", "Number of wifi STA devices", nWifi);
+  cmd.Parse (argc,argv);
+
+  NodeContainer wifiNodes;
+  wifiNodes.Create (2);
+  NodeContainer wifiApNode;
+  wifiApNode.Create (1);
+ 
+  YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
+  YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
+  phy.SetChannel (channel.Create ());
+
+  WifiHelper wifi = WifiHelper::Default ();
+  QosWifiMacHelper mac = QosWifiMacHelper::Default ();
+  wifi.SetRemoteStationManager ("ns3::AarfWifiManager", "FragmentationThreshold", UintegerValue (2500));
+
+  Ssid ssid = Ssid ("ns-3-802.11n");
+  mac.SetType ("ns3::QstaWifiMac", 
+    "Ssid", SsidValue (ssid),
+    "ActiveProbing", BooleanValue (false));
+  mac.SetMsduAggregatorForAc (AC_BE, "ns3::MsduStandardAggregator", 
+                                     "MaxAmsduSize", UintegerValue (3839));
+  
+  NetDeviceContainer staDevices;
+  staDevices = wifi.Install (phy, mac, wifiNodes);
+  
+  mac.SetType ("ns3::QapWifiMac", 
+    "Ssid", SsidValue (ssid),
+    "BeaconGeneration", BooleanValue (true),
+    "BeaconInterval", TimeValue (Seconds (2.5)));
+  mac.SetMsduAggregatorForAc (AC_BE, "ns3::MsduStandardAggregator", 
+                                     "MaxAmsduSize", UintegerValue (7935));
+
+  NetDeviceContainer apDevice;
+  apDevice = wifi.Install (phy, mac, wifiApNode);
+ 
+  /* Setting mobility model */
+  MobilityHelper mobility;
+
+  mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
+    "MinX", DoubleValue (0.0),
+    "MinY", DoubleValue (0.0),
+    "DeltaX", DoubleValue (5.0),
+    "DeltaY", DoubleValue (10.0),
+    "GridWidth", UintegerValue (3),
+    "LayoutType", StringValue ("RowFirst"));
+
+  mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel",
+    "Bounds", RectangleValue (Rectangle (-50, 50, -50, 50)));
+  mobility.Install (wifiNodes);
+
+  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+  mobility.Install (wifiApNode);
+  
+  /* Internet stack*/
+  InternetStackHelper stack;
+  stack.Install (wifiApNode);
+  stack.Install (wifiNodes);
+
+  Ipv4AddressHelper address;
+
+  address.SetBase ("192.168.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer wifiNodesInterfaces;
+  Ipv4InterfaceContainer apNodeInterface;
+  
+  wifiNodesInterfaces = address.Assign (staDevices);
+  apNodeInterface = address.Assign (apDevice);
+  
+  /* Setting applications */
+  UdpEchoServerHelper echoServer (9);
+
+  ApplicationContainer serverApps = echoServer.Install (wifiNodes.Get (1));
+  serverApps.Start (Seconds (1.0));
+  serverApps.Stop (Seconds (10.0));
+
+  UdpEchoClientHelper echoClient (wifiNodesInterfaces.GetAddress (1), 9);
+  echoClient.SetAttribute ("MaxPackets", UintegerValue (3));
+  echoClient.SetAttribute ("Interval", TimeValue (Seconds (0.000001)));
+  echoClient.SetAttribute ("PacketSize", UintegerValue (1500));
+
+  ApplicationContainer clientApps = 
+    echoClient.Install (wifiNodes.Get (0));
+  clientApps.Start (Seconds (2.0));
+  clientApps.Stop (Seconds (10.0));
+
+  GlobalRouteManager::PopulateRoutingTables ();
+
+  Simulator::Stop (Seconds (10.0));
+  
+  YansWifiPhyHelper::EnablePcap ("test-802.11n", 
+    wifiNodes.Get (nWifi - 1)->GetId (), 0);
+
+  Simulator::Run ();
+  Simulator::Destroy ();
+  
+  return 0;
+}
--- a/examples/stats/wifi-example-sim.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/examples/stats/wifi-example-sim.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -128,11 +128,12 @@
 
   NS_LOG_INFO("Installing WiFi and Internet stack.");
   WifiHelper wifi = WifiHelper::Default ();
-  wifi.SetMac("ns3::AdhocWifiMac");
+  NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
+  wifiMac.SetType ("ns3::AdhocWifiMac");
   YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
   YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
   wifiPhy.SetChannel (wifiChannel.Create ());
-  NetDeviceContainer nodeDevices = wifi.Install(wifiPhy, nodes);
+  NetDeviceContainer nodeDevices = wifi.Install(wifiPhy, wifiMac, nodes);
 
   InternetStackHelper internet;
   internet.Install(nodes);
--- a/examples/tap-wifi-dumbbell.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/examples/tap-wifi-dumbbell.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -151,19 +151,20 @@
 
   Ssid ssid = Ssid ("left");
   WifiHelper wifi = WifiHelper::Default ();
+  NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
   wifi.SetRemoteStationManager ("ns3::ArfWifiManager");
 
-  wifi.SetMac ("ns3::NqapWifiMac", 
-               "Ssid", SsidValue (ssid), 
-               "BeaconGeneration", BooleanValue (true), 
-               "BeaconInterval", TimeValue (Seconds (2.5)));
-  NetDeviceContainer devicesLeft = wifi.Install (wifiPhy, nodesLeft.Get (0));
+  wifiMac.SetType ("ns3::NqapWifiMac", 
+                   "Ssid", SsidValue (ssid), 
+                   "BeaconGeneration", BooleanValue (true), 
+                   "BeaconInterval", TimeValue (Seconds (2.5)));
+  NetDeviceContainer devicesLeft = wifi.Install (wifiPhy, wifiMac, nodesLeft.Get (0));
 
 
-  wifi.SetMac ("ns3::NqstaWifiMac", 
-               "Ssid", SsidValue (ssid), 
-               "ActiveProbing", BooleanValue (false));
-  devicesLeft.Add (wifi.Install (wifiPhy, NodeContainer (nodesLeft.Get (1), nodesLeft.Get (2), nodesLeft.Get (3))));
+  wifiMac.SetType ("ns3::NqstaWifiMac", 
+                   "Ssid", SsidValue (ssid), 
+                   "ActiveProbing", BooleanValue (false));
+  devicesLeft.Add (wifi.Install (wifiPhy, wifiMac, NodeContainer (nodesLeft.Get (1), nodesLeft.Get (2), nodesLeft.Get (3))));
 
   MobilityHelper mobility;
   mobility.Install (nodesLeft);
--- a/examples/third.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/examples/third.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -89,21 +89,23 @@
   WifiHelper wifi = WifiHelper::Default ();
   wifi.SetRemoteStationManager ("ns3::AarfWifiManager");
 
+  NqosWifiMacHelper mac = NqosWifiMacHelper::Default ();
+  
   Ssid ssid = Ssid ("ns-3-ssid");
-  wifi.SetMac ("ns3::NqstaWifiMac", 
+  mac.SetType ("ns3::NqstaWifiMac", 
     "Ssid", SsidValue (ssid),
     "ActiveProbing", BooleanValue (false));
 
   NetDeviceContainer staDevices;
-  staDevices = wifi.Install (phy, wifiStaNodes);
+  staDevices = wifi.Install (phy, mac, wifiStaNodes);
 
-  wifi.SetMac ("ns3::NqapWifiMac", 
+  mac.SetType ("ns3::NqapWifiMac", 
     "Ssid", SsidValue (ssid),
     "BeaconGeneration", BooleanValue (true),
     "BeaconInterval", TimeValue (Seconds (2.5)));
 
   NetDeviceContainer apDevices;
-  apDevices = wifi.Install (phy, wifiApNode);
+  apDevices = wifi.Install (phy, mac, wifiApNode);
 
   MobilityHelper mobility;
 
--- a/examples/wifi-adhoc.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/examples/wifi-adhoc.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -36,7 +36,8 @@
 public:
   Experiment ();
   Experiment (std::string name);
-  Gnuplot2dDataset Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy, const YansWifiChannelHelper &wifiChannel);
+  Gnuplot2dDataset Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy,
+                        const NqosWifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel);
 private:
   void ReceivePacket (Ptr<Socket> socket);
   void SetPosition (Ptr<Node> node, Vector position);
@@ -109,7 +110,8 @@
 }
 
 Gnuplot2dDataset
-Experiment::Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy, const YansWifiChannelHelper &wifiChannel)
+Experiment::Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy,
+                 const NqosWifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel)
 {
   m_bytesTotal = 0;
 
@@ -121,7 +123,9 @@
 
   YansWifiPhyHelper phy = wifiPhy;
   phy.SetChannel (wifiChannel.Create ());
-  NetDeviceContainer devices = wifi.Install (phy, c);
+
+  NqosWifiMacHelper mac = wifiMac;
+  NetDeviceContainer devices = wifi.Install (phy, mac, c);
 
   MobilityHelper mobility;
   Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
@@ -170,66 +174,67 @@
 
   Experiment experiment;
   WifiHelper wifi = WifiHelper::Default ();
+  NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
   YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
   YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
   Gnuplot2dDataset dataset;
 
-  wifi.SetMac ("ns3::AdhocWifiMac");
+  wifiMac.SetType ("ns3::AdhocWifiMac");
 
   NS_LOG_DEBUG ("54");
   experiment = Experiment ("54mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-54mbs"));
-  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+  dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("48");
   experiment = Experiment ("48mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-48mbs"));
-  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+  dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("36");
   experiment = Experiment ("36mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-36mbs"));
-  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+  dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("24");
   experiment = Experiment ("24mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-24mbs"));
-  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+  dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("18");
   experiment = Experiment ("18mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-18mbs"));
-  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+  dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("12");
   experiment = Experiment ("12mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-12mbs"));
-  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+  dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("9");
   experiment = Experiment ("9mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-9mbs"));
-  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+  dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("6");
   experiment = Experiment ("6mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-6mbs"));
-  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+  dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   gnuplot.GenerateOutput (std::cout);
@@ -242,37 +247,37 @@
   NS_LOG_DEBUG ("arf");
   experiment = Experiment ("arf");
   wifi.SetRemoteStationManager ("ns3::ArfWifiManager");
-  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+  dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("aarf");
   experiment = Experiment ("aarf");
   wifi.SetRemoteStationManager ("ns3::AarfWifiManager");
-  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+  dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("aarf-cd");
   experiment = Experiment ("aarf-cd");
   wifi.SetRemoteStationManager ("ns3::AarfcdWifiManager");
-  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+  dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("cara");
   experiment = Experiment ("cara");
   wifi.SetRemoteStationManager ("ns3::CaraWifiManager");
-  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+  dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("rraa");
   experiment = Experiment ("rraa");
   wifi.SetRemoteStationManager ("ns3::RraaWifiManager");
-  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+  dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("ideal");
   experiment = Experiment ("ideal");
   wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
-  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+  dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   gnuplot.GenerateOutput (std::cout);
--- a/examples/wifi-ap.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/examples/wifi-ap.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -131,21 +131,22 @@
   packetSocket.Install (stas);
   packetSocket.Install (ap);
 
+  NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
   YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
   YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
   wifiPhy.SetChannel (wifiChannel.Create ());
   Ssid ssid = Ssid ("wifi-default");
   wifi.SetRemoteStationManager ("ns3::ArfWifiManager");
   // setup stas.
-  wifi.SetMac ("ns3::NqstaWifiMac", 
+  wifiMac.SetType ("ns3::NqstaWifiMac", 
                "Ssid", SsidValue (ssid),
                "ActiveProbing", BooleanValue (false));
-  staDevs = wifi.Install (wifiPhy, stas);
+  staDevs = wifi.Install (wifiPhy, wifiMac, stas);
   // setup ap.
-  wifi.SetMac ("ns3::NqapWifiMac", "Ssid", SsidValue (ssid),
+  wifiMac.SetType ("ns3::NqapWifiMac", "Ssid", SsidValue (ssid),
                "BeaconGeneration", BooleanValue (true),
                "BeaconInterval", TimeValue (Seconds (2.5)));
-  wifi.Install (wifiPhy, ap);
+  wifi.Install (wifiPhy, wifiMac, ap);
 
   // mobility.
   mobility.Install (stas);
--- a/examples/wifi-wired-bridging.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/examples/wifi-wired-bridging.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -104,6 +104,7 @@
       MobilityHelper mobility;
       BridgeHelper bridge;
       WifiHelper wifi = WifiHelper::Default ();
+      NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
       YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
       YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
       wifiPhy.SetChannel (wifiChannel.Create ());
@@ -121,11 +122,11 @@
       // setup the AP.
       mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
       mobility.Install (backboneNodes.Get (i));
-      wifi.SetMac ("ns3::NqapWifiMac",
+      wifiMac.SetType ("ns3::NqapWifiMac",
 		   "Ssid", SsidValue (ssid),
 		   "BeaconGeneration", BooleanValue (true),
 		   "BeaconInterval", TimeValue (Seconds (2.5)));
-      apDev = wifi.Install (wifiPhy, backboneNodes.Get (i));
+      apDev = wifi.Install (wifiPhy, wifiMac, backboneNodes.Get (i));
 
       NetDeviceContainer bridgeDev;
       bridgeDev = bridge.Install (backboneNodes.Get (i), NetDeviceContainer (apDev, backboneDevices.Get (i)));
@@ -141,10 +142,10 @@
 				 "Speed", StringValue ("Constant:1.0"),
 				 "Bounds", RectangleValue (Rectangle (wifiX, wifiX+5.0,0.0, (nStas+1)*5.0)));
       mobility.Install (sta);
-      wifi.SetMac ("ns3::NqstaWifiMac",
+      wifiMac.SetType ("ns3::NqstaWifiMac",
 		   "Ssid", SsidValue (ssid),
 		   "ActiveProbing", BooleanValue (false));
-      staDev = wifi.Install (wifiPhy, sta);
+      staDev = wifi.Install (wifiPhy, wifiMac, sta);
       staInterface = ip.Assign (staDev);
 
       // save everything in containers.
--- a/examples/wscript	Wed Apr 29 18:59:48 2009 +0400
+++ b/examples/wscript	Wed Apr 29 18:26:25 2009 +0400
@@ -145,11 +145,17 @@
 
     env = bld.env_of_name('default')
     if env['ENABLE_EMU']:
-        obj = bld.create_ns3_program('emu-udp-echo',
-                                     ['emu', 'internet-stack'])
+        obj = bld.create_ns3_program('emu-udp-echo', ['emu', 'internet-stack'])
         obj.source = 'emu-udp-echo.cc'
 
+        obj = bld.create_ns3_program('emu-ping', ['emu', 'internet-stack'])
+        obj.source = 'emu-ping.cc'
+
     if env['ENABLE_TAP']:
         obj = bld.create_ns3_program('tap-wifi-dumbbell',
                                      ['wifi', 'csma', 'point-to-point', 'tap-bridge', 'internet-stack'])
         obj.source = 'tap-wifi-dumbbell.cc'
+
+    obj = bld.create_ns3_program('simple-wifi-frame-aggregation',
+                                 ['core', 'simulator', 'mobility', 'wifi'])
+    obj.source = 'simple-wifi-frame-aggregation.cc'
--- a/src/applications/udp-echo/udp-echo-client.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/applications/udp-echo/udp-echo-client.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -76,6 +76,7 @@
 UdpEchoClient::~UdpEchoClient()
 {
   NS_LOG_FUNCTION_NOARGS ();
+  m_socket = 0;
 }
 
 void 
@@ -117,6 +118,7 @@
 
   if (m_socket != 0) 
     {
+      m_socket->Close ();
       m_socket->SetRecvCallback(MakeNullCallback<void, Ptr<Socket> > ());
     }
 
--- a/src/applications/udp-echo/udp-echo-server.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/applications/udp-echo/udp-echo-server.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -55,6 +55,7 @@
 UdpEchoServer::~UdpEchoServer()
 {
   NS_LOG_FUNCTION_NOARGS ();
+  m_socket = 0;
 }
 
 void
@@ -87,6 +88,7 @@
 
   if (m_socket != 0) 
     {
+      m_socket->Close ();
       m_socket->SetRecvCallback(MakeNullCallback<void, Ptr<Socket> > ());
     }
 }
--- a/src/devices/csma/csma-net-device.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/csma/csma-net-device.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -722,20 +722,6 @@
   NS_LOG_FUNCTION (packet << senderDevice);
   NS_LOG_LOGIC ("UID is " << packet->GetUid ());
 
-  /* IPv6 support*/
-  uint8_t mac[6];
-  Mac48Address multicast6AllNodes("33:33:00:00:00:01");
-  Mac48Address multicast6AllRouters("33:33:00:00:00:02");
-  Mac48Address multicast6AllHosts("33:33:00:00:00:03");
-  Mac48Address multicast6Node; /* multicast address addressed to our MAC address */
-
-  /* generate IPv6 multicast ethernet destination that nodes will accept */
-  GetAddress().CopyTo(mac);
-  mac[0]=0x33;
-  mac[1]=0x33;
-  /* mac[2]=0xff; */
-  multicast6Node.CopyFrom(mac);
-
   //
   // We never forward up packets that we sent.  Real devices don't do this since
   // their receivers are disabled during send, so we don't.
@@ -805,16 +791,12 @@
       // Classify the packet based on its destination.
       //
       PacketType packetType;
-      
+
       if (header.GetDestination ().IsBroadcast ())
         {
           packetType = PACKET_BROADCAST;
         }
-      else if (header.GetDestination ().IsMulticast () ||
-          header.GetDestination() == multicast6Node ||
-          header.GetDestination() == multicast6AllNodes ||
-          header.GetDestination() == multicast6AllRouters ||
-          header.GetDestination() == multicast6AllHosts)
+      else if (header.GetDestination ().IsGroup ())
         {
           packetType = PACKET_MULTICAST;          
         }
--- a/src/devices/emu/emu-net-device.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/emu/emu-net-device.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -385,7 +385,10 @@
       //
       // Execute the socket creation process image.
       //
-      status = ::execl (FindCreator ().c_str (), "emu-sock-creator", oss.str ().c_str (), (char *)NULL);
+      status = ::execl (FindCreator ("emu-sock-creator").c_str (), 
+                        "emu-sock-creator",                             // argv[0] (filename)
+                        oss.str ().c_str (),                            // argv[1] (-p<path?
+                        (char *)NULL);
 
       //
       // If the execl successfully completes, it never returns.  If it returns it failed or the OS is
@@ -520,20 +523,41 @@
 }
 
 std::string
-EmuNetDevice::FindCreator (void)
+EmuNetDevice::FindCreator (std::string creatorName)
 {
-  struct stat st;
-  std::string debug = "./build/debug/src/devices/emu/emu-sock-creator";
-  std::string optimized = "./build/optimized/src/devices/emu/emu-sock-creator";
+  NS_LOG_FUNCTION (creatorName);
+
+  std::list<std::string> locations;
+
+  // The path to the bits if we're sitting there with them
+  locations.push_back ("./");
+  locations.push_back ("./");
+
+  // The path to the bits if we're sitting in the root of the repo
+  locations.push_back ("./build/optimized/src/devices/emu/");
+  locations.push_back ("./build/debug/src/devices/emu/");
+
+  // if at the level of src (or build)
+  locations.push_back ("../build/optimized/src/devices/emu/");
+  locations.push_back ("../build/debug/src/devices/emu/");
 
-  if (::stat (debug.c_str (), &st) == 0)
+  // src/devices (or build/debug)
+  locations.push_back ("../../build/optimized/src/devices/emu/");
+  locations.push_back ("../../build/debug/src/devices/emu/");
+
+  // src/devices/emu (or build/debug/examples)
+  locations.push_back ("../../../build/optimized/src/devices/emu/");
+  locations.push_back ("../../../build/debug/src/devices/emu/");
+
+  for (std::list<std::string>::const_iterator i = locations.begin (); i != locations.end (); ++i)
     {
-      return debug;
-    }
+      struct stat st;
 
-  if (::stat (optimized.c_str (), &st) == 0)
-    {
-      return optimized;
+      if (::stat ((*i + creatorName).c_str (), &st) == 0)
+	{
+          NS_LOG_INFO ("Found Creator " << *i + creatorName);                  
+	  return *i + creatorName;
+	}
     }
 
   NS_FATAL_ERROR ("EmuNetDevice::FindCreator(): Couldn't find creator");
@@ -560,19 +584,6 @@
 {
   NS_LOG_FUNCTION (buf << len);
 
-  /* IPv6 support*/
-  uint8_t mac[6];
-  Mac48Address multicast6AllNodes("33:33:00:00:00:01");
-  Mac48Address multicast6AllRouters("33:33:00:00:00:02");
-  Mac48Address multicast6AllHosts("33:33:00:00:00:03");
-  Mac48Address multicast6Node; /* multicast address addressed to our MAC address */
-
-  /* generate IPv6 multicast ethernet destination that nodes will accept */
-  GetAddress().CopyTo(mac);
-  mac[0]=0x33;
-  mac[1]=0x33;
-  multicast6Node.CopyFrom(mac);
-
   //
   // Create a packet out of the buffer we received and free that buffer.
   //
@@ -586,13 +597,6 @@
   //
   Ptr<Packet> originalPacket = packet->Copy ();
 
-  //
-  // Checksum the packet
-  //
-  EthernetTrailer trailer;
-  packet->RemoveTrailer (trailer);
-  trailer.CheckFcs (packet);
-
   EthernetHeader header (false);
   packet->RemoveHeader (header);
 
@@ -619,16 +623,12 @@
     }
 
   PacketType packetType;
-      
+
   if (header.GetDestination ().IsBroadcast ())
     {
       packetType = NS3_PACKET_BROADCAST;
     }
-  else if (header.GetDestination ().IsMulticast () ||
-           header.GetDestination() == multicast6Node ||
-           header.GetDestination() == multicast6AllNodes ||
-           header.GetDestination() == multicast6AllRouters ||
-           header.GetDestination() == multicast6AllHosts)
+  else if (header.GetDestination ().IsGroup ())
     {
       packetType = NS3_PACKET_MULTICAST;          
     }
--- a/src/devices/emu/emu-net-device.h	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/emu/emu-net-device.h	Wed Apr 29 18:26:25 2009 +0400
@@ -196,7 +196,7 @@
   /**
    * Figure out where the raw socket creation process lives on the system.
    */
-  std::string FindCreator (void);
+  std::string FindCreator (std::string creatorName);
 
   /**
    * Get a copy of the attached Queue.
--- a/src/devices/mesh/mesh-point-device.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/mesh/mesh-point-device.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -87,7 +87,7 @@
   NS_LOG_DEBUG ("SRC="<<src48<<", DST = "<<dst48<<", I am: "<<m_address);
   if (!m_promiscRxCallback.IsNull ())
     m_promiscRxCallback (this, packet, protocol, src, dst, packetType);
-  if(dst48.IsBroadcast () || dst48.IsMulticast ())
+  if(dst48.IsBroadcast () || dst48.IsGroup ())
   {
     m_rxCallback (this, packet, protocol, src);
     Forward (incomingPort, packet->Copy (), protocol, src48, dst48);
--- a/src/devices/wifi/adhoc-wifi-mac.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/adhoc-wifi-mac.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -46,7 +46,8 @@
     .AddConstructor<AdhocWifiMac> ()
     .AddAttribute ("DcaTxop", "The DcaTxop object",
                    PointerValue (),
-                   MakePointerAccessor (&AdhocWifiMac::DoGetDcaTxop),
+                   MakePointerAccessor (&AdhocWifiMac::GetDcaTxop,
+                                        &AdhocWifiMac::SetDcaTxop),
                    MakePointerChecker<DcaTxop> ()) 
     ;
   return tid;
@@ -63,10 +64,6 @@
 
   m_dcfManager = new DcfManager ();
   m_dcfManager->SetupLowListener (m_low);
-
-  m_dca = CreateObject<DcaTxop> ();
-  m_dca->SetLow (m_low);
-  m_dca->SetManager (m_dcfManager);
 }
 AdhocWifiMac::~AdhocWifiMac ()
 {}
@@ -250,9 +247,18 @@
   m_upCallback (packet, hdr->GetAddr2 (), hdr->GetAddr1 ());
 }
 Ptr<DcaTxop>
-AdhocWifiMac::DoGetDcaTxop(void) const
+AdhocWifiMac::GetDcaTxop(void) const
 {
   return m_dca;
 }
 
+void
+AdhocWifiMac::SetDcaTxop (Ptr<DcaTxop> dcaTxop)
+{
+  m_dca = dcaTxop;
+  m_dca->SetLow (m_low);
+  m_dca->SetManager (m_dcfManager);
+}
+
+
 } // namespace ns3
--- a/src/devices/wifi/adhoc-wifi-mac.h	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/adhoc-wifi-mac.h	Wed Apr 29 18:26:25 2009 +0400
@@ -86,7 +86,8 @@
   void ForwardUp (Ptr<Packet> packet, WifiMacHeader const*hdr);
   AdhocWifiMac (const AdhocWifiMac & ctor_arg);
   AdhocWifiMac &operator = (const AdhocWifiMac &o);
-  Ptr<DcaTxop> DoGetDcaTxop(void) const;
+  Ptr<DcaTxop> GetDcaTxop(void) const;
+  void SetDcaTxop (Ptr<DcaTxop> dcaTxop);
 
   Ptr<DcaTxop> m_dca;
   Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> m_upCallback;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/amsdu-subframe-header.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,116 @@
+/* -*-  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 "amsdu-subframe-header.h"
+#include "ns3/address-utils.h"
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (AmsduSubframeHeader);
+
+TypeId
+AmsduSubframeHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::AmsduSubframeHeader")
+    .SetParent<Header> ()
+    .AddConstructor<AmsduSubframeHeader> ()
+    ;
+  return tid; 
+}
+
+TypeId 
+AmsduSubframeHeader::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+AmsduSubframeHeader::AmsduSubframeHeader ()
+  : m_length (0)
+{}
+
+AmsduSubframeHeader::~AmsduSubframeHeader ()
+{}
+
+uint32_t
+AmsduSubframeHeader::GetSerializedSize () const
+{
+  return (6 + 6 + 2);
+}
+
+void
+AmsduSubframeHeader::Serialize (Buffer::Iterator i) const
+{
+  WriteTo (i, m_da);
+  WriteTo (i, m_sa);
+  i.WriteHtonU16 (m_length);
+}
+
+uint32_t
+AmsduSubframeHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  ReadFrom (i, m_da);
+  ReadFrom (i, m_sa);
+  m_length = i.ReadNtohU16 ();
+  return i.GetDistanceFrom (start);
+}
+
+void
+AmsduSubframeHeader::Print (std::ostream &os) const
+{
+  os << "DA = " << m_da << ", SA = " << m_sa << ", length = " << m_length;
+}
+
+void
+AmsduSubframeHeader::SetDestinationAddr (Mac48Address to)
+{
+  m_da = to;
+}
+
+void
+AmsduSubframeHeader::SetSourceAddr (Mac48Address from)
+{
+  m_sa = from;
+}
+
+void
+AmsduSubframeHeader::SetLength (uint16_t length)
+{
+  m_length = length;
+}
+
+Mac48Address
+AmsduSubframeHeader::GetDestinationAddr (void) const
+{
+  return m_da;
+}
+
+Mac48Address
+AmsduSubframeHeader::GetSourceAddr (void) const
+{
+  return m_sa;
+}
+  
+uint16_t
+AmsduSubframeHeader::GetLength (void) const
+{
+  return m_length;
+}
+
+} //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/amsdu-subframe-header.h	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,57 @@
+/* -*-  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>
+ */
+#ifndef AMSDU_SUBFRAME_HEADER_H
+#define AMSDU_SUBFRAME_HEADER_H
+
+#include "ns3/header.h"
+#include "ns3/mac48-address.h"
+
+namespace ns3 {
+
+class AmsduSubframeHeader : public Header
+{
+public:
+
+  AmsduSubframeHeader ();
+  virtual ~AmsduSubframeHeader ();
+  
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+  void SetDestinationAddr (Mac48Address to);
+  void SetSourceAddr (Mac48Address to);
+  void SetLength (uint16_t);
+  Mac48Address GetDestinationAddr (void) const;
+  Mac48Address GetSourceAddr (void) const;
+  uint16_t GetLength (void) const;
+
+private:
+  Mac48Address m_da;
+  Mac48Address m_sa;
+  uint16_t m_length;
+};
+
+} //namespace ns3
+
+#endif /* AMSDU_SUBFRAME_HEADER_H */
--- a/src/devices/wifi/dca-txop.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/dca-txop.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -93,10 +93,12 @@
   DcaTxop *m_txop;
 };
 
+NS_OBJECT_ENSURE_REGISTERED (DcaTxop);
+
 TypeId 
 DcaTxop::GetTypeId (void)
 {
-  static TypeId tid = TypeId ("DcaTxop")
+  static TypeId tid = TypeId ("ns3::DcaTxop")
     .SetParent<Object> ()
     .AddConstructor<DcaTxop> ()
     .AddAttribute ("MinCw", "The minimum value of the contention window.",
--- a/src/devices/wifi/dca-txop.h	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/dca-txop.h	Wed Apr 29 18:26:25 2009 +0400
@@ -115,6 +115,9 @@
   friend class TransmissionListener;
   friend class WifiRemoteStation;
 
+  DcaTxop &operator = (const DcaTxop &);
+  DcaTxop (const DcaTxop &o);
+
   // Inherited from ns3::Object
   Ptr<MacLow> Low (void);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/edca-txop-n.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,691 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006, 2009 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#include "ns3/log.h"
+#include "ns3/assert.h"
+
+#include "edca-txop-n.h"
+#include "mac-low.h"
+#include "dcf-manager.h"
+#include "mac-tx-middle.h"
+#include "wifi-mac-trailer.h"
+#include "wifi-mac.h"
+#include "random-stream.h"
+#include "wifi-mac-queue.h"
+#include "msdu-aggregator.h"
+
+NS_LOG_COMPONENT_DEFINE ("EdcaTxopN");
+
+#define MY_DEBUG(x) \
+  NS_LOG_DEBUG (m_low->GetAddress () << " " << x)
+
+namespace ns3 {
+
+class EdcaTxopN::Dcf : public DcfState
+{
+public:
+  Dcf (EdcaTxopN *txop)
+    : m_txop (txop)
+  {}
+private:
+  virtual void DoNotifyAccessGranted (void) {
+    m_txop->NotifyAccessGranted ();
+  }
+  virtual void DoNotifyInternalCollision (void) {
+    m_txop->NotifyInternalCollision ();
+  }
+  virtual void DoNotifyCollision (void) {
+    m_txop->NotifyCollision ();
+  }
+  EdcaTxopN *m_txop;
+};
+
+class EdcaTxopN::TransmissionListener : public MacLowTransmissionListener
+{
+public:
+  TransmissionListener (EdcaTxopN *txop)
+    : MacLowTransmissionListener (),
+      m_txop (txop) {}
+      
+  virtual ~TransmissionListener () {}
+
+  virtual void GotCts (double snr, WifiMode txMode) {
+    m_txop->GotCts (snr, txMode);
+  }
+  virtual void MissedCts (void) {
+    m_txop->MissedCts ();
+  }
+  virtual void GotAck (double snr, WifiMode txMode) {
+    m_txop->GotAck (snr, txMode);
+  }
+  virtual void MissedAck (void) {
+    m_txop->MissedAck ();
+  }
+  virtual void StartNext (void) {
+    m_txop->StartNext ();
+  }
+  virtual void Cancel (void) {
+    m_txop->Cancel ();
+  }
+
+private:
+  EdcaTxopN *m_txop;
+};
+
+NS_OBJECT_ENSURE_REGISTERED (EdcaTxopN);
+
+TypeId
+EdcaTxopN::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::EdcaTxopN")
+    .SetParent<Object> ()
+    .AddConstructor<EdcaTxopN> ()
+    .AddAttribute ("MinCw", "The minimun value of the contention window.",
+                   UintegerValue (31),
+                   MakeUintegerAccessor (&EdcaTxopN::SetMinCw,
+                                         &EdcaTxopN::GetMinCw),
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("MaxCw", "The maximum value of the contention window.",
+                   UintegerValue (1023),
+                   MakeUintegerAccessor (&EdcaTxopN::SetMaxCw,
+                                         &EdcaTxopN::GetMaxCw),
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("Aifsn", "The AIFSN: the default value conforms to simple DCA.",
+                   UintegerValue (3),
+                   MakeUintegerAccessor (&EdcaTxopN::SetAifsn,
+                                         &EdcaTxopN::GetAifsn),
+                   MakeUintegerChecker<uint32_t> ())
+    ;
+  return tid;
+}
+
+EdcaTxopN::EdcaTxopN ()
+  : m_manager (0),
+    m_currentPacket(0),
+    m_aggregator (0)
+{
+  NS_LOG_FUNCTION (this);
+  m_transmissionListener = new EdcaTxopN::TransmissionListener (this);
+  m_dcf = new EdcaTxopN::Dcf (this);
+  m_queue = CreateObject<WifiMacQueue> ();
+  m_rng = new RealRandomStream ();
+}
+
+EdcaTxopN::~EdcaTxopN ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+EdcaTxopN::DoDispose (void)
+{
+  NS_LOG_FUNCTION (this);
+  m_queue = 0;
+  m_low = 0;
+  m_stationManager = 0;
+  delete m_transmissionListener;
+  delete m_dcf;
+  delete m_rng;
+  m_transmissionListener = 0;
+  m_dcf = 0;
+  m_rng = 0;
+  m_txMiddle = 0;
+  m_aggregator = 0;
+}
+
+void
+EdcaTxopN::SetManager (DcfManager *manager)
+{
+  NS_LOG_FUNCTION (this << manager);
+  m_manager = manager;
+  m_manager->Add (m_dcf);
+}
+
+void
+EdcaTxopN::SetTxOkCallback (TxOk callback)
+{
+  m_txOkCallback = callback;
+}
+
+void 
+EdcaTxopN::SetTxFailedCallback (TxFailed callback)
+{
+  m_txFailedCallback = callback;
+}
+
+void
+EdcaTxopN::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> remoteManager)
+{
+  NS_LOG_FUNCTION (this << remoteManager);
+  m_stationManager = remoteManager;
+}
+void
+EdcaTxopN::SetTypeOfStation (enum TypeOfStation type)
+{
+  NS_LOG_FUNCTION (this << type);
+  m_typeOfStation = type;
+}
+
+enum TypeOfStation
+EdcaTxopN::GetTypeOfStation (void) const
+{
+  return m_typeOfStation;
+}
+
+void 
+EdcaTxopN::SetMaxQueueSize (uint32_t size)
+{
+  NS_LOG_FUNCTION (this << size);
+  m_queue->SetMaxSize (size);
+}
+
+void
+EdcaTxopN::SetMaxQueueDelay (Time delay)
+{
+  NS_LOG_FUNCTION (this << delay);
+  m_queue->SetMaxDelay (delay);
+}
+
+void 
+EdcaTxopN::SetMinCw (uint32_t minCw)
+{
+  NS_LOG_FUNCTION (this << minCw);
+  m_dcf->SetCwMin (minCw);
+}
+
+void 
+EdcaTxopN::SetMaxCw (uint32_t maxCw)
+{
+  NS_LOG_FUNCTION (this << maxCw);
+  m_dcf->SetCwMax (maxCw);
+}
+
+void 
+EdcaTxopN::SetAifsn (uint32_t aifsn)
+{
+  NS_LOG_FUNCTION (this << aifsn);
+  m_dcf->SetAifsn (aifsn);
+}
+
+uint32_t 
+EdcaTxopN::GetMinCw (void) const
+{
+  return m_dcf->GetCwMin ();
+}
+
+uint32_t 
+EdcaTxopN::GetMaxCw (void) const
+{
+  return m_dcf->GetCwMax ();
+}
+
+uint32_t 
+EdcaTxopN::GetAifsn (void) const
+{
+  return m_dcf->GetAifsn ();
+}
+
+void
+EdcaTxopN::SetTxMiddle (MacTxMiddle *txMiddle)
+{
+  m_txMiddle = txMiddle;
+}
+
+Ptr<MacLow>
+EdcaTxopN::Low (void)
+{
+  return m_low;
+}
+
+void
+EdcaTxopN::SetLow(Ptr<MacLow> low)
+{
+  NS_LOG_FUNCTION (this << low);
+  m_low = low;
+}
+
+bool
+EdcaTxopN::NeedsAccess (void) const
+{
+  return !m_queue->IsEmpty () || m_currentPacket != 0;
+}
+
+void
+EdcaTxopN::NotifyAccessGranted (void)
+{
+  NS_LOG_FUNCTION (this);
+  if (m_currentPacket == 0)
+    {
+      if (m_queue->IsEmpty ())
+        {
+          MY_DEBUG ("queue is empty");
+          return; 
+        }
+      m_currentPacket = m_queue->Dequeue (&m_currentHdr);
+      NS_ASSERT (m_currentPacket != 0);
+      
+      uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr);
+      m_currentHdr.SetSequenceNumber (sequence);
+      m_currentHdr.SetFragmentNumber (0);
+      m_currentHdr.SetNoMoreFragments ();
+      m_currentHdr.SetNoRetry ();
+      m_fragmentNumber = 0;
+      MY_DEBUG ("dequeued size="<<m_currentPacket->GetSize ()<<
+                ", to="<<m_currentHdr.GetAddr1 ()<<
+                ", seq="<<m_currentHdr.GetSequenceControl ());
+    }
+  MacLowTransmissionParameters params;
+  params.DisableOverrideDurationId ();
+  if (m_currentHdr.GetAddr1 ().IsBroadcast ()) 
+    {
+      params.DisableRts ();
+      params.DisableAck ();
+      params.DisableNextData ();
+      m_low->StartTransmission (m_currentPacket,
+                                 &m_currentHdr,
+                                 params,
+                                 m_transmissionListener);
+      
+      m_currentPacket = 0;
+      m_dcf->ResetCw ();
+      m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+      StartAccessIfNeeded ();
+      MY_DEBUG ("tx broadcast");
+    }
+  else
+    {
+      params.EnableAck ();
+      if (NeedFragmentation () && ((m_currentHdr.IsQosData () &&
+                                    !m_currentHdr.IsQosAmsdu ()) ||
+                                    m_currentHdr.IsData ()))
+        {
+          params.DisableRts ();
+          WifiMacHeader hdr;
+          Ptr<Packet> fragment = GetFragmentPacket (&hdr);
+          if (IsLastFragment ()) 
+            {
+              MY_DEBUG ("fragmenting last fragment size=" << fragment->GetSize ());
+              params.DisableNextData ();
+            } 
+          else 
+            {
+              MY_DEBUG ("fragmenting size=" << fragment->GetSize ());
+              params.EnableNextData (GetNextFragmentSize ());
+            }
+          m_low->StartTransmission (fragment, &hdr, params, 
+                                     m_transmissionListener);
+        }
+      else
+        {
+          WifiMacHeader peekedHdr;
+          if (m_currentHdr.IsQosData () &&
+              m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (), 
+                                            WifiMacHeader::ADDR1, m_currentHdr.GetAddr1 ()) &&
+              !m_currentHdr.GetAddr1 ().IsBroadcast () &&
+              m_aggregator != 0)
+            {
+              /* here is performed aggregation */
+              Ptr<Packet> currentAggregatedPacket = Create<Packet> ();
+              m_aggregator->Aggregate (m_currentPacket, currentAggregatedPacket,
+                                       MapSrcAddressForAggregation (peekedHdr),
+                                       MapDestAddressForAggregation (peekedHdr));
+              bool aggregated = false;
+              bool isAmsdu = false;
+              Ptr<const Packet> peekedPacket = m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (), 
+                                                                       WifiMacHeader::ADDR1, 
+                                                                       m_currentHdr.GetAddr1 ());
+              while (peekedPacket != 0)
+                {
+                  aggregated = m_aggregator->Aggregate (peekedPacket, currentAggregatedPacket,
+                                                        MapSrcAddressForAggregation (peekedHdr),
+                                                        MapDestAddressForAggregation (peekedHdr));
+                  if (aggregated) 
+                    {
+                      isAmsdu = true;
+                      m_queue->Remove (peekedPacket);
+                    }
+                  else
+                    {
+                      break;
+                    }
+                  peekedPacket = m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (), 
+                                                               WifiMacHeader::ADDR1, m_currentHdr.GetAddr1 ());
+                }
+              if (isAmsdu)
+                {
+                  m_currentHdr.SetQosAmsdu ();
+                  m_currentHdr.SetAddr3 (m_low->GetBssid ());
+                  m_currentPacket = currentAggregatedPacket;
+                  currentAggregatedPacket = 0;
+                  MY_DEBUG ("tx unicast A-MSDU");
+                }
+            }
+          if (NeedRts ())
+            {
+              params.EnableRts ();
+              MY_DEBUG ("tx unicast rts");
+            } 
+          else 
+            {
+              params.DisableRts ();
+              MY_DEBUG ("tx unicast");
+            }
+          params.DisableNextData ();
+          m_low->StartTransmission (m_currentPacket, &m_currentHdr,
+                                    params, m_transmissionListener);
+        }
+    }
+}
+
+void EdcaTxopN::NotifyInternalCollision (void)
+{
+  NS_LOG_FUNCTION (this);
+  NotifyCollision ();
+}
+
+void
+EdcaTxopN::NotifyCollision (void)
+{
+  NS_LOG_FUNCTION (this);
+  m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+  RestartAccessIfNeeded ();
+}
+
+void 
+EdcaTxopN::GotCts (double snr, WifiMode txMode)
+{
+  NS_LOG_FUNCTION (this << snr << txMode);
+  MY_DEBUG ("got cts");
+}
+
+void 
+EdcaTxopN::MissedCts (void)
+{
+  NS_LOG_FUNCTION (this);
+  MY_DEBUG ("missed cts");
+  if (!NeedRtsRetransmission ())
+    {
+      MY_DEBUG ("Cts Fail");
+      WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
+      station->ReportFinalRtsFailed ();
+      if (!m_txFailedCallback.IsNull ()) 
+        {
+          m_txFailedCallback (m_currentHdr);
+        }
+      // to reset the dcf.
+      m_currentPacket = 0;
+      m_dcf->ResetCw ();
+    } 
+  else 
+    {
+      m_dcf->UpdateFailedCw ();
+    }
+  m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+  RestartAccessIfNeeded ();
+}
+
+void
+EdcaTxopN::Queue (Ptr<const Packet> packet, WifiMacHeader const &hdr)
+{
+  NS_LOG_FUNCTION (this << packet << &hdr);
+  WifiMacTrailer fcs;
+  uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.GetSerializedSize ();
+  WifiRemoteStation *station = GetStation (hdr.GetAddr1 ());
+  station->PrepareForQueue (packet, fullPacketSize);
+  m_queue->Enqueue (packet, hdr);
+  StartAccessIfNeeded ();
+}
+
+void
+EdcaTxopN::GotAck (double snr, WifiMode txMode)
+{
+  NS_LOG_FUNCTION (this << snr << txMode);
+  if (!NeedFragmentation () ||
+      IsLastFragment () ||
+      m_currentHdr.IsQosAmsdu ()) 
+    {
+      MY_DEBUG ("got ack. tx done.");
+      if (!m_txOkCallback.IsNull ())
+        {
+           m_txOkCallback (m_currentHdr);
+        }
+      m_currentPacket = 0;
+         
+      m_dcf->ResetCw ();
+      m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+      RestartAccessIfNeeded ();
+    } 
+  else 
+    {
+      MY_DEBUG ("got ack. tx not done, size="<<m_currentPacket->GetSize ());
+    }
+}
+
+void
+EdcaTxopN::MissedAck (void)
+{
+  NS_LOG_FUNCTION (this);
+  MY_DEBUG ("missed ack");
+  if (!NeedDataRetransmission ()) 
+    {
+      MY_DEBUG ("Ack Fail");
+      WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
+      station->ReportFinalDataFailed ();
+      if (!m_txFailedCallback.IsNull ()) 
+        {
+          m_txFailedCallback (m_currentHdr);
+        }
+      // to reset the dcf.
+      m_currentPacket = 0;
+      m_dcf->ResetCw ();
+    } 
+  else 
+    {
+      MY_DEBUG ("Retransmit");
+      m_currentHdr.SetRetry ();
+      m_dcf->UpdateFailedCw ();
+    }
+  m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+  RestartAccessIfNeeded ();
+}
+
+Ptr<MsduAggregator>
+EdcaTxopN::GetMsduAggregator (void) const
+{
+  return m_aggregator;
+}
+
+void
+EdcaTxopN::RestartAccessIfNeeded (void)
+{
+  NS_LOG_FUNCTION (this);
+  if ((m_currentPacket != 0 ||
+       !m_queue->IsEmpty ()) &&
+       !m_dcf->IsAccessRequested ())
+    {
+      m_manager->RequestAccess (m_dcf);
+    }
+}
+
+void
+EdcaTxopN::StartAccessIfNeeded (void)
+{
+  NS_LOG_FUNCTION (this);
+  if (m_currentPacket == 0 &&
+      !m_queue->IsEmpty () &&
+      !m_dcf->IsAccessRequested ())
+    {
+      m_manager->RequestAccess (m_dcf);
+    }
+}
+
+bool
+EdcaTxopN::NeedRts (void)
+{
+  WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
+  return station->NeedRts (m_currentPacket);
+}
+
+bool
+EdcaTxopN::NeedRtsRetransmission (void)
+{
+  WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
+  return station->NeedRtsRetransmission (m_currentPacket);
+}
+
+bool
+EdcaTxopN::NeedDataRetransmission (void)
+{
+  WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
+  return station->NeedDataRetransmission (m_currentPacket);
+}
+
+void
+EdcaTxopN::NextFragment (void)
+{
+  m_fragmentNumber++;
+}
+
+void 
+EdcaTxopN::StartNext (void)
+{
+  NS_LOG_FUNCTION (this);
+  MY_DEBUG ("start next packet fragment");
+  /* this callback is used only for fragments. */
+  NextFragment ();
+  WifiMacHeader hdr;
+  Ptr<Packet> fragment = GetFragmentPacket (&hdr);
+  MacLowTransmissionParameters params;
+  params.EnableAck ();
+  params.DisableRts ();
+  params.DisableOverrideDurationId ();
+  if (IsLastFragment ()) 
+    {
+      params.DisableNextData ();
+    } 
+  else 
+    {
+      params.EnableNextData (GetNextFragmentSize ());
+    }
+  Low ()->StartTransmission (fragment, &hdr, params, m_transmissionListener);
+}
+
+void
+EdcaTxopN::Cancel (void)
+{
+  NS_LOG_FUNCTION (this);
+  MY_DEBUG ("transmission cancelled");
+}
+
+bool
+EdcaTxopN::NeedFragmentation (void) const
+{
+  WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
+  return station->NeedFragmentation (m_currentPacket);
+}
+
+uint32_t
+EdcaTxopN::GetFragmentSize (void)
+{
+  WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
+  return station->GetFragmentSize (m_currentPacket, m_fragmentNumber);
+}
+
+uint32_t
+EdcaTxopN::GetNextFragmentSize (void) 
+{
+  WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
+  return station->GetFragmentSize (m_currentPacket, m_fragmentNumber + 1);
+}
+
+uint32_t
+EdcaTxopN::GetFragmentOffset (void) 
+{
+  WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
+  return station->GetFragmentOffset (m_currentPacket, m_fragmentNumber);
+}
+
+WifiRemoteStation *
+EdcaTxopN::GetStation (Mac48Address ad) const
+{
+  return m_stationManager->Lookup (ad);
+}
+
+bool
+EdcaTxopN::IsLastFragment (void) const
+{
+  WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
+  return station->IsLastFragment (m_currentPacket, m_fragmentNumber);
+}
+
+Ptr<Packet>
+EdcaTxopN::GetFragmentPacket (WifiMacHeader *hdr)
+{
+  *hdr = m_currentHdr;
+  hdr->SetFragmentNumber (m_fragmentNumber);
+  uint32_t startOffset = GetFragmentOffset ();
+  Ptr<Packet> fragment;
+  if (IsLastFragment ()) 
+    {
+      hdr->SetNoMoreFragments ();
+    } 
+  else 
+    {
+      hdr->SetMoreFragments ();
+    }
+  fragment = m_currentPacket->CreateFragment (startOffset, 
+                                              GetFragmentSize ());
+  return fragment;
+}
+
+Mac48Address
+EdcaTxopN::MapSrcAddressForAggregation (WifiMacHeader const &hdr)
+{
+  if (m_typeOfStation == STA || m_typeOfStation == ADHOC_STA)
+    {
+      return hdr.GetAddr2 ();
+    }
+  else
+    {
+      return hdr.GetAddr3 ();
+    }
+}
+
+Mac48Address
+EdcaTxopN::MapDestAddressForAggregation (WifiMacHeader const &hdr)
+{
+  if (m_typeOfStation == AP || m_typeOfStation == ADHOC_STA)
+    {
+      return hdr.GetAddr1 ();
+    }
+  else
+    {
+      return hdr.GetAddr3 ();
+    }
+}
+
+void
+EdcaTxopN::SetMsduAggregator (Ptr<MsduAggregator> aggr)
+{
+  m_aggregator = aggr;
+}
+
+} //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/edca-txop-n.h	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,172 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006, 2009 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#ifndef EDCA_TXOP_N_H
+#define EDCA_TXOP_N_H
+
+#include "ns3/object.h"
+#include "ns3/mac48-address.h"
+#include "ns3/packet.h"
+
+#include "wifi-mode.h"
+#include "wifi-mac.h"
+#include "wifi-mac-header.h"
+#include "qos-utils.h"
+
+#include <map>
+#include <list>
+
+namespace ns3 {
+
+class DcfState;
+class DcfManager;
+class MacLow;
+class MacTxMiddle;
+class WifiMacParameters;
+class WifiMacQueue;
+class RandomStream;
+class MsduAggregator;
+
+/* This queue contains packets for a particular access class.
+ * possibles access classes are:
+ *   
+ *   -AC_VO : voice, tid = 6,7         ^
+ *   -AC_VI : video, tid = 4,5         |
+ *   -AC_BE : best-effort, tid = 0,3   |  priority  
+ *   -AC_BK : background, tid = 1,2    |
+ * 
+ * For more details see section 9.1.3.1 in 802.11 standard.
+ */
+enum TypeOfStation
+{
+  STA,
+  AP,
+  ADHOC_STA
+};
+
+class EdcaTxopN : public Object
+{
+public:
+
+  typedef Callback <void, WifiMacHeader const&> TxOk;
+  typedef Callback <void, WifiMacHeader const&> TxFailed;
+  
+  static TypeId GetTypeId (void);
+  EdcaTxopN ();
+  virtual ~EdcaTxopN ();
+  void DoDispose ();
+  
+  void SetLow (Ptr<MacLow> low);
+  void SetTxMiddle (MacTxMiddle *txMiddle);
+  void SetManager (DcfManager *manager);
+  void SetTxOkCallback (TxOk callback);
+  void SetTxFailedCallback (TxFailed callback);
+  void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> remoteManager);
+  void SetTypeOfStation (enum TypeOfStation type);
+  enum TypeOfStation GetTypeOfStation (void) const;
+
+  void SetMaxQueueSize (uint32_t size);
+  void SetMaxQueueDelay (Time delay);
+  void SetMinCw (uint32_t minCw);
+  void SetMaxCw (uint32_t maxCw);
+  void SetAifsn (uint32_t aifsn);
+  uint32_t GetMinCw (void) const;
+  uint32_t GetMaxCw (void) const;
+  uint32_t GetAifsn (void) const;
+
+  Ptr<MacLow> Low (void);
+  Ptr<MsduAggregator> GetMsduAggregator (void) const;
+
+  /* dcf notifications forwarded here */
+  bool NeedsAccess (void) const;
+  void NotifyAccessGranted (void);
+  void NotifyInternalCollision (void);
+  void NotifyCollision (void);
+
+  /*event handlers*/
+  void GotCts (double snr, WifiMode txMode);
+  void MissedCts (void);
+  void GotAck (double snr, WifiMode txMode);
+  void MissedAck (void);
+  void StartNext (void);
+  void Cancel (void);
+
+  void RestartAccessIfNeeded (void);
+  void StartAccessIfNeeded (void);
+  bool NeedRts (void);
+  bool NeedRtsRetransmission (void);
+  bool NeedDataRetransmission (void);
+  bool NeedFragmentation (void) const;
+  uint32_t GetNextFragmentSize (void);
+  uint32_t GetFragmentSize (void);
+  uint32_t GetFragmentOffset (void);
+  WifiRemoteStation *GetStation (Mac48Address to) const;
+  bool IsLastFragment (void) const;
+  void NextFragment (void);
+  Ptr<Packet> GetFragmentPacket (WifiMacHeader *hdr);
+  
+  void Queue (Ptr<const Packet> packet, WifiMacHeader const &hdr);
+  void SetMsduAggregator (Ptr<MsduAggregator> aggr);
+
+private:
+  /**
+   * This functions are used only to correctly set addresses in a-msdu subframe.
+   * If aggregating sta is a STA (in an infrastructured network):
+   *   SA = Address2
+   *   DA = Address3
+   * If aggregating sta is an AP
+   *   SA = Address3
+   *   DA = Address1
+   */
+  Mac48Address MapSrcAddressForAggregation (WifiMacHeader const &hdr);
+  Mac48Address MapDestAddressForAggregation (WifiMacHeader const &hdr);
+  EdcaTxopN &operator = (const EdcaTxopN &);
+  EdcaTxopN (const EdcaTxopN &);
+  
+  class Dcf;
+  class TransmissionListener;
+  friend class Dcf;
+  friend class TransmissionListener;
+  Dcf *m_dcf;
+  DcfManager *m_manager;
+  Ptr<WifiMacQueue> m_queue;
+  TxOk m_txOkCallback;
+  TxFailed m_txFailedCallback;
+  Ptr<MacLow> m_low;
+  MacTxMiddle *m_txMiddle;
+  TransmissionListener *m_transmissionListener;
+  RandomStream *m_rng;
+  Ptr<WifiRemoteStationManager> m_stationManager;
+  uint8_t m_fragmentNumber;
+  
+  /* current packet could be a simple MSDU or, if an aggregator for this queue is
+     present, could be an A-MSDU.
+   */
+  Ptr<const Packet> m_currentPacket;
+  
+  WifiMacHeader m_currentHdr;
+  Ptr<MsduAggregator> m_aggregator;
+  TypeOfStation m_typeOfStation;
+};
+
+}  //namespace ns3
+
+#endif /* EDCA_TXOP_N_H */
--- a/src/devices/wifi/mac-tx-middle.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/mac-tx-middle.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -1,6 +1,7 @@
 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2005 INRIA
+ * Copyright (c) 2005, 2009 INRIA
+ * 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 
@@ -16,6 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
  */
 
 #include "ns3/assert.h"
@@ -26,11 +28,14 @@
 namespace ns3 {
 
 MacTxMiddle::MacTxMiddle ()
+  : m_sequence (0)
+{}
+
+MacTxMiddle::~MacTxMiddle ()
 {
-  m_sequence = 0;
-  for (uint8_t i = 0; i < 16; i++) 
+  for (std::map<Mac48Address,uint16_t*>::iterator i = m_qosSequences.begin(); i != m_qosSequences.end (); i++)
     {
-      m_qosSequences[i] = 0;
+      delete [] i->second;
     }
 }
 
@@ -43,9 +48,25 @@
     {
       uint8_t tid = hdr->GetQosTid ();
       NS_ASSERT (tid < 16);
-      retval = m_qosSequences[tid];
-      m_qosSequences[tid]++;
-      m_qosSequences[tid] %= 4096;
+      std::map<Mac48Address, uint16_t*>::iterator it = m_qosSequences.find (hdr->GetAddr1 ());
+      if (it != m_qosSequences.end ())
+        {
+          retval = it->second[tid];
+          it->second[tid]++;
+          it->second[tid] %= 4096;
+        }
+      else
+        {
+          retval = 0;
+          std::pair <Mac48Address,uint16_t*> newSeq (hdr->GetAddr1 (), new uint16_t[16]);
+          std::pair <std::map<Mac48Address,uint16_t*>::iterator,bool> newIns = m_qosSequences.insert (newSeq);
+          NS_ASSERT(newIns.second == true);
+          for (uint8_t i = 0; i < 16; i++)
+            {
+              newIns.first->second[i] = 0;
+            }
+          newIns.first->second[tid]++;
+        }
     } 
   else 
     {
--- a/src/devices/wifi/mac-tx-middle.h	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/mac-tx-middle.h	Wed Apr 29 18:26:25 2009 +0400
@@ -1,6 +1,7 @@
 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2005 INRIA
+ * Copyright (c) 2005, 2009 INRIA
+ * 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 
@@ -16,12 +17,15 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
  */
 
 #ifndef MAC_TX_MIDDLE_H
 #define MAC_TX_MIDDLE_H
 
 #include <stdint.h>
+#include <map>
+#include "ns3/mac48-address.h"
 
 namespace ns3 {
 
@@ -30,11 +34,12 @@
 class MacTxMiddle {
 public:
   MacTxMiddle ();
+  ~MacTxMiddle ();
 
   uint16_t GetNextSequenceNumberfor (const WifiMacHeader *hdr);
 
 private:
-  uint16_t m_qosSequences[16];
+  std::map <Mac48Address,uint16_t*> m_qosSequences;
   uint16_t m_sequence;
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/msdu-aggregator.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,78 @@
+/* -*-  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/log.h"
+
+#include "msdu-aggregator.h"
+#include "wifi-mac-header.h"
+
+NS_LOG_COMPONENT_DEFINE ("MsduAggregator");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (MsduAggregator);
+
+TypeId
+MsduAggregator::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::MsduAggregator")
+    .SetParent<Object> ()
+    ;
+  return tid;
+}
+
+MsduAggregator::DeaggregatedMsdus
+MsduAggregator::Deaggregate (Ptr<Packet> aggregatedPacket)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  DeaggregatedMsdus set;
+  
+  AmsduSubframeHeader hdr;
+  uint32_t maxSize = aggregatedPacket->GetSize ();
+  // The worst condition is: two aggregated packets with no padding.
+  // 28 bytes is the size of two Amsdu subframe headers.
+  uint8_t *buffer = new uint8_t[maxSize-28];
+  uint32_t padding;
+  uint32_t deserialized = 0;
+
+  while (deserialized < maxSize)
+   {
+     deserialized += aggregatedPacket->RemoveHeader (hdr);
+     deserialized += aggregatedPacket->CopyData (buffer, hdr.GetLength ());
+     aggregatedPacket->RemoveAtStart (hdr.GetLength ());
+     
+     padding = (4 - ((hdr.GetLength () + 14) %4 )) % 4;
+  
+     if (padding > 0)
+       {
+         aggregatedPacket->RemoveAtStart (padding);
+         deserialized += padding;
+       }
+     //a new packet is created with the content of extracted msdu
+     Ptr<Packet> p = Create<Packet> (buffer, hdr.GetLength ());
+     
+     std::pair<Ptr<Packet>, AmsduSubframeHeader> packetHdr (p,hdr);
+     set.push_back (packetHdr);
+   }
+  delete [] buffer;
+  NS_LOG_INFO ("Deaggreated A-MSDU: extracted "<< set.size () << " MSDUs");
+  return set;
+}
+
+} //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/msdu-aggregator.h	Wed Apr 29 18:26:25 2009 +0400
@@ -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: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#ifndef MSDU_AGGREGATOR_H
+#define MSDU_AGGREGATOR_H
+
+#include "ns3/ptr.h"
+#include "ns3/packet.h"
+#include "ns3/object.h"
+
+#include "amsdu-subframe-header.h"
+
+#include <list>
+
+namespace ns3 {
+	
+class WifiMacHeader;
+/**
+ * \brief Abstract class that concrete msdu aggregators have to implement
+ */
+class MsduAggregator : public Object
+{
+public:
+  typedef std::list<std::pair<Ptr<Packet>, AmsduSubframeHeader> > DeaggregatedMsdus;
+
+  static TypeId GetTypeId (void);
+  /* Adds <i>packet</i> to <i>aggregatedPacket</i>. In concrete aggregator's implementation is 
+   * specified how and if <i>packet</i> can be added to <i>aggregatedPacket</i>. If <i>packet</i>
+   * can be added returns true, false otherwise.
+   */
+  virtual bool Aggregate (Ptr<const Packet> packet, Ptr<Packet> aggregatedPacket,
+                          Mac48Address src, Mac48Address dest) = 0;
+
+  static DeaggregatedMsdus Deaggregate (Ptr<Packet> aggregatedPacket);
+};
+
+}  //namespace ns3
+
+#endif /* MSDU_AGGREGATOR_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/msdu-standard-aggregator.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,86 @@
+/* -*-  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/log.h"
+#include "ns3/uinteger.h"
+
+#include "amsdu-subframe-header.h"
+#include "msdu-standard-aggregator.h"
+
+NS_LOG_COMPONENT_DEFINE ("MsduStandardAggregator");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (MsduStandardAggregator);
+
+TypeId
+MsduStandardAggregator::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::MsduStandardAggregator")
+    .SetParent<MsduAggregator> ()
+    .AddConstructor<MsduStandardAggregator> ()
+    .AddAttribute ("MaxAmsduSize", "Max length in byte of an A-MSDU",
+                   UintegerValue (7935),
+                   MakeUintegerAccessor (&MsduStandardAggregator::m_maxAmsduLength),
+                   MakeUintegerChecker<uint32_t> ())
+    ;
+  return tid;
+}
+
+MsduStandardAggregator::MsduStandardAggregator () 
+{}
+
+MsduStandardAggregator::~MsduStandardAggregator ()
+{}
+
+bool
+MsduStandardAggregator::Aggregate (Ptr<const Packet> packet, Ptr<Packet> aggregatedPacket,
+                                   Mac48Address src, Mac48Address dest)
+{
+  NS_LOG_FUNCTION (this);
+  Ptr<Packet> currentPacket;
+  AmsduSubframeHeader currentHdr;
+
+  uint32_t padding = CalculatePadding (packet);
+  uint32_t actualSize = aggregatedPacket->GetSize ();
+                          
+  if ((14 + packet->GetSize () + actualSize + padding) <= m_maxAmsduLength)
+    {
+      currentHdr.SetDestinationAddr (dest);
+      currentHdr.SetSourceAddr (src);
+      currentHdr.SetLength (packet->GetSize ());
+      currentPacket = packet->Copy ();
+      if (padding)
+        {
+          currentPacket->AddPaddingAtEnd (padding);
+        }
+      currentPacket->AddHeader (currentHdr);
+      aggregatedPacket->AddAtEnd (currentPacket);
+      return true;
+    }
+  return false;
+}
+
+uint32_t
+MsduStandardAggregator::CalculatePadding (Ptr<const Packet> packet)
+{
+  return (4 - ((packet->GetSize() + 14) %4 )) % 4;
+}
+
+}  //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/msdu-standard-aggregator.h	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,56 @@
+/* -*-  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>
+ */
+#ifndef MSDU_STANDARD_AGGREGATOR_H
+#define MSDU_STANDARD_AGGREGATOR_H
+
+#include "msdu-aggregator.h"
+
+namespace ns3 {
+
+class MsduStandardAggregator : public MsduAggregator
+{
+public:
+
+  static TypeId GetTypeId (void);
+  MsduStandardAggregator ();
+  ~MsduStandardAggregator ();
+  /**
+   * \param packet Packet we have to insert into </i>aggregatedPacket</i>.
+   * \param aggregatedPacket Packet that will contain <i>packet</i>, if aggregation is possible, 
+   * \param src Source address of <i>packet</i>.
+   * \param dest Destination address of <i>packet</i>.
+   * 
+   * This method performs an MSDU aggregation.
+   * Returns true if <i>packet</i> can be aggregated to <i>aggregatedPacket</i>, false otherwise. 
+   */
+  virtual bool Aggregate (Ptr<const Packet> packet, Ptr<Packet> aggregatedPacket,
+                          Mac48Address src, Mac48Address dest);
+private:
+  /*  Calculates how much padding must be added to the end of packet.
+      Each A-MSDU subframe is padded so that its length is multiple of 4 octects.
+   */
+  uint32_t CalculatePadding (Ptr<const Packet> packet);
+
+  uint32_t m_maxAmsduLength;
+};
+
+}  //namespace ns3
+
+#endif /* MSDU_STANDARD_AGGREGATOR_H */
--- a/src/devices/wifi/nqap-wifi-mac.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/nqap-wifi-mac.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -60,7 +60,8 @@
                    MakeBooleanChecker ())
     .AddAttribute ("DcaTxop", "The DcaTxop object",
                    PointerValue (),
-                   MakePointerAccessor (&NqapWifiMac::DoGetDcaTxop),
+                   MakePointerAccessor (&NqapWifiMac::GetDcaTxop,
+                                        &NqapWifiMac::SetDcaTxop),
                    MakePointerChecker<DcaTxop> ()) 
     ;
   return tid;
@@ -78,12 +79,6 @@
   m_dcfManager = new DcfManager ();
   m_dcfManager->SetupLowListener (m_low);
 
-  m_dca = CreateObject<DcaTxop> ();
-  m_dca->SetLow (m_low);
-  m_dca->SetManager (m_dcfManager);
-  m_dca->SetTxOkCallback (MakeCallback (&NqapWifiMac::TxOk, this));
-  m_dca->SetTxFailedCallback (MakeCallback (&NqapWifiMac::TxFailed, this));
-
   m_beaconDca = CreateObject<DcaTxop> ();
   m_beaconDca->SetAifsn(1);
   m_beaconDca->SetMinCw(0);
@@ -108,6 +103,7 @@
   m_phy = 0;
   m_dca = 0;
   m_beaconDca = 0;
+  m_stationManager = 0;
   m_beaconEvent.Cancel ();
   WifiMac::DoDispose ();
 }
@@ -300,8 +296,7 @@
   hdr.SetAddr3 (from);
   hdr.SetDsFrom ();
   hdr.SetDsNotTo ();
-
-  m_dca->Queue (packet, hdr);  
+  m_dca->Queue (packet, hdr);
 }
 void 
 NqapWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
@@ -565,9 +560,19 @@
     }  
 }
 Ptr<DcaTxop>
-NqapWifiMac::DoGetDcaTxop(void) const
+NqapWifiMac::GetDcaTxop(void) const
 {
   return m_dca;
 }
 
+void
+NqapWifiMac::SetDcaTxop (Ptr<DcaTxop> dcaTxop)
+{
+  m_dca = dcaTxop;
+  m_dca->SetLow (m_low);
+  m_dca->SetManager (m_dcfManager);
+  m_dca->SetTxOkCallback (MakeCallback (&NqapWifiMac::TxOk, this));
+  m_dca->SetTxFailedCallback (MakeCallback (&NqapWifiMac::TxFailed, this));
+}
+
 } // namespace ns3
--- a/src/devices/wifi/nqap-wifi-mac.h	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/nqap-wifi-mac.h	Wed Apr 29 18:26:25 2009 +0400
@@ -21,6 +21,7 @@
 #define MAC_HIGH_NQAP_H
 
 #include <stdint.h>
+
 #include "ns3/mac48-address.h"
 #include "ns3/callback.h"
 #include "ns3/packet.h"
@@ -113,7 +114,8 @@
   virtual void DoDispose (void);
   NqapWifiMac (const NqapWifiMac & ctor_arg);
   NqapWifiMac &operator = (const NqapWifiMac &o);
-  Ptr<DcaTxop> DoGetDcaTxop(void) const;
+  Ptr<DcaTxop> GetDcaTxop (void) const;
+  void SetDcaTxop (Ptr<DcaTxop> dcaTxop);
 
   Ptr<DcaTxop> m_dca;
   Ptr<DcaTxop> m_beaconDca;
--- a/src/devices/wifi/nqsta-wifi-mac.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/nqsta-wifi-mac.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -89,7 +89,8 @@
                    MakeBooleanChecker ())
     .AddAttribute ("DcaTxop", "The DcaTxop object",
                    PointerValue (),
-                   MakePointerAccessor (&NqstaWifiMac::DoGetDcaTxop),
+                   MakePointerAccessor (&NqstaWifiMac::GetDcaTxop,
+                                        &NqstaWifiMac::SetDcaTxop),
                    MakePointerChecker<DcaTxop> ()) 
     .AddTraceSource ("Assoc", "Associated with an access point.",
                      MakeTraceSourceAccessor (&NqstaWifiMac::m_assocLogger))
@@ -99,7 +100,6 @@
   return tid;
 }
 
-
 NqstaWifiMac::NqstaWifiMac ()
   : m_state (BEACON_MISSED),
     m_probeRequestEvent (),
@@ -115,10 +115,6 @@
 
   m_dcfManager = new DcfManager ();
   m_dcfManager->SetupLowListener (m_low);
-
-  m_dca = CreateObject<DcaTxop> ();
-  m_dca->SetLow (m_low);
-  m_dca->SetManager (m_dcfManager);
 }
 
 NqstaWifiMac::~NqstaWifiMac ()
@@ -137,6 +133,7 @@
   m_dcfManager = 0;
   m_phy = 0;
   m_dca = 0;
+  m_stationManager = 0;
   WifiMac::DoDispose ();
 }
 
@@ -207,10 +204,17 @@
   return m_low->GetPifs ();
 }
 Ptr<DcaTxop>
-NqstaWifiMac::DoGetDcaTxop(void) const
+NqstaWifiMac::GetDcaTxop(void) const
 {
   return m_dca;
 }
+void
+NqstaWifiMac::SetDcaTxop (Ptr<DcaTxop> dcaTxop)
+{
+  m_dca = dcaTxop;
+  m_dca->SetLow (m_low);
+  m_dca->SetManager (m_dcfManager);
+}
 void 
 NqstaWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
 {
@@ -565,7 +569,7 @@
           SetState (WAIT_ASSOC_RESP);
           SendAssociationRequest ();
         }
-  } 
+    } 
   else if (hdr->IsProbeResp ()) 
     {
       if (m_state == WAIT_PROBE_RESP) 
--- a/src/devices/wifi/nqsta-wifi-mac.h	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/nqsta-wifi-mac.h	Wed Apr 29 18:26:25 2009 +0400
@@ -137,7 +137,8 @@
   virtual void DoDispose (void);
   NqstaWifiMac (const NqstaWifiMac & ctor_arg);
   NqstaWifiMac &operator = (const NqstaWifiMac & ctor_arg);
-  Ptr<DcaTxop> DoGetDcaTxop(void) const;
+  Ptr<DcaTxop> GetDcaTxop(void) const;
+  void SetDcaTxop (Ptr<DcaTxop> dcaTxop);
   void SetState (enum MacState value);
 
   enum MacState m_state;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/qadhoc-wifi-mac.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,441 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006, 2009 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#include "ns3/pointer.h"
+#include "ns3/log.h"
+#include "ns3/string.h"
+
+#include "qos-tag.h"
+#include "edca-txop-n.h"
+#include "qadhoc-wifi-mac.h"
+#include "mac-low.h"
+#include "dcf-manager.h"
+#include "mac-rx-middle.h"
+#include "mac-tx-middle.h"
+#include "wifi-mac-header.h"
+#include "msdu-aggregator.h"
+#include "amsdu-subframe-header.h"
+#include "mgt-headers.h"
+
+NS_LOG_COMPONENT_DEFINE ("QadhocWifiMac");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (QadhocWifiMac);
+
+TypeId
+QadhocWifiMac::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::QadhocWifiMac")
+    .SetParent<WifiMac> ()
+    .AddConstructor<QadhocWifiMac> ()
+    .AddAttribute ("VO_EdcaTxopN",
+                   "Queue that manages packets belonging to AC_VO access class",
+                   PointerValue (),
+                   MakePointerAccessor(&QadhocWifiMac::GetVOQueue,
+                                       &QadhocWifiMac::SetVOQueue),
+                   MakePointerChecker<EdcaTxopN> ())
+    .AddAttribute ("VI_EdcaTxopN",
+                   "Queue that manages packets belonging to AC_VI access class",
+                   PointerValue (),
+                   MakePointerAccessor(&QadhocWifiMac::GetVIQueue,
+                                       &QadhocWifiMac::SetVIQueue),
+                   MakePointerChecker<EdcaTxopN> ())
+    .AddAttribute ("BE_EdcaTxopN",
+                   "Queue that manages packets belonging to AC_BE access class",
+                   PointerValue (),
+                   MakePointerAccessor(&QadhocWifiMac::GetBEQueue,
+                                       &QadhocWifiMac::SetBEQueue),
+                   MakePointerChecker<EdcaTxopN> ())
+    .AddAttribute ("BK_EdcaTxopN",
+                   "Queue that manages packets belonging to AC_BK access class",
+                   PointerValue (),
+                   MakePointerAccessor(&QadhocWifiMac::GetBKQueue,
+                                       &QadhocWifiMac::SetBKQueue),
+                   MakePointerChecker<EdcaTxopN> ())
+    ;
+  return tid;
+}
+
+QadhocWifiMac::QadhocWifiMac ()
+{
+  NS_LOG_FUNCTION (this);
+  m_rxMiddle = new MacRxMiddle ();
+  m_rxMiddle->SetForwardCallback (MakeCallback (&QadhocWifiMac::Receive, this));
+
+  m_txMiddle = new MacTxMiddle ();
+
+  m_low = CreateObject<MacLow> ();
+  m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
+
+  m_dcfManager = new DcfManager ();
+  m_dcfManager->SetupLowListener (m_low);
+}
+
+QadhocWifiMac::~QadhocWifiMac ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+QadhocWifiMac::DoDispose (void)
+{
+  NS_LOG_FUNCTION (this);
+  delete m_rxMiddle;
+  m_rxMiddle = 0;
+  delete m_txMiddle;
+  m_txMiddle = 0;
+  delete m_dcfManager;
+  m_dcfManager = 0;
+  m_low = 0;
+  m_phy = 0;
+  m_voEdca = 0;
+  m_viEdca = 0;
+  m_beEdca = 0;
+  m_bkEdca = 0;
+  m_stationManager = 0;
+  std::map<AccessClass, Ptr<EdcaTxopN> >::iterator it = m_queues.begin ();
+  for (;it != m_queues.end (); it++)
+    {
+      it->second = 0;
+    }
+  WifiMac::DoDispose ();
+}
+
+void
+QadhocWifiMac::SetSlot (Time slotTime)
+{
+  m_dcfManager->SetSlot (slotTime);
+  m_low->SetSlotTime (slotTime);
+}
+
+void
+QadhocWifiMac::SetSifs (Time sifs)
+{
+  m_dcfManager->SetSifs (sifs);
+  m_low->SetSifs (sifs);
+}
+
+void
+QadhocWifiMac::SetEifsNoDifs (Time eifsNoDifs)
+{
+  m_dcfManager->SetEifsNoDifs (eifsNoDifs);
+  m_eifsNoDifs = eifsNoDifs;
+}
+
+void
+QadhocWifiMac::SetAckTimeout (Time ackTimeout)
+{
+  m_low->SetAckTimeout (ackTimeout);
+}
+
+void
+QadhocWifiMac::SetCtsTimeout (Time ctsTimeout)
+{
+  m_low->SetCtsTimeout (ctsTimeout);
+}
+
+void
+QadhocWifiMac::SetPifs (Time pifs)
+{
+  m_low->SetPifs (pifs);
+}
+
+Time
+QadhocWifiMac::GetSlot (void) const
+{
+  return m_low->GetSlotTime ();
+}
+
+Time
+QadhocWifiMac::GetSifs (void) const
+{
+  return m_low->GetSifs ();
+}
+
+Time
+QadhocWifiMac::GetEifsNoDifs (void) const
+{
+  return m_eifsNoDifs;
+}
+
+Time
+QadhocWifiMac::GetAckTimeout (void) const
+{
+  return m_low->GetAckTimeout ();
+}
+
+Time
+QadhocWifiMac::GetCtsTimeout (void) const
+{
+  return m_low->GetCtsTimeout ();
+}
+
+Time
+QadhocWifiMac::GetPifs (void) const
+{
+  return m_low->GetPifs ();
+}
+
+void
+QadhocWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
+{
+  m_phy = phy;
+  m_dcfManager->SetupPhyListener (phy);
+  m_low->SetPhy (phy);
+}
+
+void
+QadhocWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
+{
+  NS_LOG_FUNCTION (this << stationManager);
+  m_stationManager = stationManager;
+  m_voEdca->SetWifiRemoteStationManager (stationManager);
+  m_viEdca->SetWifiRemoteStationManager (stationManager);
+  m_beEdca->SetWifiRemoteStationManager (stationManager);
+  m_bkEdca->SetWifiRemoteStationManager (stationManager);  
+  m_low->SetWifiRemoteStationManager (stationManager);
+}
+
+void
+QadhocWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
+{
+  NS_FATAL_ERROR ("Adhoc does not support a from != m_low->GetAddress ()");
+}
+
+void
+QadhocWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
+{
+  /* For now Qos adhoc stations sends only Qos frame. In the future they 
+   * should be able to send frames also to Non-Qos Stas.
+   */
+  NS_LOG_FUNCTION (packet->GetSize () << to);
+  WifiMacHeader hdr;
+  hdr.SetType (WIFI_MAC_QOSDATA);
+  hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
+  hdr.SetQosNoEosp ();
+  hdr.SetQosNoAmsdu ();
+  /* Transmission of multiple frames in the same 
+     Txop is not supported for now */
+  hdr.SetQosTxopLimit (0);
+  
+  hdr.SetAddr1 (to);
+  hdr.SetAddr2 (m_low->GetAddress ());
+  hdr.SetAddr3 (GetBssid ());
+  hdr.SetDsNotFrom ();
+  hdr.SetDsNotTo ();
+
+  WifiRemoteStation *destination = m_stationManager->Lookup (to);
+  if (destination->IsBrandNew ())
+    {
+      // in adhoc mode, we assume that every destination
+      // supports all the rates we support.
+      for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
+        {
+          destination->AddSupportedMode (m_phy->GetMode (i));
+        }
+      destination->RecordDisassociated ();
+    }
+
+  uint8_t tid = QosUtilsGetTidForPacket (packet);
+  if (tid < 8)
+    {
+      hdr.SetQosTid (tid);
+      AccessClass ac = QosUtilsMapTidToAc (tid);
+      m_queues[ac]->Queue (packet, hdr);
+    }
+  else
+    {
+      //packet is considerated belonging to BestEffort AC
+      hdr.SetQosTid (0);
+      m_queues[AC_BE]->Queue (packet, hdr);
+    }
+}
+
+bool
+QadhocWifiMac::SupportsSendFrom (void) const
+{
+  return false;
+}
+
+void
+QadhocWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback)
+{
+  m_forwardUp = upCallback;
+}
+
+void
+QadhocWifiMac::SetLinkUpCallback (Callback<void> linkUp)
+{
+  // an Adhoc network is always UP.
+  linkUp ();
+}
+
+void
+QadhocWifiMac::SetLinkDownCallback (Callback<void> linkDown)
+{}
+
+Mac48Address
+QadhocWifiMac::GetAddress (void) const
+{
+  return m_low->GetAddress ();
+}
+
+Ssid
+QadhocWifiMac::GetSsid (void) const
+{
+  return m_ssid;
+}
+
+void
+QadhocWifiMac::SetAddress (Mac48Address address)
+{
+  m_low->SetAddress (address);
+  m_low->SetBssid (address);
+}
+
+void
+QadhocWifiMac::SetSsid (Ssid ssid)
+{
+  NS_LOG_FUNCTION (this << ssid);
+  // XXX: here, we should start a special adhoc network
+  m_ssid = ssid;
+}
+
+Mac48Address
+QadhocWifiMac::GetBssid (void) const
+{
+  return m_low->GetBssid ();
+}
+
+void
+QadhocWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to)
+{
+  NS_LOG_FUNCTION (this << packet << from);
+  m_forwardUp (packet, from, to);
+}
+
+void
+QadhocWifiMac::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
+{
+  NS_LOG_FUNCTION (this << packet << hdr);
+  NS_ASSERT (!hdr->IsCtl ());
+  Mac48Address from = hdr->GetAddr2 ();
+  Mac48Address to = hdr->GetAddr1 ();
+  if (hdr->IsData ())
+    {
+      if (hdr->IsQosData () && hdr->IsQosAmsdu ())
+        {
+          NS_LOG_DEBUG ("Received A-MSDU from"<<from);
+          DeaggregateAmsduAndForward (packet, hdr);
+        }
+      else
+        {
+          ForwardUp (packet, from, to);
+        }
+    }
+  else if (hdr->IsMgt ())
+    {
+      //Handling action frames
+    }
+}
+
+void
+QadhocWifiMac::DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket,
+                                           WifiMacHeader const *hdr)
+{
+  DeaggregatedMsdus packets = MsduAggregator::Deaggregate (aggregatedPacket);
+  for (DeaggregatedMsdusCI i = packets.begin (); i != packets.end (); ++i)
+    {
+      ForwardUp ((*i).first, (*i).second.GetSourceAddr (),
+                 (*i).second.GetDestinationAddr ());
+    }
+}
+
+Ptr<EdcaTxopN>
+QadhocWifiMac::GetVOQueue (void) const
+{
+  return m_voEdca;
+}
+
+Ptr<EdcaTxopN>
+QadhocWifiMac::GetVIQueue (void) const
+{
+  return m_viEdca;
+}
+
+Ptr<EdcaTxopN>
+QadhocWifiMac::GetBEQueue (void) const
+{
+  return m_beEdca;
+}
+
+Ptr<EdcaTxopN>
+QadhocWifiMac::GetBKQueue (void) const
+{
+  return m_bkEdca;
+}
+
+void
+QadhocWifiMac::SetVOQueue (Ptr<EdcaTxopN> voQueue)
+{
+  m_voEdca = voQueue;
+  m_queues.insert (std::make_pair(AC_VO, m_voEdca));
+  m_queues[AC_VO]->SetLow (m_low);
+  m_queues[AC_VO]->SetManager (m_dcfManager);
+  m_queues[AC_VO]->SetTypeOfStation (ADHOC_STA);
+  m_queues[AC_VO]->SetTxMiddle (m_txMiddle);
+}
+
+void
+QadhocWifiMac::SetVIQueue (Ptr<EdcaTxopN> viQueue)
+{
+  m_viEdca = viQueue;
+  m_queues.insert (std::make_pair(AC_VI, m_viEdca));
+  m_queues[AC_VI]->SetLow (m_low);
+  m_queues[AC_VI]->SetManager (m_dcfManager);
+  m_queues[AC_VI]->SetTypeOfStation (ADHOC_STA);
+  m_queues[AC_VI]->SetTxMiddle (m_txMiddle);
+}
+
+void
+QadhocWifiMac::SetBEQueue (Ptr<EdcaTxopN> beQueue)
+{
+  m_beEdca = beQueue;
+  m_queues.insert (std::make_pair(AC_BE, m_beEdca));
+  m_queues[AC_BE]->SetLow (m_low);
+  m_queues[AC_BE]->SetManager (m_dcfManager);
+  m_queues[AC_BE]->SetTypeOfStation (ADHOC_STA);
+  m_queues[AC_BE]->SetTxMiddle (m_txMiddle);
+}
+
+void
+QadhocWifiMac::SetBKQueue (Ptr<EdcaTxopN> bkQueue)
+{
+  m_bkEdca = bkQueue;
+  m_queues.insert (std::make_pair(AC_BK, m_bkEdca));
+  m_queues[AC_BK]->SetLow (m_low);
+  m_queues[AC_BK]->SetManager (m_dcfManager);
+  m_queues[AC_BK]->SetTypeOfStation (ADHOC_STA);
+  m_queues[AC_BK]->SetTxMiddle (m_txMiddle);
+}
+
+} //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/qadhoc-wifi-mac.h	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,122 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006, 2009 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#ifndef QADHOC_WIFI_MAC_H
+#define QADHOC_WIFI_MAC_H
+
+#include "ns3/mac48-address.h"
+#include "ns3/callback.h"
+#include "ns3/packet.h"
+
+#include "wifi-mac.h"
+#include "qos-utils.h"
+#include "amsdu-subframe-header.h"
+
+namespace ns3 {
+
+class EdcaTxopN;
+class WifiMacHeader;
+class WifiPhy;
+class DcfManager;
+class MacLow;
+class MacRxMiddle;
+
+class QadhocWifiMac : public WifiMac
+{
+public:
+  static TypeId GetTypeId (void);
+
+  QadhocWifiMac ();
+  ~QadhocWifiMac ();
+
+  // all inherited from WifiMac base class.
+  virtual void SetSlot (Time slotTime);
+  virtual void SetSifs (Time sifs);
+  virtual void SetEifsNoDifs (Time eifsNoDifs);
+  virtual void SetAckTimeout (Time ackTimeout);
+  virtual void SetCtsTimeout (Time ctsTimeout);
+  virtual void SetPifs (Time pifs);
+  virtual Time GetSlot (void) const;
+  virtual Time GetSifs (void) const;
+  virtual Time GetEifsNoDifs (void) const;
+  virtual Time GetAckTimeout (void) const;
+  virtual Time GetCtsTimeout (void) const;
+  virtual Time GetPifs (void) const;
+  virtual void SetWifiPhy (Ptr<WifiPhy> phy);
+  virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
+  virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from);
+  virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
+  virtual bool SupportsSendFrom (void) const;
+  virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback);
+  virtual void SetLinkUpCallback (Callback<void> linkUp);
+  virtual void SetLinkDownCallback (Callback<void> linkDown);
+  virtual Mac48Address GetAddress (void) const;
+  virtual Ssid GetSsid (void) const;
+  virtual void SetAddress (Mac48Address address);
+  virtual void SetSsid (Ssid ssid);
+  virtual Mac48Address GetBssid (void) const;
+
+private:
+  Callback<void, Ptr<Packet>, Mac48Address, Mac48Address> m_forwardUp;
+  virtual void DoDispose (void);
+  void Receive (Ptr<Packet> packet, WifiMacHeader const *hdr);
+  void ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to);
+  QadhocWifiMac &operator = (const QadhocWifiMac &);
+  QadhocWifiMac (const QadhocWifiMac &);
+
+  /**
+  * When an A-MSDU is received, is deaggregated by this method and all extracted packets are
+  * forwarded up.
+  */
+  void DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, WifiMacHeader const *hdr);
+
+  typedef std::map<AccessClass, Ptr<EdcaTxopN> > Queues;
+  typedef std::list<std::pair<Ptr<Packet>, AmsduSubframeHeader> > DeaggregatedMsdus;
+  typedef std::list<std::pair<Ptr<Packet>, AmsduSubframeHeader> >::const_iterator DeaggregatedMsdusCI;
+
+  Ptr<EdcaTxopN> GetVOQueue (void) const;
+  Ptr<EdcaTxopN> GetVIQueue (void) const;
+  Ptr<EdcaTxopN> GetBEQueue (void) const;
+  Ptr<EdcaTxopN> GetBKQueue (void) const;
+
+  void SetVOQueue (Ptr<EdcaTxopN> voQueue);
+  void SetVIQueue (Ptr<EdcaTxopN> viQueue);
+  void SetBEQueue (Ptr<EdcaTxopN> beQueue);
+  void SetBKQueue (Ptr<EdcaTxopN> bkQueue);
+
+  Queues m_queues;
+  Ptr<EdcaTxopN> m_voEdca;
+  Ptr<EdcaTxopN> m_viEdca;
+  Ptr<EdcaTxopN> m_beEdca;
+  Ptr<EdcaTxopN> m_bkEdca;
+  Ptr<MacLow> m_low;
+  Ptr<WifiPhy> m_phy;
+  Ptr<WifiRemoteStationManager> m_stationManager;
+  MacRxMiddle *m_rxMiddle;
+  MacTxMiddle *m_txMiddle;
+  DcfManager *m_dcfManager;
+  Ssid m_ssid;
+  Time m_eifsNoDifs;
+};
+
+} //namespace ns3
+
+#endif /* QADHOC_WIFI_MAC_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/qap-wifi-mac.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,789 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006, 2009 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/string.h"
+#include "ns3/pointer.h"
+
+#include "qos-tag.h"
+#include "qap-wifi-mac.h"
+#include "dca-txop.h"
+#include "edca-txop-n.h"
+#include "wifi-phy.h"
+#include "dcf-manager.h"
+#include "mac-rx-middle.h"
+#include "mac-tx-middle.h"
+#include "mgt-headers.h"
+#include "mac-low.h"
+#include "amsdu-subframe-header.h"
+#include "msdu-aggregator.h"
+
+NS_LOG_COMPONENT_DEFINE ("QapWifiMac");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (QapWifiMac);
+
+TypeId
+QapWifiMac::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::QapWifiMac")
+    .SetParent<WifiMac> ()
+    .AddConstructor<QapWifiMac> ()
+    .AddAttribute ("BeaconInterval", "Delay between two beacons",
+                   TimeValue (Seconds (0.1)),
+                   MakeTimeAccessor (&QapWifiMac::GetBeaconInterval,
+                                     &QapWifiMac::SetBeaconInterval),
+                   MakeTimeChecker ())
+    .AddAttribute ("BeaconGeneration", "Whether or not beacons are generated.",
+                   BooleanValue (true),
+                   MakeBooleanAccessor (&QapWifiMac::SetBeaconGeneration,
+                                        &QapWifiMac::GetBeaconGeneration),
+                   MakeBooleanChecker ())
+    .AddAttribute ("VO_EdcaTxopN",
+                   "Queue that manages packets belonging to AC_VO access class",
+                   PointerValue (),
+                   MakePointerAccessor(&QapWifiMac::GetVOQueue,
+                                       &QapWifiMac::SetVOQueue),
+                   MakePointerChecker<EdcaTxopN> ())
+    .AddAttribute ("VI_EdcaTxopN",
+                   "Queue that manages packets belonging to AC_VI access class",
+                   PointerValue (),
+                   MakePointerAccessor(&QapWifiMac::GetVIQueue,
+                                       &QapWifiMac::SetVIQueue),
+                   MakePointerChecker<EdcaTxopN> ())
+    .AddAttribute ("BE_EdcaTxopN",
+                   "Queue that manages packets belonging to AC_BE access class",
+                   PointerValue (),
+                   MakePointerAccessor(&QapWifiMac::GetBEQueue,
+                                       &QapWifiMac::SetBEQueue),
+                   MakePointerChecker<EdcaTxopN> ())
+    .AddAttribute ("BK_EdcaTxopN",
+                   "Queue that manages packets belonging to AC_BK access class",
+                   PointerValue (),
+                   MakePointerAccessor(&QapWifiMac::GetBKQueue,
+                                       &QapWifiMac::SetBKQueue),
+                   MakePointerChecker<EdcaTxopN> ())
+    ;  
+  return tid;
+}
+
+QapWifiMac::QapWifiMac ()
+{
+  NS_LOG_FUNCTION (this);
+  m_rxMiddle = new MacRxMiddle ();
+  m_rxMiddle->SetForwardCallback (MakeCallback (&QapWifiMac::Receive, this));
+  
+  m_txMiddle = new MacTxMiddle ();
+
+  m_low = CreateObject<MacLow> ();
+  m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
+  
+  m_dcfManager = new DcfManager ();
+  m_dcfManager->SetupLowListener (m_low);
+
+  m_beaconDca = CreateObject<DcaTxop> ();
+  m_beaconDca->SetAifsn(1);
+  m_beaconDca->SetMinCw(0);
+  m_beaconDca->SetMaxCw(0);
+  m_beaconDca->SetLow (m_low);
+  m_beaconDca->SetManager (m_dcfManager);
+}
+
+QapWifiMac::~QapWifiMac ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+QapWifiMac::DoDispose ()
+{
+  delete m_rxMiddle;
+  m_rxMiddle = 0;
+  delete m_txMiddle;
+  m_txMiddle = 0;
+  delete m_dcfManager;
+  m_dcfManager = 0;
+  m_low = 0;
+  m_phy = 0;
+  m_beaconDca = 0;
+  m_beaconEvent.Cancel ();
+  m_voEdca = 0;
+  m_viEdca = 0;
+  m_beEdca = 0;
+  m_bkEdca = 0;
+  m_stationManager = 0;
+  std::map<AccessClass, Ptr<EdcaTxopN> >::iterator it = m_queues.begin ();
+  for (;it != m_queues.end (); it++)
+    {
+      it->second = 0;
+    }
+  WifiMac::DoDispose ();
+}
+
+void
+QapWifiMac::SetBeaconGeneration (bool enable)
+{
+  NS_LOG_FUNCTION (this << enable);
+  if (enable)
+    {
+      m_beaconEvent = Simulator::ScheduleNow (&QapWifiMac::SendOneBeacon, this);
+    }
+  else
+    {
+      m_beaconEvent.Cancel ();
+    }
+}
+
+bool
+QapWifiMac::GetBeaconGeneration (void) const
+{
+  return m_beaconEvent.IsRunning ();
+}
+
+Time
+QapWifiMac::GetBeaconInterval (void) const
+{
+  return m_beaconInterval;
+}
+
+void 
+QapWifiMac::SetSlot (Time slotTime)
+{
+  NS_LOG_FUNCTION (this << slotTime);
+  m_dcfManager->SetSlot (slotTime);
+  m_low->SetSlotTime (slotTime);
+}
+
+void 
+QapWifiMac::SetSifs (Time sifs)
+{
+  NS_LOG_FUNCTION (this << sifs);
+  m_dcfManager->SetSifs (sifs);
+  m_low->SetSifs (sifs);
+}
+
+void 
+QapWifiMac::SetEifsNoDifs (Time eifsNoDifs)
+{
+  NS_LOG_FUNCTION (this << eifsNoDifs);
+  m_dcfManager->SetEifsNoDifs (eifsNoDifs);
+  m_eifsNoDifs = eifsNoDifs;
+}
+
+void 
+QapWifiMac::SetAckTimeout (Time ackTimeout)
+{
+  m_low->SetAckTimeout (ackTimeout);
+}
+
+void 
+QapWifiMac::SetCtsTimeout (Time ctsTimeout)
+{
+  m_low->SetCtsTimeout (ctsTimeout);
+}
+
+void 
+QapWifiMac::SetPifs (Time pifs)
+{
+  m_low->SetPifs (pifs);
+}
+
+Time 
+QapWifiMac::GetSlot (void) const
+{
+  return m_low->GetSlotTime ();
+}
+
+Time 
+QapWifiMac::GetSifs (void) const
+{
+  return m_low->GetSifs ();
+}
+
+Time 
+QapWifiMac::GetEifsNoDifs (void) const
+{
+  return m_eifsNoDifs;
+}
+
+Time 
+QapWifiMac::GetAckTimeout (void) const
+{
+  return m_low->GetAckTimeout ();
+}
+
+Time 
+QapWifiMac::GetCtsTimeout (void) const
+{
+  return m_low->GetCtsTimeout ();
+}
+
+Time 
+QapWifiMac::GetPifs (void) const
+{
+  return m_low->GetPifs ();
+}
+
+void 
+QapWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
+{
+  NS_LOG_FUNCTION (this << phy);
+  m_phy = phy;
+  m_dcfManager->SetupPhyListener (phy);
+  m_low->SetPhy (phy);
+}
+
+void
+QapWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
+{
+  NS_LOG_FUNCTION (this << stationManager);
+  m_stationManager = stationManager;
+  m_voEdca->SetWifiRemoteStationManager (stationManager);
+  m_viEdca->SetWifiRemoteStationManager (stationManager);
+  m_beEdca->SetWifiRemoteStationManager (stationManager);
+  m_bkEdca->SetWifiRemoteStationManager (stationManager);
+  m_beaconDca->SetWifiRemoteStationManager (stationManager);
+  m_low->SetWifiRemoteStationManager (stationManager);
+}
+
+void 
+QapWifiMac::SetForwardUpCallback (Callback<void, Ptr<Packet>, Mac48Address, Mac48Address> upCallback)
+{
+  NS_LOG_FUNCTION (this);
+  m_forwardUp = upCallback;
+}
+
+void
+QapWifiMac::SetLinkUpCallback (Callback<void> linkUp)
+{
+  NS_LOG_FUNCTION (this);
+  if (!linkUp.IsNull ())
+    {
+      linkUp ();
+    }
+}
+
+void 
+QapWifiMac::SetLinkDownCallback (Callback<void> linkDown)
+{
+  NS_LOG_FUNCTION (this);
+}
+
+Mac48Address
+QapWifiMac::GetAddress () const
+{
+  return m_low->GetAddress ();
+}
+
+Ssid 
+QapWifiMac::GetSsid (void) const
+{
+  return m_ssid;
+}
+
+void
+QapWifiMac::SetAddress (Mac48Address address)
+{
+  NS_LOG_FUNCTION (address);
+  m_low->SetAddress (address);
+  m_low->SetBssid (address);
+}
+
+void
+QapWifiMac::SetSsid (Ssid ssid)
+{
+  NS_LOG_FUNCTION (this << ssid);
+  m_ssid = ssid;
+}
+
+Mac48Address 
+QapWifiMac::GetBssid (void) const
+{
+  return m_low->GetBssid ();
+}
+
+void
+QapWifiMac::SetBeaconInterval (Time interval)
+{
+  NS_LOG_FUNCTION (this << interval);
+  m_beaconInterval = interval;
+}
+
+void
+QapWifiMac::StartBeaconing (void)
+{
+  NS_LOG_FUNCTION (this);
+  SendOneBeacon ();
+}
+
+void
+QapWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to)
+{
+  NS_LOG_FUNCTION (this << packet << from);
+  m_forwardUp (packet, from, to);
+}
+
+void
+QapWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
+{
+  /* For now Qos AP sends only Qos frame. In the future it should be able to 
+     send frames also to Non-Qos Stas.
+   */
+  NS_LOG_FUNCTION (this << packet << from << to);
+  WifiMacHeader hdr;
+  hdr.SetType (WIFI_MAC_QOSDATA);
+  hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
+  hdr.SetQosNoEosp ();
+  hdr.SetQosNoAmsdu ();
+  /* Transmission of multiple frames in the same 
+     Txop is not supported for now */
+  hdr.SetQosTxopLimit (0);
+
+  hdr.SetAddr1 (to);
+  hdr.SetAddr2 (GetAddress ());
+  hdr.SetAddr3 (from);
+  hdr.SetDsFrom ();
+  hdr.SetDsNotTo ();
+  
+  uint8_t tid = QosUtilsGetTidForPacket (packet);
+  if (tid < 8)
+    {
+      hdr.SetQosTid (tid);
+      AccessClass ac = QosUtilsMapTidToAc (tid);
+      m_queues[ac]->Queue (packet, hdr);
+    }
+  else
+    {
+      //packet is considerated belonging to BestEffort AC
+      hdr.SetQosTid (0);
+      m_queues[AC_BE]->Queue (packet, hdr);
+    }
+}
+
+void
+QapWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to,
+                         WifiMacHeader const *oldHdr)
+{
+  /* For now Qos AP sends only Qos frame. In the future it should be able to 
+     send frames also to Non-Qos Stas.
+   */
+  NS_LOG_FUNCTION (this << packet << from << to);
+  NS_ASSERT (oldHdr->IsQosData ());
+  WifiMacHeader hdr;
+  hdr.SetType (WIFI_MAC_QOSDATA);
+  hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
+  hdr.SetQosNoEosp ();
+  hdr.SetQosNoAmsdu ();
+  /* Transmission of multiple frames in the same 
+     Txop is not supported for now */
+  hdr.SetQosTxopLimit (0);
+  hdr.SetQosTid (oldHdr->GetQosTid ());
+
+  hdr.SetAddr1 (to);
+  hdr.SetAddr2 (GetAddress ());
+  hdr.SetAddr3 (from);
+  hdr.SetDsFrom ();
+  hdr.SetDsNotTo ();
+
+  AccessClass ac = QosUtilsMapTidToAc (oldHdr->GetQosTid ());
+  m_queues[ac]->Queue (packet, hdr);
+}
+
+void
+QapWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
+{
+  NS_LOG_FUNCTION (this << packet << from << to);
+  ForwardDown (packet, from, to);
+}
+
+void 
+QapWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
+{
+  NS_LOG_FUNCTION (this << packet << to);
+  ForwardDown (packet, m_low->GetAddress (), to);
+}
+
+bool 
+QapWifiMac::SupportsSendFrom (void) const
+{
+  return true;
+}
+
+SupportedRates
+QapWifiMac::GetSupportedRates (void) const
+{
+  // 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);
+      rates.AddSupportedRate (mode.GetDataRate ());
+    }
+  // set the basic rates
+  for (uint32_t j = 0; j < m_stationManager->GetNBasicModes (); j++)
+    {
+      WifiMode mode = m_stationManager->GetBasicMode (j);
+      rates.SetBasicRate (mode.GetDataRate ());
+    }
+  return rates; 
+}
+
+void
+QapWifiMac::SendProbeResp (Mac48Address to)
+{
+  NS_LOG_FUNCTION (this << to);
+  WifiMacHeader hdr;
+  hdr.SetProbeResp ();
+  hdr.SetAddr1 (to);
+  hdr.SetAddr2 (GetAddress ());
+  hdr.SetAddr3 (GetAddress ());
+  hdr.SetDsNotFrom ();
+  hdr.SetDsNotTo ();
+  Ptr<Packet> packet = Create<Packet> ();
+  MgtProbeResponseHeader probe;
+  probe.SetSsid (GetSsid ());
+  probe.SetSupportedRates (GetSupportedRates ());
+  probe.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
+  packet->AddHeader (probe);
+
+  /* Which is correct queue for management frames ? */
+  m_queues[AC_VO]->Queue (packet, hdr);
+}
+
+void
+QapWifiMac::SendAssocResp (Mac48Address to, bool success)
+{
+  NS_LOG_FUNCTION (this << to << success);
+  WifiMacHeader hdr;
+  hdr.SetAssocResp ();
+  hdr.SetAddr1 (to);
+  hdr.SetAddr2 (GetAddress ());
+  hdr.SetAddr3 (GetAddress ());
+  hdr.SetDsNotFrom ();
+  hdr.SetDsNotTo ();
+  Ptr<Packet> packet = Create<Packet> ();
+  MgtAssocResponseHeader assoc;
+  StatusCode code;
+  if (success)
+    {
+      code.SetSuccess ();
+    }
+  else
+    {
+      code.SetFailure ();
+    }
+  assoc.SetSupportedRates (GetSupportedRates ());
+  assoc.SetStatusCode (code);
+  packet->AddHeader (assoc);
+  
+  /* Which is correct queue for management frames ? */
+  m_queues[AC_VO]->Queue (packet, hdr);
+}
+
+void
+QapWifiMac::SendOneBeacon (void)
+{
+  NS_LOG_FUNCTION (this);
+  WifiMacHeader hdr;
+  hdr.SetBeacon ();
+  hdr.SetAddr1 (Mac48Address::GetBroadcast ());
+  hdr.SetAddr2 (GetAddress ());
+  hdr.SetAddr3 (GetAddress ());
+  hdr.SetDsNotFrom ();
+  hdr.SetDsNotTo ();
+  Ptr<Packet> packet = Create<Packet> ();
+  MgtBeaconHeader beacon;
+  beacon.SetSsid (GetSsid ());
+  beacon.SetSupportedRates (GetSupportedRates ());
+  beacon.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
+  
+  packet->AddHeader (beacon);
+
+  m_beaconDca->Queue (packet, hdr);
+  m_beaconEvent = Simulator::Schedule (m_beaconInterval, &QapWifiMac::SendOneBeacon, this);  
+}
+
+void
+QapWifiMac::TxOk (WifiMacHeader const &hdr)
+{
+  NS_LOG_FUNCTION (this);
+  WifiRemoteStation *station = m_stationManager->Lookup (hdr.GetAddr1 ());
+  if (hdr.IsAssocResp () && 
+      station->IsWaitAssocTxOk ()) 
+    {
+      NS_LOG_DEBUG ("associated with sta="<<hdr.GetAddr1 ());
+      station->RecordGotAssocTxOk ();
+    }
+}
+
+void
+QapWifiMac::TxFailed (WifiMacHeader const &hdr)
+{
+  NS_LOG_FUNCTION (this);
+  WifiRemoteStation *station = m_stationManager->Lookup (hdr.GetAddr1 ());
+  if (hdr.IsAssocResp () && 
+      station->IsWaitAssocTxOk ()) 
+    {
+      NS_LOG_DEBUG ("assoc failed with sta="<<hdr.GetAddr1 ());
+      station->RecordGotAssocTxFailed ();
+    }
+}
+
+void
+QapWifiMac::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
+{
+  NS_LOG_FUNCTION (this << packet << hdr);
+
+  Mac48Address from = hdr->GetAddr2 ();
+  WifiRemoteStation *fromStation = m_stationManager->Lookup (from);
+  
+  if (hdr->IsData ())
+    {
+      Mac48Address bssid = hdr->GetAddr1 ();
+      if (!hdr->IsFromDs () && 
+          hdr->IsToDs () &&
+          bssid == GetAddress () &&
+          fromStation->IsAssociated ())
+        {
+          Mac48Address to = hdr->GetAddr3 ();
+          WifiRemoteStation *toStation = m_stationManager->Lookup (to);
+          
+          if (to == GetAddress ())
+            {
+              NS_LOG_DEBUG ("frame for me (Qap) from="<<from);
+              if (hdr->IsQosData ())
+                {
+                  if (hdr->IsQosAmsdu ())
+                    {
+                      NS_LOG_DEBUG ("Received A-MSDU from="<<from<<", size="<<packet->GetSize ());
+                      DeaggregateAmsduAndForward (packet, hdr);
+                      packet = 0;
+                    }
+                  else
+                    {
+                      ForwardUp (packet, from, bssid);
+                    }
+                }
+              else
+                {
+                  ForwardUp (packet, from, bssid);
+                }
+            }
+          else if (to.IsGroup () ||
+                   toStation->IsAssociated ())
+            {
+              NS_LOG_DEBUG ("forwarding frame from="<<from<<", to="<<to);
+              Ptr<Packet> copy = packet->Copy ();
+              ForwardDown (packet, from, to, hdr);
+              ForwardUp (copy, from, to);
+            }
+          else
+            {
+              ForwardUp (packet, from, to);
+            }
+        }
+      else if (hdr->IsFromDs () &&
+               hdr->IsToDs ()) 
+        {
+          // this is an AP-to-AP frame
+          // we ignore for now.
+        }
+      else 
+        {
+          // we can ignore these frames since 
+          // they are not targeted at the AP
+        }
+    }
+  else if (hdr->IsMgt ())
+    {
+      if (hdr->IsProbeReq ()) 
+        {
+          NS_ASSERT (hdr->GetAddr1 ().IsBroadcast ());
+          SendProbeResp (hdr->GetAddr2 ());
+        }
+      else if (hdr->GetAddr1 () == GetAddress ()) 
+        {
+          if (hdr->IsAssocReq ()) 
+            {
+              // first, verify that the the station's supported
+              // rate set is compatible with our Basic Rate set
+              MgtAssocRequestHeader assocReq;
+              packet->RemoveHeader (assocReq);
+              SupportedRates rates = assocReq.GetSupportedRates ();
+              bool problem = false;
+              for (uint32_t i = 0; i < m_stationManager->GetNBasicModes (); i++)
+                {
+                  WifiMode mode = m_stationManager->GetBasicMode (i);
+                  if (!rates.IsSupportedRate (mode.GetDataRate ()))
+                   {
+                     problem = true;
+                     break;
+                   }
+                }
+             if (problem)
+               {
+                 // one of the Basic Rate set mode is not
+                 // supported by the station. So, we return an assoc
+                 // response with an error status.
+                 SendAssocResp (hdr->GetAddr2 (), false);
+               }
+             else
+               {
+                 // station supports all rates in Basic Rate Set.
+                 // record all its supported modes in its associated WifiRemoteStation
+                 for (uint32_t j = 0; j < m_phy->GetNModes (); j++)
+                   {
+                     WifiMode mode = m_phy->GetMode (j);
+                     if (rates.IsSupportedRate (mode.GetDataRate ()))
+                       {
+                         fromStation->AddSupportedMode (mode);
+                       }
+                    }
+                  fromStation->RecordWaitAssocTxOk ();
+                  // send assoc response with success status.
+                  SendAssocResp (hdr->GetAddr2 (), true);
+                }
+            }
+          else if (hdr->IsDisassociation ()) 
+            {
+              fromStation->RecordDisassociated ();
+            } 
+          else if (hdr->IsReassocReq ()) 
+            {
+              /* we don't support reassoc frames for now */
+            } 
+          else if (hdr->IsAuthentication () ||
+                   hdr->IsDeauthentication ()) 
+                 {
+                   /*
+                   */
+                 } 
+          else 
+            {
+              /* unknown mgt frame
+              */
+            }
+        }
+    }
+}
+
+void
+QapWifiMac::DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, WifiMacHeader const *hdr)
+{
+  DeaggregatedMsdus packets = MsduAggregator::Deaggregate (aggregatedPacket);
+  for (DeaggregatedMsdusCI i = packets.begin (); i != packets.end (); ++i)
+    {
+      if ((*i).second.GetDestinationAddr () == GetAddress ())
+        {
+          ForwardUp ((*i).first, (*i).second.GetSourceAddr (),
+                     (*i).second.GetDestinationAddr ());
+        }
+      else
+        {
+          Mac48Address from = (*i).second.GetSourceAddr ();
+          Mac48Address to = (*i).second.GetDestinationAddr ();
+          NS_LOG_DEBUG ("forwarding QoS frame from="<<from<<", to="<<to);
+          ForwardDown ((*i).first, from, to, hdr);
+        }
+    }
+}
+
+Ptr<EdcaTxopN>
+QapWifiMac::GetVOQueue (void) const
+{
+  return m_voEdca;
+}
+
+Ptr<EdcaTxopN>
+QapWifiMac::GetVIQueue (void) const
+{
+  return m_viEdca;
+}
+
+Ptr<EdcaTxopN>
+QapWifiMac::GetBEQueue (void) const
+{
+  return m_beEdca;
+}
+
+Ptr<EdcaTxopN>
+QapWifiMac::GetBKQueue (void) const
+{
+  return m_bkEdca;
+}
+
+void
+QapWifiMac::SetVOQueue (Ptr<EdcaTxopN> voQueue)
+{
+  m_voEdca = voQueue;
+  m_queues.insert (std::make_pair(AC_VO, m_voEdca));
+  m_queues[AC_VO]->SetLow (m_low);
+  m_queues[AC_VO]->SetManager (m_dcfManager);
+  m_queues[AC_VO]->SetTypeOfStation (AP);
+  m_queues[AC_VO]->SetTxMiddle (m_txMiddle);
+  m_queues[AC_VO]->SetTxOkCallback (MakeCallback (&QapWifiMac::TxOk, this));
+  m_queues[AC_VO]->SetTxFailedCallback (MakeCallback (&QapWifiMac::TxFailed, this));
+}
+
+void
+QapWifiMac::SetVIQueue (Ptr<EdcaTxopN> viQueue)
+{
+  m_viEdca = viQueue;
+  m_queues.insert (std::make_pair(AC_VI, m_viEdca));
+  m_queues[AC_VI]->SetLow (m_low);
+  m_queues[AC_VI]->SetManager (m_dcfManager);
+  m_queues[AC_VI]->SetTypeOfStation (AP);
+  m_queues[AC_VI]->SetTxMiddle (m_txMiddle);
+  m_queues[AC_VI]->SetTxOkCallback (MakeCallback (&QapWifiMac::TxOk, this));
+  m_queues[AC_VI]->SetTxFailedCallback (MakeCallback (&QapWifiMac::TxFailed, this));
+}
+
+void
+QapWifiMac::SetBEQueue (Ptr<EdcaTxopN> beQueue)
+{
+  m_beEdca = beQueue;
+  m_queues.insert (std::make_pair(AC_BE, m_beEdca));
+  m_queues[AC_BE]->SetLow (m_low);
+  m_queues[AC_BE]->SetManager (m_dcfManager);
+  m_queues[AC_BE]->SetTypeOfStation (AP);
+  m_queues[AC_BE]->SetTxMiddle (m_txMiddle);
+  m_queues[AC_BE]->SetTxOkCallback (MakeCallback (&QapWifiMac::TxOk, this));
+  m_queues[AC_BE]->SetTxFailedCallback (MakeCallback (&QapWifiMac::TxFailed, this));
+}
+
+void
+QapWifiMac::SetBKQueue (Ptr<EdcaTxopN> bkQueue)
+{
+  m_bkEdca = bkQueue;
+  m_queues.insert (std::make_pair(AC_BK, m_bkEdca));
+  m_queues[AC_BK]->SetLow (m_low);
+  m_queues[AC_BK]->SetManager (m_dcfManager);
+  m_queues[AC_BK]->SetTypeOfStation (AP);
+  m_queues[AC_BK]->SetTxMiddle (m_txMiddle);
+  m_queues[AC_BK]->SetTxOkCallback (MakeCallback (&QapWifiMac::TxOk, this));
+  m_queues[AC_BK]->SetTxFailedCallback (MakeCallback (&QapWifiMac::TxFailed, this));
+}
+
+}  //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/qap-wifi-mac.h	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,147 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006, 2009 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#ifndef QAP_WIFI_MAC_H
+#define QAP_WIFI_MAC_H
+
+#include "ns3/mac48-address.h"
+#include "ns3/callback.h"
+#include "ns3/packet.h"
+#include "ns3/nstime.h"
+#include "ns3/event-id.h"
+
+#include "supported-rates.h"
+#include "wifi-remote-station-manager.h"
+#include "wifi-mac.h"
+#include "qos-utils.h"
+
+#include <map>
+
+namespace ns3 {
+
+class DcaTxop;
+class EdcaTxopN;
+class WifiMacHeader;
+class WifiPhy;
+class MacLow;
+class MacRxMiddle;
+class MacTxMiddle;
+class DcfManager;
+class AmsduSubframeHeader;
+class MsduAggregator;
+
+class QapWifiMac : public WifiMac
+{
+public:
+  static TypeId GetTypeId (void);
+  QapWifiMac ();
+  virtual ~QapWifiMac ();
+  
+  // inherited from WifiMac.
+  virtual void SetSlot (Time slotTime);
+  virtual void SetSifs (Time sifs);
+  virtual void SetEifsNoDifs (Time eifsNoDifs);
+  virtual void SetAckTimeout (Time ackTimeout);
+  virtual void SetCtsTimeout (Time ctsTimeout);
+  virtual void SetPifs (Time pifs);
+  virtual Time GetSlot (void) const;
+  virtual Time GetSifs (void) const;
+  virtual Time GetEifsNoDifs (void) const;
+  virtual Time GetAckTimeout (void) const;
+  virtual Time GetCtsTimeout (void) const;
+  virtual Time GetPifs (void) const;
+  virtual void SetWifiPhy (Ptr<WifiPhy> phy);
+  virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
+  virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from);
+  virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
+  virtual bool SupportsSendFrom (void) const;
+  virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback);
+  virtual void SetLinkUpCallback (Callback<void> linkUp);
+  virtual void SetLinkDownCallback (Callback<void> linkDown);
+  virtual Mac48Address GetAddress (void) const;
+  virtual Ssid GetSsid (void) const;
+  virtual void SetAddress (Mac48Address address);
+  virtual void SetSsid (Ssid ssid);
+  virtual Mac48Address GetBssid (void) const;
+
+  void SetBeaconInterval (Time interval);
+  Time GetBeaconInterval (void) const;
+  void StartBeaconing (void);
+
+private:
+  virtual void DoDispose (void);
+  void Receive (Ptr<Packet> packet, WifiMacHeader const *hdr);
+  void ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to);
+  void ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to);
+  /* Next function is invoked only when ap relies a frame. */
+  void ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to,
+                    WifiMacHeader const *oldHdr);
+  void TxOk (WifiMacHeader const &hdr);
+  void TxFailed (WifiMacHeader const &hdr);
+  void SendProbeResp (Mac48Address to);
+  void SendAssocResp (Mac48Address to, bool success);
+  void SendOneBeacon (void);
+  SupportedRates GetSupportedRates (void) const;
+  void SetBeaconGeneration (bool enable);
+  bool GetBeaconGeneration (void) const;
+  
+  void DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, WifiMacHeader const *hdr);
+  QapWifiMac &operator = (const QapWifiMac &);
+  QapWifiMac (const QapWifiMac &);
+
+  typedef std::map<AccessClass, Ptr<EdcaTxopN> > Queues;
+  typedef std::list<std::pair<Ptr<Packet>, AmsduSubframeHeader> > DeaggregatedMsdus;
+  typedef std::list<std::pair<Ptr<Packet>, AmsduSubframeHeader> >::const_iterator DeaggregatedMsdusCI;
+
+  Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> m_forwardUp;
+  
+  Ptr<EdcaTxopN> GetVOQueue (void) const;
+  Ptr<EdcaTxopN> GetVIQueue (void) const;
+  Ptr<EdcaTxopN> GetBEQueue (void) const;
+  Ptr<EdcaTxopN> GetBKQueue (void) const;
+
+  void SetVOQueue (Ptr<EdcaTxopN> voQueue);
+  void SetVIQueue (Ptr<EdcaTxopN> viQueue);
+  void SetBEQueue (Ptr<EdcaTxopN> beQueue);
+  void SetBKQueue (Ptr<EdcaTxopN> bkQueue);
+
+  /*Next map is used only for an esay access to a specific queue*/
+  Queues m_queues;
+  Ptr<EdcaTxopN> m_voEdca;
+  Ptr<EdcaTxopN> m_viEdca;
+  Ptr<EdcaTxopN> m_beEdca;
+  Ptr<EdcaTxopN> m_bkEdca;
+  Ptr<DcaTxop> m_beaconDca;
+  Ptr<MacLow> m_low;
+  Ptr<WifiPhy> m_phy;
+  Ptr<WifiRemoteStationManager> m_stationManager;
+  MacRxMiddle *m_rxMiddle;
+  MacTxMiddle *m_txMiddle;
+  DcfManager *m_dcfManager;
+  Ssid m_ssid;
+  EventId m_beaconEvent;
+  Time m_beaconInterval;
+  Time m_eifsNoDifs;
+};
+
+}  //namespace ns3
+
+#endif /* QAP_WIFI_MAC_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/qos-tag.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,85 @@
+/* -*-  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 "qos-tag.h"
+#include "ns3/tag.h"
+#include "ns3/uinteger.h"
+
+namespace ns3 {
+
+TypeId 
+QosTag::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::QosTag")
+    .SetParent<Tag> ()
+    .AddConstructor<QosTag> ()
+    .AddAttribute ("tid", "The tid that indicates AC which packet belongs",
+                   UintegerValue (0),
+                   MakeUintegerAccessor (&QosTag::Get),
+                   MakeUintegerChecker<uint8_t> ())
+    ;
+  return tid;
+}
+
+TypeId
+QosTag::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+QosTag::QosTag()
+{}
+
+uint32_t 
+QosTag::GetSerializedSize (void) const
+{
+  return 1;
+}
+
+void
+QosTag::Serialize (TagBuffer i) const
+{
+  i.WriteU8 (m_tid);
+}
+
+void
+QosTag::Deserialize (TagBuffer i)
+{
+  m_tid = i.ReadU8 ();
+}
+
+void
+QosTag::Set (uint8_t tid)
+{
+  m_tid = tid;
+}
+
+uint8_t
+QosTag::Get () const
+{
+  return m_tid;
+}
+
+void
+QosTag::Print (std::ostream &os) const
+{
+  os << "Tid=" << m_tid;
+}
+
+} //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/qos-tag.h	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,49 @@
+/* -*-  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>
+ */
+#ifndef QOS_TAG_H
+#define QOS_TAG_H
+
+#include "ns3/packet.h"
+
+namespace ns3 {
+
+class Tag;
+
+class QosTag : public Tag
+{
+public:
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  
+  QosTag ();
+  virtual void Serialize (TagBuffer i) const;
+  virtual void Deserialize (TagBuffer i);
+  virtual uint32_t GetSerializedSize () const;
+  virtual void Print (std::ostream &os) const;
+
+  uint8_t Get (void) const;
+  void Set (uint8_t tid);
+private:
+  uint8_t m_tid;
+};
+
+} //namespace ns3
+
+#endif /* QOS_TAG_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/qos-utils.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,72 @@
+/* -*-  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 "qos-utils.h"
+#include "qos-tag.h"
+
+namespace ns3 {
+
+AccessClass
+QosUtilsMapTidToAc (uint8_t tid)
+{
+  switch (tid) {
+  case 0 :
+    return AC_BE;
+    break;
+  case 1 :
+    return AC_BK;
+    break;
+  case 2 :
+    return AC_BK;
+    break;
+  case 3 :
+    return AC_BE;
+    break;
+  case 4 :
+    return AC_VI;
+    break;
+  case 5 :
+    return AC_VI;
+    break;
+  case 6 :
+    return AC_VO;
+    break;
+  case 7 : 
+    return AC_VO;
+    break;
+  }
+  return AC_UNDEF;
+}
+
+uint8_t
+QosUtilsGetTidForPacket (Ptr<const Packet> packet)
+{
+  QosTag qos;
+  uint8_t tid = 8;
+  if (packet->PeekPacketTag (qos))
+    {
+      if (qos.Get () < 8)
+        {
+          tid = qos.Get ();
+        }
+    }
+  return tid;
+}
+
+} //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/qos-utils.h	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,49 @@
+/* -*-  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>
+ */
+#ifndef QOS_UTILS_H
+#define QOS_UTILS_H
+
+#include "ns3/uinteger.h"
+#include "ns3/ptr.h"
+#include "ns3/packet.h"
+
+namespace ns3 {
+
+enum AccessClass {
+  AC_VO = 0,
+  AC_VI = 1,
+  AC_BE = 2,
+  AC_BK = 3,
+  AC_UNDEF
+};
+
+/* Maps TID (Traffic ID) to Access classes.
+ * For more details see table 9-1 of IEEE802.11 standard.
+ */
+AccessClass QosUtilsMapTidToAc (uint8_t tid);
+
+/* If a qos tag is attached to the packet, returns a value < 8.
+   A value >= 8 is returned otherwise.
+ */
+uint8_t QosUtilsGetTidForPacket (Ptr<const Packet> packet);
+
+} //namespace ns3
+
+#endif /* QOS_UTILS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/qsta-wifi-mac.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,768 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006, 2009 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/string.h"
+#include "ns3/pointer.h"
+
+#include "qos-tag.h"
+#include "edca-txop-n.h"
+#include "qsta-wifi-mac.h"
+#include "mac-low.h"
+#include "dcf-manager.h"
+#include "mac-rx-middle.h"
+#include "mac-tx-middle.h"
+#include "wifi-mac-header.h"
+#include "msdu-aggregator.h"
+#include "amsdu-subframe-header.h"
+#include "mgt-headers.h"
+
+NS_LOG_COMPONENT_DEFINE ("QstaWifiMac");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (QstaWifiMac);
+
+TypeId
+QstaWifiMac::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::QstaWifiMac")
+    .SetParent<WifiMac> ()
+    .AddConstructor<QstaWifiMac> ()
+    .AddAttribute ("ProbeRequestTimeout", "The interval between two consecutive probe request attempts.",
+                   TimeValue (Seconds (0.05)),
+                   MakeTimeAccessor (&QstaWifiMac::m_probeRequestTimeout),
+                   MakeTimeChecker ())
+    .AddAttribute ("AssocRequestTimeout", "The interval between two consecutive assoc request attempts.",
+                   TimeValue (Seconds (0.5)),
+                   MakeTimeAccessor (&QstaWifiMac::m_assocRequestTimeout),
+                   MakeTimeChecker ())
+    .AddAttribute ("MaxMissedBeacons", 
+                   "Number of beacons which much be consecutively missed before "
+                   "we attempt to restart association.",
+                   UintegerValue (10),
+                   MakeUintegerAccessor (&QstaWifiMac::m_maxMissedBeacons),
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("ActiveProbing", "If true, we send probe requests. If false, we don't.",
+                   BooleanValue (false),
+                   MakeBooleanAccessor (&QstaWifiMac::SetActiveProbing),
+                   MakeBooleanChecker ())
+    .AddAttribute ("VO_EdcaTxopN",
+                   "Queue that manages packets belonging to AC_VO access class",
+                   PointerValue (),
+                   MakePointerAccessor(&QstaWifiMac::GetVOQueue,
+                                       &QstaWifiMac::SetVOQueue),
+                   MakePointerChecker<EdcaTxopN> ())
+    .AddAttribute ("VI_EdcaTxopN",
+                   "Queue that manages packets belonging to AC_VI access class",
+                   PointerValue (),
+                   MakePointerAccessor(&QstaWifiMac::GetVIQueue,
+                                       &QstaWifiMac::SetVIQueue),
+                   MakePointerChecker<EdcaTxopN> ())
+    .AddAttribute ("BE_EdcaTxopN",
+                   "Queue that manages packets belonging to AC_BE access class",
+                   PointerValue (),
+                   MakePointerAccessor(&QstaWifiMac::GetBEQueue,
+                                       &QstaWifiMac::SetBEQueue),
+                   MakePointerChecker<EdcaTxopN> ())
+    .AddAttribute ("BK_EdcaTxopN",
+                   "Queue that manages packets belonging to AC_BK access class",
+                   PointerValue (),
+                   MakePointerAccessor(&QstaWifiMac::GetBKQueue,
+                                       &QstaWifiMac::SetBKQueue),
+                   MakePointerChecker<EdcaTxopN> ())
+    ;
+  return tid;
+}
+
+QstaWifiMac::QstaWifiMac ()
+  : m_state (BEACON_MISSED),
+    m_probeRequestEvent (),
+    m_assocRequestEvent (),
+    m_beaconWatchdogEnd (Seconds (0.0))
+{
+  NS_LOG_FUNCTION (this);
+  m_rxMiddle = new MacRxMiddle ();
+  m_rxMiddle->SetForwardCallback (MakeCallback (&QstaWifiMac::Receive, this));
+  /*TxMiddle can be shared between all queues */
+  m_txMiddle= new MacTxMiddle ();
+  
+  m_low = CreateObject<MacLow> ();
+  m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
+
+  m_dcfManager = new DcfManager ();
+  m_dcfManager->SetupLowListener (m_low);
+}
+
+QstaWifiMac::~QstaWifiMac ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+QstaWifiMac::DoDispose ()
+{
+  NS_LOG_FUNCTION (this);
+  delete m_rxMiddle;
+  delete m_txMiddle;
+  delete m_dcfManager;
+  m_rxMiddle = 0;
+  m_txMiddle = 0;
+  m_low = 0;
+  m_phy = 0;
+  m_dcfManager = 0;
+  m_voEdca = 0;
+  m_viEdca = 0;
+  m_beEdca = 0;
+  m_bkEdca = 0;
+  m_stationManager = 0;
+  std::map<AccessClass, Ptr<EdcaTxopN> >::iterator it = m_queues.begin ();
+  for (;it != m_queues.end (); it++)
+    {
+      it->second = 0;
+    }
+  WifiMac::DoDispose ();
+}
+
+void
+QstaWifiMac::SetSlot (Time slotTime)
+{
+  NS_LOG_FUNCTION (this << slotTime);
+  m_dcfManager->SetSlot (slotTime);
+  m_low->SetSlotTime (slotTime);
+}
+
+void 
+QstaWifiMac::SetSifs (Time sifs)
+{
+  NS_LOG_FUNCTION (this << sifs);
+  m_dcfManager->SetSifs (sifs);
+  m_low->SetSifs (sifs);
+}
+
+void
+QstaWifiMac::SetEifsNoDifs (Time eifsNoDifs)
+{
+  NS_LOG_FUNCTION (this << eifsNoDifs);
+  m_dcfManager->SetEifsNoDifs (eifsNoDifs);
+  m_eifsNoDifs = eifsNoDifs;
+}
+
+void
+QstaWifiMac::SetAckTimeout (Time ackTimeout)
+{
+  m_low->SetAckTimeout (ackTimeout);
+}
+
+void
+QstaWifiMac::SetCtsTimeout (Time ctsTimeout)
+{
+  m_low->SetCtsTimeout (ctsTimeout);
+}
+
+void
+QstaWifiMac::SetPifs (Time pifs)
+{
+  m_low->SetPifs (pifs);
+}
+
+Time
+QstaWifiMac::GetSlot (void) const
+{
+  return m_low->GetSlotTime ();
+}
+
+Time
+QstaWifiMac::GetSifs (void) const
+{
+  return m_low->GetSifs ();
+}
+
+Time 
+QstaWifiMac::GetEifsNoDifs (void) const
+{
+  return m_eifsNoDifs;
+}
+
+Time
+QstaWifiMac::GetAckTimeout (void) const
+{
+ return m_low->GetAckTimeout ();
+}
+
+Time
+QstaWifiMac::GetCtsTimeout (void) const
+{
+  return m_low->GetCtsTimeout ();
+}
+
+Time 
+QstaWifiMac::GetPifs (void) const
+{
+  return m_low->GetPifs ();
+}
+
+void
+QstaWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
+{
+  m_phy = phy;
+  m_dcfManager->SetupPhyListener (phy);
+  m_low->SetPhy (phy);
+}
+
+void
+QstaWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
+{
+  m_stationManager = stationManager;
+  m_queues[AC_VO]->SetWifiRemoteStationManager (stationManager);
+  m_queues[AC_VI]->SetWifiRemoteStationManager (stationManager);
+  m_queues[AC_BE]->SetWifiRemoteStationManager (stationManager);
+  m_queues[AC_BK]->SetWifiRemoteStationManager (stationManager);
+  m_low->SetWifiRemoteStationManager (stationManager);
+}
+
+void
+QstaWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback)
+{
+  m_forwardUp = upCallback;
+}
+
+void
+QstaWifiMac::SetLinkUpCallback (Callback<void> linkUp)
+{
+  m_linkUp = linkUp;
+}
+
+void
+QstaWifiMac::SetLinkDownCallback (Callback<void> linkDown)
+{
+  m_linkDown = linkDown;
+}
+
+Mac48Address
+QstaWifiMac::GetAddress (void) const
+{
+  return m_low->GetAddress ();
+}
+
+Ssid
+QstaWifiMac::GetSsid (void) const
+{
+  return m_ssid;
+}
+
+Mac48Address
+QstaWifiMac::GetBssid () const
+{
+  return m_low->GetBssid ();
+}
+
+void
+QstaWifiMac::SetAddress (Mac48Address address)
+{
+  NS_LOG_FUNCTION (this << address);
+  m_low->SetAddress (address);
+}
+
+void
+QstaWifiMac::SetSsid (Ssid ssid)
+{
+  NS_LOG_FUNCTION (this << ssid);
+  m_ssid = ssid;
+}
+
+void
+QstaWifiMac::SetMaxMissedBeacons (uint32_t missed)
+{
+  NS_LOG_FUNCTION (this << missed);
+  m_maxMissedBeacons = missed;
+}
+
+void
+QstaWifiMac::SetProbeRequestTimeout (Time timeout)
+{
+  NS_LOG_FUNCTION (this << timeout);
+  m_probeRequestTimeout = timeout;
+}
+
+void
+QstaWifiMac::SetAssocRequestTimeout (Time timeout)
+{
+  NS_LOG_FUNCTION (this << timeout);
+  m_assocRequestTimeout = timeout;
+}
+
+void
+QstaWifiMac::StartActiveAssociation (void)
+{
+  NS_LOG_FUNCTION (this);
+  TryToEnsureAssociated ();
+}
+
+Mac48Address
+QstaWifiMac::GetBroadcastBssid (void)
+{
+  return Mac48Address::GetBroadcast ();
+}
+
+void 
+QstaWifiMac::SetBssid (Mac48Address bssid)
+{
+  NS_LOG_FUNCTION (this << bssid);
+  m_low->SetBssid (bssid);
+}
+
+void
+QstaWifiMac::SetActiveProbing (bool enable)
+{
+  NS_LOG_FUNCTION (this << enable);
+  if (enable)
+    {
+      TryToEnsureAssociated ();
+    }
+  else
+    {
+      m_probeRequestEvent.Cancel ();
+    }
+}
+
+void
+QstaWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to)
+{
+  NS_LOG_FUNCTION (this << packet << from << to);
+  m_forwardUp (packet, from, to);
+}
+
+void
+QstaWifiMac::SendProbeRequest (void)
+{
+  NS_LOG_FUNCTION (this);
+  WifiMacHeader hdr;
+  hdr.SetProbeReq ();
+  hdr.SetAddr1 (GetBroadcastBssid ());
+  hdr.SetAddr2 (GetAddress ());
+  hdr.SetAddr3 (GetBroadcastBssid ());
+  hdr.SetDsNotFrom ();
+  hdr.SetDsNotTo ();
+  Ptr<Packet> packet = Create<Packet> ();
+  MgtProbeRequestHeader probe;
+  probe.SetSsid (GetSsid ());
+  probe.SetSupportedRates (GetSupportedRates ());
+  packet->AddHeader (probe);
+
+  /* Which is correct queue for management frames ? */
+  m_queues[AC_VO]->Queue (packet, hdr);
+
+  m_probeRequestEvent = Simulator::Schedule (m_probeRequestTimeout,
+                                             &QstaWifiMac::ProbeRequestTimeout, this);
+}
+
+void
+QstaWifiMac::SendAssociationRequest (void)
+{
+  NS_LOG_FUNCTION (this << GetBssid ());
+  WifiMacHeader hdr;
+  hdr.SetAssocReq ();
+  hdr.SetAddr1 (GetBssid ());
+  hdr.SetAddr2 (GetAddress ());
+  hdr.SetAddr3 (GetBssid ());
+  hdr.SetDsNotFrom ();
+  hdr.SetDsNotTo ();
+  Ptr<Packet> packet = Create<Packet> ();
+  MgtAssocRequestHeader assoc;
+  assoc.SetSsid (GetSsid ());
+  assoc.SetSupportedRates (GetSupportedRates ());
+  packet->AddHeader (assoc);
+  
+  /* Which is correct queue for management frames ? */
+  m_queues[AC_VO]->Queue (packet, hdr);
+
+  m_assocRequestEvent = Simulator::Schedule (m_assocRequestTimeout,
+                                             &QstaWifiMac::AssocRequestTimeout, this);
+}
+
+void
+QstaWifiMac::TryToEnsureAssociated (void)
+{
+  NS_LOG_FUNCTION (this);
+  switch (m_state) {
+  case ASSOCIATED:
+    return;
+    break;
+  case WAIT_PROBE_RESP:
+    /* we have sent a probe request earlier so we
+       do not need to re-send a probe request immediately.
+       We just need to wait until probe-request-timeout
+       or until we get a probe response
+     */
+    break;
+  case BEACON_MISSED:
+    /* we were associated but we missed a bunch of beacons
+     * so we should assume we are not associated anymore.
+     * We try to initiate a probe request now.
+     */
+    m_linkDown ();
+    m_state = WAIT_PROBE_RESP;
+    SendProbeRequest ();
+    break;
+  case WAIT_ASSOC_RESP:
+    /* we have sent an assoc request so we do not need to
+       re-send an assoc request right now. We just need to
+       wait until either assoc-request-timeout or until
+       we get an assoc response.
+     */
+    break;
+  case REFUSED:
+    /* we have sent an assoc request and received a negative
+       assoc resp. We wait until someone restarts an 
+       association with a given ssid.
+     */
+    break;
+  }
+}
+
+void
+QstaWifiMac::AssocRequestTimeout (void)
+{
+  NS_LOG_FUNCTION (this);
+  m_state = WAIT_ASSOC_RESP;
+  SendAssociationRequest ();
+}
+
+void
+QstaWifiMac::ProbeRequestTimeout (void)
+{
+  NS_LOG_FUNCTION (this);
+  m_state = WAIT_PROBE_RESP;
+  SendProbeRequest ();
+}
+
+void
+QstaWifiMac::MissedBeacons (void)
+{
+  NS_LOG_FUNCTION (this);
+  if (m_beaconWatchdogEnd > Simulator::Now ())
+    {
+      m_beaconWatchdog = Simulator::Schedule (m_beaconWatchdogEnd - Simulator::Now (),
+                                              &QstaWifiMac::MissedBeacons, this);
+      return;
+    }
+  NS_LOG_DEBUG ("beacon missed");
+  m_state = BEACON_MISSED;
+  TryToEnsureAssociated ();
+}
+
+void
+QstaWifiMac::RestartBeaconWatchdog (Time delay)
+{
+  NS_LOG_FUNCTION (this << delay);
+  m_beaconWatchdogEnd = std::max (Simulator::Now () + delay, m_beaconWatchdogEnd);
+  if (Simulator::GetDelayLeft (m_beaconWatchdog) < delay &&
+                               m_beaconWatchdog.IsExpired ())
+    {
+      NS_LOG_DEBUG ("really restart watchdog.");
+      m_beaconWatchdog = Simulator::Schedule (delay, &QstaWifiMac::MissedBeacons, this);
+    }
+}
+
+bool
+QstaWifiMac::IsAssociated ()
+{
+  return (m_state == ASSOCIATED)?true:false;
+}
+
+void
+QstaWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
+{
+  NS_LOG_FUNCTION (this << packet << to);
+  if (!IsAssociated ()) 
+    {
+      TryToEnsureAssociated ();
+      return;
+    }
+  WifiMacHeader hdr;
+
+  hdr.SetType (WIFI_MAC_QOSDATA);
+  hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
+  hdr.SetQosNoAmsdu ();
+  hdr.SetQosNoEosp ();
+  /* Transmission of multiple frames in the same 
+     Txop is not supported for now */
+  hdr.SetQosTxopLimit (0);
+
+  hdr.SetAddr1 (GetBssid ());
+  hdr.SetAddr2 (m_low->GetAddress ());
+  hdr.SetAddr3 (to);
+  hdr.SetDsNotFrom ();
+  hdr.SetDsTo ();
+  
+  uint8_t tid = QosUtilsGetTidForPacket (packet);
+  if (tid < 8)
+    {
+      hdr.SetQosTid (tid);
+      AccessClass ac = QosUtilsMapTidToAc (tid);
+      m_queues[ac]->Queue (packet, hdr);
+    }
+  else
+    {
+      //packet is considerated belonging to BestEffort Access Class (AC_BE)
+      hdr.SetQosTid (0);
+      m_queues[AC_BE]->Queue (packet, hdr);
+    }
+}
+
+bool
+QstaWifiMac::SupportsSendFrom (void) const
+{
+  return true;
+}
+
+void
+QstaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
+{
+  NS_LOG_FUNCTION (this);
+  NS_ASSERT (!hdr->IsCtl ());
+  if (hdr->GetAddr1 () != GetAddress () &&
+      !hdr->GetAddr1 ().IsBroadcast ())
+    {
+      NS_LOG_LOGIC ("packet is not for us");
+    }
+  else if (hdr->IsData ())
+    {
+      if (!IsAssociated ())
+        { 
+          NS_LOG_LOGIC ("Received data frame while not associated: ignore");
+          return;
+        }
+      if (!(hdr->IsFromDs () && !hdr->IsToDs ()))
+        {
+          NS_LOG_LOGIC ("Received data frame not from the DS: ignore");
+          return;
+        }
+      if (hdr->GetAddr2 () != GetBssid ())
+        {
+          NS_LOG_LOGIC ("Received data frame not from the BSS we are associated with: ignore");
+          return;
+        }
+      if (hdr->GetAddr3 () != GetAddress ())
+        {
+          if (hdr->IsQosData ())
+            {
+              if (hdr->IsQosAmsdu ())
+                {
+                  NS_ASSERT (hdr->GetAddr3 () == GetBssid ());
+                  DeaggregateAmsduAndForward (packet, hdr);
+                  packet = 0;
+                }
+              else
+                {
+                  ForwardUp (packet, hdr->GetAddr3 (), hdr->GetAddr1 ());
+                }
+            }
+          else
+            {
+              ForwardUp (packet, hdr->GetAddr3 (), hdr->GetAddr1 ());
+            }
+        }
+    }
+  else if (hdr->IsBeacon ()) 
+    {
+      MgtBeaconHeader beacon;
+      packet->RemoveHeader (beacon);
+      bool goodBeacon = false;
+      if (GetSsid ().IsBroadcast () ||
+          beacon.GetSsid ().IsEqual (GetSsid ()))
+        {
+          goodBeacon = true;
+        }
+      if (IsAssociated () && hdr->GetAddr3 () != GetBssid ())
+        {
+          goodBeacon = false;
+        }
+      if (goodBeacon)
+        {
+          Time delay = MicroSeconds (beacon.GetBeaconIntervalUs () * m_maxMissedBeacons);
+          RestartBeaconWatchdog (delay);
+          SetBssid (hdr->GetAddr3 ());
+        }
+      if (goodBeacon && m_state == BEACON_MISSED) 
+        {
+          m_state = WAIT_ASSOC_RESP;
+          SendAssociationRequest ();
+        }
+    }
+  else if (hdr->IsProbeResp ()) 
+    {
+      if (m_state == WAIT_PROBE_RESP) 
+        {
+          MgtProbeResponseHeader probeResp;
+          packet->RemoveHeader (probeResp);
+          if (!probeResp.GetSsid ().IsEqual (GetSsid ()))
+            {
+              //not a probe resp for our ssid.
+              return;
+            }
+          SetBssid (hdr->GetAddr3 ());
+          Time delay = MicroSeconds (probeResp.GetBeaconIntervalUs () * m_maxMissedBeacons);
+          RestartBeaconWatchdog (delay);
+          if (m_probeRequestEvent.IsRunning ()) 
+            {
+              m_probeRequestEvent.Cancel ();
+            }
+          m_state = WAIT_ASSOC_RESP;
+          SendAssociationRequest ();
+        }
+    } 
+  else if (hdr->IsAssocResp ()) 
+    {
+      if (m_state == WAIT_ASSOC_RESP) 
+        {
+          MgtAssocResponseHeader assocResp;
+          packet->RemoveHeader (assocResp);
+          if (m_assocRequestEvent.IsRunning ()) 
+            {
+              m_assocRequestEvent.Cancel ();
+            }
+          if (assocResp.GetStatusCode ().IsSuccess ()) 
+            {
+              m_state = ASSOCIATED;
+              NS_LOG_DEBUG ("assoc completed"); 
+              SupportedRates rates = assocResp.GetSupportedRates ();
+              WifiRemoteStation *ap = m_stationManager->Lookup (hdr->GetAddr2 ());
+              for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
+                {
+                  WifiMode mode = m_phy->GetMode (i);
+                  if (rates.IsSupportedRate (mode.GetDataRate ()))
+                    {
+                      ap->AddSupportedMode (mode);
+                      if (rates.IsBasicRate (mode.GetDataRate ()))
+                        {
+                          m_stationManager->AddBasicMode (mode);
+                        }
+                    }
+                }
+              if (!m_linkUp.IsNull ())
+                {
+                  m_linkUp ();
+                }
+            } 
+          else 
+            {
+              NS_LOG_DEBUG ("assoc refused");
+              m_state = REFUSED;
+            }
+        }
+    }
+}
+
+SupportedRates
+QstaWifiMac::GetSupportedRates (void) const
+{
+  SupportedRates rates;
+  for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
+    {
+      WifiMode mode = m_phy->GetMode (i);
+      rates.AddSupportedRate (mode.GetDataRate ());
+    }
+  return rates;
+}
+
+void
+QstaWifiMac::DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, WifiMacHeader const *hdr)
+{
+  DeaggregatedMsdus packets = MsduAggregator::Deaggregate (aggregatedPacket);
+  for (DeaggregatedMsdusCI i = packets.begin (); i != packets.end (); ++i)
+    {
+      ForwardUp ((*i).first, (*i).second.GetSourceAddr (),
+                 (*i).second.GetDestinationAddr ());
+    }
+}
+
+Ptr<EdcaTxopN>
+QstaWifiMac::GetVOQueue (void) const
+{
+  return m_voEdca;
+}
+
+Ptr<EdcaTxopN>
+QstaWifiMac::GetVIQueue (void) const
+{
+  return m_viEdca;
+}
+
+Ptr<EdcaTxopN>
+QstaWifiMac::GetBEQueue (void) const
+{
+  return m_beEdca;
+}
+
+Ptr<EdcaTxopN>
+QstaWifiMac::GetBKQueue (void) const
+{
+  return m_bkEdca;
+}
+
+void
+QstaWifiMac::SetVOQueue (Ptr<EdcaTxopN> voQueue)
+{
+  m_voEdca = voQueue;
+  m_queues.insert (std::make_pair(AC_VO, m_voEdca));
+  m_queues[AC_VO]->SetLow (m_low);
+  m_queues[AC_VO]->SetManager (m_dcfManager);
+  m_queues[AC_VO]->SetTypeOfStation (STA);
+  m_queues[AC_VO]->SetTxMiddle (m_txMiddle);
+}
+
+void
+QstaWifiMac::SetVIQueue (Ptr<EdcaTxopN> viQueue)
+{
+  m_viEdca = viQueue;
+  m_queues.insert (std::make_pair(AC_VI, m_viEdca));
+  m_queues[AC_VI]->SetLow (m_low);
+  m_queues[AC_VI]->SetManager (m_dcfManager);
+  m_queues[AC_VI]->SetTypeOfStation (STA);
+  m_queues[AC_VI]->SetTxMiddle (m_txMiddle);
+}
+
+void
+QstaWifiMac::SetBEQueue (Ptr<EdcaTxopN> beQueue)
+{
+  m_beEdca = beQueue;
+  m_queues.insert (std::make_pair(AC_BE, m_beEdca));
+  m_queues[AC_BE]->SetLow (m_low);
+  m_queues[AC_BE]->SetManager (m_dcfManager);
+  m_queues[AC_BE]->SetTypeOfStation (STA);
+  m_queues[AC_BE]->SetTxMiddle (m_txMiddle);
+}
+
+void
+QstaWifiMac::SetBKQueue (Ptr<EdcaTxopN> bkQueue)
+{
+  m_bkEdca = bkQueue;
+  m_queues.insert (std::make_pair(AC_BK, m_bkEdca));
+  m_queues[AC_BK]->SetLow (m_low);
+  m_queues[AC_BK]->SetManager (m_dcfManager);
+  m_queues[AC_BK]->SetTypeOfStation (STA);
+  m_queues[AC_BK]->SetTxMiddle (m_txMiddle);
+}
+
+}  //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/qsta-wifi-mac.h	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,171 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006, 2009 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#ifndef QSTA_WIFI_MAC_H
+#define QSTA_WIFI_MAC_H
+
+#include "ns3/callback.h"
+#include "ns3/packet.h"
+#include "ns3/event-id.h"
+
+#include "wifi-mac.h"
+#include "supported-rates.h"
+#include "qos-utils.h"
+
+#include <string>
+#include <vector>
+#include <list>
+#include <map>
+
+namespace ns3  {
+
+class DcfManager;
+class EdcaTxopN;
+class MacRxMiddle;
+class MacTxMiddle;
+class MacLow;
+class WifiMacHeader;
+class AmsduSubframeHeader;
+class MsduAggregator;
+
+class QstaWifiMac : public WifiMac
+{
+public:
+  static TypeId GetTypeId (void);
+  
+  QstaWifiMac ();
+  virtual ~QstaWifiMac ();
+  
+  // inherited from WifiMac.
+  virtual void SetSlot (Time slotTime);
+  virtual void SetSifs (Time sifs);
+  virtual void SetEifsNoDifs (Time eifsNoDifs);
+  virtual void SetAckTimeout (Time ackTimeout);
+  virtual void SetCtsTimeout (Time ctsTimeout);
+  virtual void SetPifs (Time pifs);
+  virtual Time GetSlot (void) const;
+  virtual Time GetSifs (void) const;
+  virtual Time GetEifsNoDifs (void) const;
+  virtual Time GetAckTimeout (void) const;
+  virtual Time GetCtsTimeout (void) const;
+  virtual Time GetPifs (void) const;
+  virtual void SetWifiPhy (Ptr<WifiPhy> phy);
+  virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
+  virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from){};
+  virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
+  virtual bool SupportsSendFrom (void) const;
+  virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback);
+  virtual void SetLinkUpCallback (Callback<void> linkUp);
+  virtual void SetLinkDownCallback (Callback<void> linkDown);
+  virtual Mac48Address GetAddress (void) const;
+  virtual Ssid GetSsid (void) const;
+  virtual void SetAddress (Mac48Address address);
+  virtual void SetSsid (Ssid ssid);
+  virtual Mac48Address GetBssid (void) const;
+
+  void SetMaxMissedBeacons (uint32_t missed);
+  void SetProbeRequestTimeout (Time timeout);
+  void SetAssocRequestTimeout (Time timeout);
+  void StartActiveAssociation (void);
+
+private:
+  void SetBssid (Mac48Address bssid);
+  Mac48Address GetBroadcastBssid (void);
+  void Receive (Ptr<Packet> p, const WifiMacHeader *hdr);
+  void ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to);
+  void SetActiveProbing (bool enable);
+  bool GetActiveProbing (void) const;
+  void MissedBeacons (void);
+  SupportedRates GetSupportedRates (void) const;
+  void RestartBeaconWatchdog (Time delay);
+  void AssocRequestTimeout (void);
+  void ProbeRequestTimeout (void);
+  void SendAssociationRequest (void);
+  void SendProbeRequest (void);
+  void TryToEnsureAssociated (void);
+  bool IsAssociated (void);
+  virtual void DoDispose (void);
+
+ /**
+  * When an A-MSDU is received, is deaggregated by this method and all extracted packets are
+  * forwarded up.
+  */
+  void DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, WifiMacHeader const *hdr);
+
+  Ptr<EdcaTxopN> GetVOQueue (void) const;
+  Ptr<EdcaTxopN> GetVIQueue (void) const;
+  Ptr<EdcaTxopN> GetBEQueue (void) const;
+  Ptr<EdcaTxopN> GetBKQueue (void) const;
+
+  void SetVOQueue (Ptr<EdcaTxopN> voQueue);
+  void SetVIQueue (Ptr<EdcaTxopN> viQueue);
+  void SetBEQueue (Ptr<EdcaTxopN> beQueue);
+  void SetBKQueue (Ptr<EdcaTxopN> bkQueue);
+
+  QstaWifiMac &operator = (const QstaWifiMac &);
+  QstaWifiMac (const QstaWifiMac &);
+
+  typedef std::map<AccessClass, Ptr<EdcaTxopN> > Queues;
+  typedef std::list<std::pair<Ptr<Packet>, AmsduSubframeHeader> > DeaggregatedMsdus;
+  typedef std::list<std::pair<Ptr<Packet>, AmsduSubframeHeader> >::const_iterator DeaggregatedMsdusCI;
+    
+  enum {
+    ASSOCIATED,
+    WAIT_PROBE_RESP,
+    WAIT_ASSOC_RESP,
+    BEACON_MISSED,
+    REFUSED
+  } m_state;
+
+  /*Next map is used only for an esay access to a specific queue*/
+  Queues m_queues;
+  Ptr<EdcaTxopN> m_voEdca;
+  Ptr<EdcaTxopN> m_viEdca;
+  Ptr<EdcaTxopN> m_beEdca;
+  Ptr<EdcaTxopN> m_bkEdca;
+
+  Ptr<MacLow> m_low;
+  Ptr<WifiPhy> m_phy;
+  Ptr<WifiRemoteStationManager> m_stationManager;
+  DcfManager *m_dcfManager;
+  MacRxMiddle *m_rxMiddle;
+  MacTxMiddle *m_txMiddle;
+  Ssid m_ssid;
+  
+  Callback<void, Ptr<Packet>, Mac48Address, Mac48Address> m_forwardUp;
+  Callback<void> m_linkUp;
+  Callback<void> m_linkDown;
+  
+  Time m_probeRequestTimeout;
+  Time m_assocRequestTimeout;
+  EventId m_probeRequestEvent;
+  EventId m_assocRequestEvent;
+  
+  Time m_beaconWatchdogEnd;
+  EventId m_beaconWatchdog;
+  
+  uint32_t m_maxMissedBeacons;
+  Time m_eifsNoDifs;
+};
+
+}  //namespace ns3
+
+#endif /* QSTA_WIFI_MAC_H */
--- a/src/devices/wifi/wifi-mac-header.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/wifi-mac-header.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -1,6 +1,7 @@
 /* -*-  Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2006 INRIA
+ * Copyright (c) 2006, 2009 INRIA
+ * 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
@@ -16,6 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
  */
 #include "ns3/assert.h"
 #include "ns3/address-utils.h"
@@ -43,7 +45,8 @@
   : m_ctrlPwrMgt (0),
     m_ctrlMoreData (0),
     m_ctrlWep (0),
-    m_ctrlOrder (1)
+    m_ctrlOrder (1),
+    m_amsduPresent (0)
 {}
 WifiMacHeader::~WifiMacHeader ()
 {}
@@ -141,7 +144,7 @@
 }
 
 void 
-WifiMacHeader::SetType (enum WifiMacType_e type)
+WifiMacHeader::SetType (enum WifiMacType type)
 {
   switch (type) {
   case WIFI_MAC_CTL_BACKREQ:
@@ -323,6 +326,39 @@
 {
   m_qosTid = tid;
 }
+void WifiMacHeader::SetQosEosp ()
+{
+  m_qosEosp = 1;
+}
+void WifiMacHeader::SetQosNoEosp ()
+{
+  m_qosEosp = 0;
+}
+void WifiMacHeader::SetQosAckPolicy (enum QosAckPolicy policy)
+{
+  switch (policy) {
+  case NORMAL_ACK :
+    m_qosAckPolicy = 0;
+    break;
+  case NO_ACK :
+    m_qosAckPolicy = 1;
+    break;
+  case NO_EXPLICIT_ACK :
+    m_qosAckPolicy = 2;
+    break;
+  case BLOCK_ACK :
+    m_qosAckPolicy = 3;
+    break;
+  }
+}
+void WifiMacHeader::SetQosAmsdu (void)
+{
+  m_amsduPresent = 1;
+}
+void WifiMacHeader::SetQosNoAmsdu (void)
+{
+  m_amsduPresent = 0;
+}
 void WifiMacHeader::SetQosTxopLimit (uint8_t txop)
 {
   m_qosStuff = txop;
@@ -348,7 +384,8 @@
 {
   return m_addr4;
 }
-enum WifiMacType_e 
+
+enum WifiMacType 
 WifiMacHeader::GetType (void) const
 {
   switch (m_ctrlType) {
@@ -468,7 +505,7 @@
   }
   // NOTREACHED
   NS_ASSERT (false);
-  return (enum WifiMacType_e)-1;
+  return (enum WifiMacType)-1;
 }
 bool 
 WifiMacHeader::IsFromDs (void) const
@@ -651,12 +688,46 @@
   NS_ASSERT (IsQosData ());
   return (m_qosAckPolicy == 0)?true:false;
 }
+bool
+WifiMacHeader::IsQosEosp (void) const
+{
+  NS_ASSERT (IsQosData ());
+  return (m_qosEosp == 1)?true:false;
+}
+bool
+WifiMacHeader::IsQosAmsdu (void) const
+{
+  NS_ASSERT (IsQosData ());
+  return (m_amsduPresent == 1)?true:false;
+}
 uint8_t
 WifiMacHeader::GetQosTid (void) const
 {
   NS_ASSERT (IsQosData ());
   return m_qosTid;
 }
+enum WifiMacHeader::QosAckPolicy
+WifiMacHeader::GetQosAckPolicy (void) const
+{
+  switch (m_qosAckPolicy) {
+  case 0 :
+    return NORMAL_ACK;
+    break;
+  case 1 :
+    return NO_ACK;
+    break;
+  case 2 :
+    return NO_EXPLICIT_ACK;
+    break;
+  case 3 :
+    return BLOCK_ACK;
+    break;
+  }
+  // NOTREACHED
+  NS_ASSERT (false);
+  return (enum QosAckPolicy)-1;
+}
+
 uint8_t 
 WifiMacHeader::GetQosTxopLimit (void) const
 {
@@ -687,6 +758,7 @@
   val |= m_qosTid;
   val |= m_qosEosp << 4;
   val |= m_qosAckPolicy << 5;
+  val |= m_amsduPresent << 7;
   val |= m_qosStuff << 8;
   return val;
 }
@@ -716,6 +788,7 @@
   m_qosTid = qos & 0x000f;
   m_qosEosp = (qos >> 4) & 0x0001;
   m_qosAckPolicy = (qos >> 5) & 0x0003;
+  m_amsduPresent = (qos >> 7) & 0x0001;
   m_qosStuff = (qos >> 8) & 0x00ff;
 }
 
@@ -816,6 +889,7 @@
     ;
   return tid;
 }
+
 TypeId 
 WifiMacHeader::GetInstanceTypeId (void) const
 {
--- a/src/devices/wifi/wifi-mac-header.h	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/wifi-mac-header.h	Wed Apr 29 18:26:25 2009 +0400
@@ -1,6 +1,7 @@
 /* -*-  Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2006 INRIA
+ * Copyright (c) 2006, 2009 INRIA
+ * 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
@@ -16,6 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
  */
 #ifndef WIFI_MAC_HEADER_H
 #define WIFI_MAC_HEADER_H
@@ -27,7 +29,7 @@
 
 namespace ns3 {
 
-enum WifiMacType_e {
+enum WifiMacType {
   WIFI_MAC_CTL_RTS = 0,
   WIFI_MAC_CTL_CTS,
   WIFI_MAC_CTL_ACK,
@@ -68,6 +70,19 @@
 class WifiMacHeader : public Header 
 {
 public:
+  enum QosAckPolicy {
+    NORMAL_ACK = 0,
+    NO_ACK = 1,
+    NO_EXPLICIT_ACK = 2,
+    BLOCK_ACK = 3,
+  };
+  
+  enum AddressType {
+    ADDR1,	
+    ADDR2,
+    ADDR3,
+    ADDR4
+  };
 
   WifiMacHeader ();
   ~WifiMacHeader ();
@@ -96,7 +111,7 @@
   void SetAddr2 (Mac48Address address);
   void SetAddr3 (Mac48Address address);
   void SetAddr4 (Mac48Address address);
-  void SetType (enum WifiMacType_e type);
+  void SetType (enum WifiMacType type);
   void SetRawDuration (uint16_t duration);
   void SetDuration (Time duration);
   void SetId (uint16_t id);
@@ -107,13 +122,19 @@
   void SetRetry (void);
   void SetNoRetry (void);
   void SetQosTid (uint8_t tid);
+  void SetQosEosp ();
+  void SetQosNoEosp ();
+  void SetQosAckPolicy (enum QosAckPolicy);
+  void SetQosAmsdu (void);
+  void SetQosNoAmsdu (void);
   void SetQosTxopLimit (uint8_t txop);
+ 
 
   Mac48Address GetAddr1 (void) const;
   Mac48Address GetAddr2 (void) const;
   Mac48Address GetAddr3 (void) const;
   Mac48Address GetAddr4 (void) const;
-  enum WifiMacType_e GetType (void) const;
+  enum WifiMacType GetType (void) const;
   bool IsFromDs (void) const;
   bool IsToDs (void) const;
   bool IsData (void) const;
@@ -146,7 +167,10 @@
   bool IsQosBlockAck (void) const;
   bool IsQosNoAck (void) const;
   bool IsQosAck (void) const;
+  bool IsQosEosp (void) const;
+  bool IsQosAmsdu (void) const;
   uint8_t GetQosTid (void) const;
+  enum QosAckPolicy GetQosAckPolicy (void) const;
   uint8_t GetQosTxopLimit (void) const;
 
   uint32_t GetSize (void) const;
@@ -181,6 +205,7 @@
   uint8_t m_qosTid;
   uint8_t m_qosEosp;
   uint8_t m_qosAckPolicy;
+  uint8_t m_amsduPresent;
   uint16_t m_qosStuff;
 };
 
--- a/src/devices/wifi/wifi-mac-queue.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/wifi-mac-queue.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -1,6 +1,7 @@
 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2005 INRIA
+ * Copyright (c) 2005, 2009 INRIA
+ * 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 
@@ -16,8 +17,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
  */
-
 #include "ns3/simulator.h"
 #include "ns3/packet.h"
 #include "ns3/uinteger.h"
@@ -30,7 +31,6 @@
 
 NS_OBJECT_ENSURE_REGISTERED (WifiMacQueue);
 
-
 WifiMacQueue::Item::Item (Ptr<const Packet> packet, 
                           WifiMacHeader const &hdr, 
                           Time tstamp)
@@ -69,16 +69,19 @@
 {
   m_maxSize = maxSize;
 }
-void 
+
+void
 WifiMacQueue::SetMaxDelay (Time delay)
 {
   m_maxDelay = delay;
 }
+
 uint32_t 
 WifiMacQueue::GetMaxSize (void) const
 {
   return m_maxSize;
 }
+
 Time 
 WifiMacQueue::GetMaxDelay (void) const
 {
@@ -97,6 +100,7 @@
   m_queue.push_back (Item (packet, hdr, now));
   m_size++;
 }
+
 void
 WifiMacQueue::Cleanup (void)
 {
@@ -136,6 +140,72 @@
   return 0;
 }
 
+Ptr<const Packet>
+WifiMacQueue::Peek (WifiMacHeader *hdr)
+{
+  Cleanup ();
+  if (!m_queue.empty ()) 
+    {
+      Item i = m_queue.front ();
+      *hdr = i.hdr;
+      return i.packet;
+    }
+  return 0;
+}
+
+Ptr<const Packet>
+WifiMacQueue::DequeueByTidAndAddress (WifiMacHeader *hdr, uint8_t tid, 
+                                      WifiMacHeader::AddressType type, Mac48Address dest)
+{
+  Cleanup ();
+  Ptr<const Packet> packet = 0;
+  if (!m_queue.empty ())
+    {
+      PacketQueueI it;
+      NS_ASSERT (type <= 4);
+      for (it = m_queue.begin (); it != m_queue.end (); ++it)
+        {
+          if (it->hdr.IsQosData ())
+            {
+              if (GetAddressForPacket (type, it) == dest &&
+                  it->hdr.GetQosTid () == tid)
+                {
+                  packet = it->packet;
+                  *hdr = it->hdr;
+                  m_queue.erase (it);
+                  m_size--;
+                  break;
+                }
+            }
+        }
+    }
+  return packet;
+}
+
+Ptr<const Packet>
+WifiMacQueue::PeekByTidAndAddress (WifiMacHeader *hdr, uint8_t tid, 
+                                   WifiMacHeader::AddressType type, Mac48Address dest)
+{
+  Cleanup ();
+  if (!m_queue.empty ())
+    {
+      PacketQueueI it;
+      NS_ASSERT (type <= 4);
+      for (it = m_queue.begin (); it != m_queue.end (); ++it)
+        {
+          if (it->hdr.IsQosData ())
+            {
+              if (GetAddressForPacket (type, it) == dest &&
+                  it->hdr.GetQosTid () == tid)
+                {
+                  *hdr = it->hdr;
+                  return it->packet;
+                }
+            }
+        }
+    }
+  return 0;
+}
 
 bool
 WifiMacQueue::IsEmpty (void)
@@ -144,7 +214,6 @@
   return m_queue.empty ();
 }
 
-
 uint32_t
 WifiMacQueue::GetSize (void)
 {
@@ -158,4 +227,37 @@
   m_size = 0;
 }
 
+Mac48Address
+WifiMacQueue::GetAddressForPacket (uint8_t type, PacketQueueI it)
+{
+  if (type == WifiMacHeader::ADDR1)
+    {
+      return it->hdr.GetAddr1 ();
+    }
+  if (type == WifiMacHeader::ADDR2)
+    {
+      return it->hdr.GetAddr2 ();
+    }
+  if (type == WifiMacHeader::ADDR3)
+    {
+      return it->hdr.GetAddr3 ();
+    }
+  return 0;
+}
+
+bool
+WifiMacQueue::Remove (Ptr<const Packet> packet)
+{
+  PacketQueueI it = m_queue.begin ();
+  for (; it != m_queue.end (); it++)
+    {
+      if (it->packet == packet)
+        {
+          m_queue.erase (it);
+          return true;
+        }
+    }
+  return false;
+}
+
 } // namespace ns3
--- a/src/devices/wifi/wifi-mac-queue.h	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/wifi-mac-queue.h	Wed Apr 29 18:26:25 2009 +0400
@@ -1,6 +1,7 @@
 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2005 INRIA
+ * Copyright (c) 2005, 2009 INRIA
+ * 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 
@@ -16,11 +17,12 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
  */
 #ifndef WIFI_MAC_QUEUE_H
 #define WIFI_MAC_QUEUE_H
 
-#include <deque>
+#include <list>
 #include <utility>
 #include "ns3/packet.h"
 #include "ns3/nstime.h"
@@ -60,25 +62,60 @@
 
   void Enqueue (Ptr<const Packet> packet, WifiMacHeader const &hdr);
   Ptr<const Packet> Dequeue (WifiMacHeader *hdr);
-
+  Ptr<const Packet> Peek (WifiMacHeader *hdr);
+  /**
+   * Searchs and returns, if is present in this queue, first packet having 
+   * address indicated by <i>type</i> equals to <i>addr</i>, and tid 
+   * equals to <i>tid</i>. This method removes the packet from this queue. 
+   * Is typically used by ns3::EdcaTxopN in order to perform correct MSDU 
+   * aggregation (A-MSDU).
+   */
+  Ptr<const Packet> DequeueByTidAndAddress (WifiMacHeader *hdr,
+                                            uint8_t tid, 
+                                            WifiMacHeader::AddressType type,
+                                            Mac48Address addr);
+  /**
+   * Searchs and returns, if is present in this queue, first packet having
+   * address indicated by <i>type</i> equals to <i>addr</i>, and tid 
+   * equals to <i>tid</i>. This method doesn't remove the packet from this queue.
+   * Is typically used by ns3::EdcaTxopN in order to perform correct MSDU
+   * aggregation (A-MSDU).
+   */
+  Ptr<const Packet> PeekByTidAndAddress (WifiMacHeader *hdr,
+                                         uint8_t tid,
+                                         WifiMacHeader::AddressType type,
+                                         Mac48Address addr);
+  /**
+   * If exists, removes <i>packet</i> from queue and returns true. Otherwise it
+   * takes no effects and return false. Deletion of the packet is
+   * performed in linear time (O(n)).  
+   */
+  bool Remove (Ptr<const Packet> packet);
+  
   void Flush (void);
 
   bool IsEmpty (void);
   uint32_t GetSize (void);
 
 private:
+  struct Item;
+  
+  typedef std::list<struct Item> PacketQueue;
+  typedef std::list<struct Item>::reverse_iterator PacketQueueRI;
+  typedef std::list<struct Item>::iterator PacketQueueI;
+  
   void Cleanup (void);
+  Mac48Address GetAddressForPacket (uint8_t type, PacketQueueI);
+  
   struct Item {
     Item (Ptr<const Packet> packet, 
-          WifiMacHeader const&hdr, 
+          WifiMacHeader const &hdr, 
           Time tstamp);
     Ptr<const Packet> packet;
     WifiMacHeader hdr;
     Time tstamp;
   };
-  typedef std::deque<struct Item> PacketQueue;
-  typedef std::deque<struct Item>::reverse_iterator PacketQueueRI;
-  typedef std::deque<struct Item>::iterator PacketQueueI;
+
   PacketQueue m_queue;
   WifiMacParameters *m_parameters;
   uint32_t m_size;
@@ -88,5 +125,4 @@
 
 } // namespace ns3
 
-
 #endif /* WIFI_MAC_QUEUE_H */
--- a/src/devices/wifi/wifi-test.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/wifi-test.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -33,6 +33,8 @@
 #include "ns3/simulator.h"
 #include "ns3/test.h"
 #include "ns3/object-factory.h"
+#include "dca-txop.h"
+#include "ns3/pointer.h"
 
 namespace ns3 {
 
@@ -69,7 +71,9 @@
   Ptr<Node> node = CreateObject<Node> ();
   Ptr<WifiNetDevice> dev = CreateObject<WifiNetDevice> ();
 
+  Ptr<DcaTxop> queue = CreateObject<DcaTxop> ();
   Ptr<WifiMac> mac = m_mac.Create<WifiMac> ();
+  mac->SetAttribute("DcaTxop", PointerValue (queue));
   Ptr<ConstantPositionMobilityModel> mobility = CreateObject<ConstantPositionMobilityModel> ();
   Ptr<YansWifiPhy> phy = CreateObject<YansWifiPhy> ();
   Ptr<ErrorRateModel> error = CreateObject<YansErrorRateModel> ();
--- a/src/devices/wifi/wifi.h	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/wifi.h	Wed Apr 29 18:26:25 2009 +0400
@@ -11,30 +11,61 @@
  *
  * The current implementation provides roughly 4 levels of models:
  *   - the PHY layer models
- *   - the so-called MAC low models: they implement DCF
+ *   - the so-called MAC low models: they implement DCF and EDCAF
  *   - the so-called MAC high models: they implement the MAC-level
  *     beacon generation, probing, and association state machines.
  *   - a set of Rate control algorithms used by the MAC low models.
  *
- * We have today 3 MAC high models:
+ * We have today 6 MAC high models, 3 for non QoS MACs and 3 for QoS MACs.
+ *   
+ *  a)non QoS MACs:
+ *
  *   - a simple adhoc state machine which does not perform any
  *     kind of beacon generation, probing, or association. This
- *     state machine is implemented by the ns3::AdhocWifiNetDevice
- *     and ns3::MacHighAdhoc classes.
+ *     state machine is implemented by the ns3::AdhocWifiMac class.
  *   - an active probing and association state machine which handles
  *     automatic re-association whenever too many beacons are missed
- *     is implemented by the ns3::NqstaWifiNetDevice and 
- *     ns3::MacHighNqsta classes.
+ *     is implemented by the ns3::NqstaWifiMac class.
  *   - an access point which generates periodic beacons, and which
  *     accepts every attempt to associate. This AP state machine
- *     is implemented by the ns3::NqapWifiNetDevice and 
- *     ns3::MacHighNqap classes.
+ *     is implemented by the ns3::NqapWifiMac class.
+ *
+ *  b)QoS MACs:
+ *
+ *   - like above but these MAC models are also able to manage QoS traffic.
+ *     These MAC layers are implemented respectively by ns3::QadhocWifiMac,
+ *     ns3::QstaWifiMac and ns3::QapWifiMac classes.
+ *     With these MAC models is possible to work with traffic belonging to 
+ *     four different access classes: AC_VO for voice traffic, AC_VI for video
+ *     traffic, AC_BE for best-effort traffic and AC_BK for background traffic.
+ *     In order to determine MSDU's access class, every packet forwarded down
+ *     to these MAC layers should be marked using ns3::QosTag in order to set
+ *     a TID (traffic id) for that packet otherwise it will be considered
+ *     belonging to AC_BE access class. 
+ *     How TIDs are mapped to access classes are shown in the table below. 
+ *   
+ *     TID-AccessClass mapping:
+ *     
+ *      TID  | Access class
+ *      --------------------
+ *       7   |    AC_VO      ^
+ *       6   |    AC_VO      |
+ *       5   |    AC_VI      |
+ *       4   |    AC_VI      |
+ *       3   |    AC_BE      | priority
+ *       0   |    AC_BE      |  
+ *       2   |    AC_BK      |
+ *       1   |    AC_BK      |
+ *     
  *
  * The MAC low layer is split in 3 components:
  *   - ns3::MacLow which takes care of RTS/CTS/DATA/ACK transactions.
  *   - ns3::DcfManager and ns3::DcfState which implements the DCF function.
- *   - ns3::DcaTxop which handles the packet queue, packet fragmentation,
- *     and packet retransmissions if they are needed.
+ *   - ns3::DcaTxop or ns3::EdcaTxopN which handle the packet queue, packet 
+ *     fragmentation, and packet retransmissions if they are needed.
+ *     ns3::DcaTxop object is used by non QoS high MACs. ns3::EdcaTxopN is
+ *     used by Qos high MACs and performs also QoS operations like 802.11n MSDU
+ *     aggregation.
  *
  * The PHY layer implements a single model in the ns3::WifiPhy class: the
  * physical layer model implemented there is described fully in a paper titled
--- a/src/devices/wifi/wscript	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/devices/wifi/wscript	Wed Apr 29 18:26:25 2009 +0400
@@ -46,6 +46,15 @@
         'cara-wifi-manager.cc',
         'constant-rate-wifi-manager.cc',
         'wifi-test.cc',
+        'qos-tag.cc',
+        'qos-utils.cc',
+        'qadhoc-wifi-mac.cc',
+        'qap-wifi-mac.cc',
+        'qsta-wifi-mac.cc',
+        'edca-txop-n.cc',
+        'msdu-aggregator.cc',
+        'amsdu-subframe-header.cc',
+        'msdu-standard-aggregator.cc',
         ]
     headers = bld.new_task_gen('ns3header')
     headers.module = 'wifi'
@@ -58,7 +67,7 @@
         'wifi-mode.h',
         'ssid.h',
         'wifi-preamble.h',
-        'wifi-phy-standard.h',
+	'wifi-phy-standard.h',
         'yans-wifi-phy.h',
         'yans-wifi-channel.h',
         'wifi-phy.h',
@@ -77,17 +86,18 @@
         'nqap-wifi-mac.h',
         'wifi-phy.h',
         'supported-rates.h',
-        'mgt-headers.h',
-        'status-code.h',
-        'capability-information.h',
         'error-rate-model.h',
         'yans-error-rate-model.h',
-# Need this for module devices/mesh
         'dca-txop.h',
         'wifi-mac-header.h',
-        'dcf-manager.h',
-        'mac-rx-middle.h',
-        'mac-low.h',
+        'qadhoc-wifi-mac.h',
+        'qap-wifi-mac.h',
+        'qsta-wifi-mac.h',
+        'qos-utils.h',
+        'edca-txop-n.h',
+        'msdu-aggregator.h',
+        'amsdu-subframe-header.h',
+        'qos-tag.h',
         ]
 
     obj = bld.create_ns3_program('wifi-phy-test',
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/nqos-wifi-mac-helper.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,86 @@
+/* -*-  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 "nqos-wifi-mac-helper.h"
+#include "ns3/wifi-mac.h"
+#include "ns3/pointer.h"
+#include "ns3/dca-txop.h"
+
+namespace ns3 {
+
+NqosWifiMacHelper::NqosWifiMacHelper ()
+{
+  m_queue.SetTypeId ("ns3::DcaTxop");
+}
+
+NqosWifiMacHelper::~NqosWifiMacHelper ()
+{}
+
+NqosWifiMacHelper
+NqosWifiMacHelper::Default (void)
+{
+  NqosWifiMacHelper helper;
+  helper.SetType ("ns3::AdhocWifiMac");
+  return helper;
+}
+
+void
+NqosWifiMacHelper::SetType (std::string type,
+                            std::string n0, const AttributeValue &v0,
+                            std::string n1, const AttributeValue &v1,
+                            std::string n2, const AttributeValue &v2,
+                            std::string n3, const AttributeValue &v3,
+                            std::string n4, const AttributeValue &v4,
+                            std::string n5, const AttributeValue &v5,
+                            std::string n6, const AttributeValue &v6,
+                            std::string n7, const AttributeValue &v7)
+{
+  m_mac.SetTypeId (type);
+  m_mac.Set (n0, v0);
+  m_mac.Set (n1, v1);
+  m_mac.Set (n2, v2);
+  m_mac.Set (n3, v3);
+  m_mac.Set (n4, v4);
+  m_mac.Set (n5, v5);
+  m_mac.Set (n6, v6);
+  m_mac.Set (n7, v7);
+}
+
+void
+NqosWifiMacHelper::SetDcaParameters (std::string n0, const AttributeValue &v0,
+                                     std::string n1, const AttributeValue &v1,
+                                     std::string n2, const AttributeValue &v2,
+                                     std::string n3, const AttributeValue &v3)
+{
+  m_queue.Set (n0, v0);
+  m_queue.Set (n1, v1);
+  m_queue.Set (n2, v2);
+  m_queue.Set (n3, v3);
+}
+
+Ptr<WifiMac>
+NqosWifiMacHelper::Create (void) const
+{
+  Ptr<WifiMac> mac = m_mac.Create<WifiMac> ();
+  Ptr<DcaTxop> queue = m_queue.Create<DcaTxop> ();
+  mac->SetAttribute ("DcaTxop", PointerValue (queue));
+  return mac;
+}
+
+} //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/nqos-wifi-mac-helper.h	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,95 @@
+/* -*-  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>
+ */
+#ifndef NQOS_WIFI_MAC_HELPER_H
+#define NQOS_WIFI_MAC_HELPER_H
+
+#include "wifi-helper.h"
+
+namespace ns3 {
+
+class NqosWifiMacHelper : public WifiMacHelper
+{
+public:
+  NqosWifiMacHelper ();
+  virtual ~NqosWifiMacHelper ();
+  /**
+   * Create a mac helper in a default working state.
+   */
+  static NqosWifiMacHelper Default (void);
+  /**
+   * \param type the type of ns3::WifiMac to create.
+   * \param n0 the name of the attribute to set
+   * \param v0 the value of the attribute to set
+   * \param n1 the name of the attribute to set
+   * \param v1 the value of the attribute to set
+   * \param n2 the name of the attribute to set
+   * \param v2 the value of the attribute to set
+   * \param n3 the name of the attribute to set
+   * \param v3 the value of the attribute to set
+   * \param n4 the name of the attribute to set
+   * \param v4 the value of the attribute to set
+   * \param n5 the name of the attribute to set
+   * \param v5 the value of the attribute to set
+   * \param n6 the name of the attribute to set
+   * \param v6 the value of the attribute to set
+   * \param n7 the name of the attribute to set
+   * \param v7 the value of the attribute to set
+   *
+   * All the attributes specified in this method should exist
+   * in the requested mac.
+   */
+  void SetType (std::string type,
+                std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+                std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+                std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+                std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+                std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+                std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+                std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+                std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+  /**
+   * \param type the type of ns3::WifiMac to create.
+   * \param n0 the name of the attribute to set
+   * \param v0 the value of the attribute to set
+   * \param n1 the name of the attribute to set
+   * \param v1 the value of the attribute to set
+   * \param n2 the name of the attribute to set
+   * \param v2 the value of the attribute to set
+   * \param n3 the name of the attribute to set
+   */
+  void SetDcaParameters (std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+                         std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+                         std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+                         std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue ());
+private:
+  /**
+   * \returns a newly-created MAC object.
+   *
+   * This method implements the pure virtual method defined in \ref ns3::WifiMacHelper.
+   */
+  virtual Ptr<WifiMac> Create (void) const;
+
+  ObjectFactory m_mac;
+  ObjectFactory m_queue;
+};
+
+} //namespace ns3
+
+#endif /* NQOS_WIFI_MAC_HELPER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/qos-wifi-mac-helper.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,191 @@
+/* -*-  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 "qos-wifi-mac-helper.h"
+#include "ns3/msdu-aggregator.h"
+#include "ns3/wifi-mac.h"
+#include "ns3/edca-txop-n.h"
+#include "ns3/pointer.h"
+#include "ns3/uinteger.h"
+
+namespace ns3 {
+
+QosWifiMacHelper::QosWifiMacHelper ()
+{
+  m_aggregators.insert (std::make_pair (AC_VO, ObjectFactory ()));
+  m_aggregators.insert (std::make_pair (AC_VI, ObjectFactory ()));
+  m_aggregators.insert (std::make_pair (AC_BE, ObjectFactory ()));
+  m_aggregators.insert (std::make_pair (AC_BK, ObjectFactory ()));
+
+  m_queues.insert (std::make_pair (AC_VO, ObjectFactory ()));
+  m_queues.insert (std::make_pair (AC_VI, ObjectFactory ()));
+  m_queues.insert (std::make_pair (AC_BE, ObjectFactory ()));
+  m_queues.insert (std::make_pair (AC_BK, ObjectFactory ()));
+
+  m_queues[AC_VO].SetTypeId ("ns3::EdcaTxopN");
+  m_queues[AC_VI].SetTypeId ("ns3::EdcaTxopN");
+  m_queues[AC_BE].SetTypeId ("ns3::EdcaTxopN");
+  m_queues[AC_BK].SetTypeId ("ns3::EdcaTxopN");
+}
+
+QosWifiMacHelper::~QosWifiMacHelper ()
+{}
+
+QosWifiMacHelper
+QosWifiMacHelper::Default (void)
+{
+  QosWifiMacHelper helper;
+  helper.SetType ("ns3::QstaWifiMac");
+  /* For more details about this default parameters see IEE802.11 section 7.3.2.29 */
+  helper.SetEdcaParametersForAc (AC_VO,"MinCw", UintegerValue (3),
+                                       "MaxCw", UintegerValue (7),
+                                       "Aifsn", UintegerValue (2));
+  helper.SetEdcaParametersForAc (AC_VI,"MinCw", UintegerValue (7),
+                                       "MaxCw", UintegerValue (15),
+                                       "Aifsn", UintegerValue (2));
+  helper.SetEdcaParametersForAc (AC_BE,"MinCw", UintegerValue (15),
+                                       "MaxCw", UintegerValue (1023),
+                                       "Aifsn", UintegerValue (3));
+  helper.SetEdcaParametersForAc (AC_BK,"MinCw", UintegerValue (15),
+                                       "MaxCw", UintegerValue (1023),
+                                       "Aifsn", UintegerValue (7));
+  return helper;
+}
+
+void
+QosWifiMacHelper::SetType (std::string type,
+                           std::string n0, const AttributeValue &v0,
+                           std::string n1, const AttributeValue &v1,
+                           std::string n2, const AttributeValue &v2,
+                           std::string n3, const AttributeValue &v3,
+                           std::string n4, const AttributeValue &v4,
+                           std::string n5, const AttributeValue &v5,
+                           std::string n6, const AttributeValue &v6,
+                           std::string n7, const AttributeValue &v7)
+{
+  m_mac.SetTypeId (type);
+  m_mac.Set (n0, v0);
+  m_mac.Set (n1, v1);
+  m_mac.Set (n2, v2);
+  m_mac.Set (n3, v3);
+  m_mac.Set (n4, v4);
+  m_mac.Set (n5, v5);
+  m_mac.Set (n6, v6);
+  m_mac.Set (n7, v7);
+}
+
+void
+QosWifiMacHelper::SetMsduAggregatorForAc (AccessClass accessClass, std::string type,
+                                          std::string n0, const AttributeValue &v0,
+                                          std::string n1, const AttributeValue &v1,
+                                          std::string n2, const AttributeValue &v2,
+                                          std::string n3, const AttributeValue &v3)
+{
+  std::map<AccessClass, ObjectFactory>::iterator it;
+  it = m_aggregators.find (accessClass);
+  if (it != m_aggregators.end ())
+    {
+      it->second.SetTypeId (type);
+      it->second.Set (n0, v0);
+      it->second.Set (n1, v1);
+      it->second.Set (n2, v2);
+      it->second.Set (n3, v3);
+    }
+}
+
+void
+QosWifiMacHelper::SetEdcaParametersForAc (AccessClass accessClass,
+                                          std::string n0, const AttributeValue &v0,
+                                          std::string n1, const AttributeValue &v1,
+                                          std::string n2, const AttributeValue &v2,
+                                          std::string n3, const AttributeValue &v3)
+{
+  std::map<AccessClass, ObjectFactory>::iterator it;
+  it = m_queues.find (accessClass);
+  if (it != m_queues.end ())
+    {
+      it->second.Set (n0, v0);
+      it->second.Set (n1, v1);
+      it->second.Set (n2, v2);
+      it->second.Set (n3, v3);
+    }
+}
+
+Ptr<WifiMac>
+QosWifiMacHelper::Create (void) const
+{
+  Ptr<WifiMac> mac = m_mac.Create<WifiMac> ();
+  
+  Ptr<EdcaTxopN> edcaQueue;
+  Ptr<MsduAggregator> aggregator;
+  std::map<AccessClass, ObjectFactory>::const_iterator itQueue;
+  std::map<AccessClass, ObjectFactory>::const_iterator itAggr;
+
+  /* Setting for VO queue */
+  itQueue = m_queues.find (AC_VO);
+  itAggr = m_aggregators.find (AC_VO);
+
+  edcaQueue = itQueue->second.Create<EdcaTxopN> ();
+  if (itAggr->second.GetTypeId ().GetUid () != 0)
+    {
+      aggregator = itAggr->second.Create<MsduAggregator> ();
+      edcaQueue->SetMsduAggregator (aggregator);
+    }
+  mac->SetAttribute ("VO_EdcaTxopN", PointerValue (edcaQueue));
+
+  /* Setting for VI queue */
+  itQueue = m_queues.find (AC_VI);
+  itAggr = m_aggregators.find (AC_VI);
+
+  edcaQueue = itQueue->second.Create<EdcaTxopN> ();
+  if (itAggr->second.GetTypeId ().GetUid () != 0)
+    {
+      aggregator = itAggr->second.Create<MsduAggregator> ();
+      edcaQueue->SetMsduAggregator (aggregator);
+    }
+  mac->SetAttribute ("VI_EdcaTxopN", PointerValue (edcaQueue));
+
+  /* Setting for BE queue */
+  itQueue = m_queues.find (AC_BE);
+  itAggr = m_aggregators.find (AC_BE);
+
+  edcaQueue = itQueue->second.Create<EdcaTxopN> ();
+  if (itAggr->second.GetTypeId ().GetUid () != 0)
+    {
+      aggregator = itAggr->second.Create<MsduAggregator> ();
+      edcaQueue->SetMsduAggregator (aggregator);
+    }
+  mac->SetAttribute ("BE_EdcaTxopN", PointerValue (edcaQueue));
+  
+  /* Setting for BK queue */
+  itQueue = m_queues.find (AC_BK);
+  itAggr = m_aggregators.find (AC_BK);
+
+  edcaQueue = itQueue->second.Create<EdcaTxopN> ();
+  if (itAggr->second.GetTypeId ().GetUid () != 0)
+    {
+      aggregator = itAggr->second.Create<MsduAggregator> ();
+      edcaQueue->SetMsduAggregator (aggregator);
+    }
+  mac->SetAttribute ("BK_EdcaTxopN", PointerValue (edcaQueue));
+
+  return mac;
+}
+
+} //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/qos-wifi-mac-helper.h	Wed Apr 29 18:26:25 2009 +0400
@@ -0,0 +1,123 @@
+/* -*-  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>
+ */
+#ifndef QOS_WIFI_MAC_HELPER_H
+#define QOS_WIFI_MAC_HELPER_H
+
+#include "wifi-helper.h"
+#include "ns3/qos-utils.h"
+
+#include <map>
+
+namespace ns3 {
+
+class QosWifiMacHelper : public WifiMacHelper
+{
+public:
+  QosWifiMacHelper ();
+  virtual ~QosWifiMacHelper ();
+  /**
+   * Create a mac helper in a default working state.
+   */
+  static QosWifiMacHelper Default (void);
+  /**
+   * \param type the type of ns3::WifiMac to create.
+   * \param n0 the name of the attribute to set
+   * \param v0 the value of the attribute to set
+   * \param n1 the name of the attribute to set
+   * \param v1 the value of the attribute to set
+   * \param n2 the name of the attribute to set
+   * \param v2 the value of the attribute to set
+   * \param n3 the name of the attribute to set
+   * \param v3 the value of the attribute to set
+   * \param n4 the name of the attribute to set
+   * \param v4 the value of the attribute to set
+   * \param n5 the name of the attribute to set
+   * \param v5 the value of the attribute to set
+   * \param n6 the name of the attribute to set
+   * \param v6 the value of the attribute to set
+   * \param n7 the name of the attribute to set
+   * \param v7 the value of the attribute to set
+   *
+   * All the attributes specified in this method should exist
+   * in the requested mac.
+   */
+  void SetType (std::string type,
+                std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+                std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+                std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+                std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+                std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+                std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+                std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+                std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+  /**
+   * \param accessClass access class for which we are setting aggregator. Possibilities
+   *  are: AC_BK, AC_BE, AC_VI, AC_VO.
+   * \param aggregatorType type of aggregator.
+   * \param n0 the name of the attribute to set
+   * \param v0 the value of the attribute to set
+   * \param n1 the name of the attribute to set
+   * \param v1 the value of the attribute to set
+   * \param n2 the name of the attribute to set
+   * \param v2 the value of the attribute to set
+   * \param n3 the name of the attribute to set
+   * \param v3 the value of the attribute to set
+   *
+   * All the attributes specified in this method should exist
+   * in the requested aggregator.
+   */
+  void SetMsduAggregatorForAc (AccessClass accessClass, std::string type,
+                               std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+                               std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+                               std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+                               std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue ());
+  /**
+   * \param accessClass access class for which we are setting edca params. Possibilities
+   *  are: AC_BK, AC_BE, AC_VI, AC_VO.
+   * \param n0 the name of the attribute to set
+   * \param v0 the value of the attribute to set
+   * \param n1 the name of the attribute to set
+   * \param v1 the value of the attribute to set
+   * \param n2 the name of the attribute to set
+   * \param v2 the value of the attribute to set
+   * \param n3 the name of the attribute to set
+   * \param v3 the value of the attribute to set
+   */
+  void SetEdcaParametersForAc (AccessClass accessClass,
+                               std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+                               std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+                               std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+                               std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue ());
+private:
+  /**
+   * \returns a newly-created MAC object.
+   *
+   * This method implements the pure virtual method defined in \ref ns3::WifiMacHelper.
+   */
+  virtual Ptr<WifiMac> Create (void) const;
+
+  ObjectFactory m_mac;
+  std::map<AccessClass, ObjectFactory> m_queues;
+  std::map<AccessClass, ObjectFactory> m_aggregators;
+};
+
+} //namespace ns3
+
+#endif /* QOS_WIFI_MAC_HELPER_H */
--- a/src/helper/wifi-helper.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/helper/wifi-helper.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -1,6 +1,7 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
  * Copyright (c) 2008 INRIA
+ * 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
@@ -16,6 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
  */
 #include "wifi-helper.h"
 #include "ns3/wifi-net-device.h"
@@ -40,6 +42,8 @@
 WifiPhyHelper::~WifiPhyHelper ()
 {}
 
+WifiMacHelper::~WifiMacHelper ()
+{}
 
 WifiHelper::WifiHelper ()
 {}
@@ -49,7 +53,6 @@
 {
   WifiHelper helper;
   helper.SetRemoteStationManager ("ns3::ArfWifiManager");
-  helper.SetMac ("ns3::AdhocWifiMac");
   return helper;
 }
 
@@ -76,31 +79,9 @@
   m_stationManager.Set (n7, v7);
 }
 
-void 
-WifiHelper::SetMac (std::string type,
-                    std::string n0, const AttributeValue &v0,
-                    std::string n1, const AttributeValue &v1,
-                    std::string n2, const AttributeValue &v2,
-                    std::string n3, const AttributeValue &v3,
-                    std::string n4, const AttributeValue &v4,
-                    std::string n5, const AttributeValue &v5,
-                    std::string n6, const AttributeValue &v6,
-                    std::string n7, const AttributeValue &v7)
-{
-  m_mac = ObjectFactory ();
-  m_mac.SetTypeId (type);
-  m_mac.Set (n0, v0);
-  m_mac.Set (n1, v1);
-  m_mac.Set (n2, v2);
-  m_mac.Set (n3, v3);
-  m_mac.Set (n4, v4);
-  m_mac.Set (n5, v5);
-  m_mac.Set (n6, v6);
-  m_mac.Set (n7, v7);
-}
-
 NetDeviceContainer 
-WifiHelper::Install (const WifiPhyHelper &phyHelper, NodeContainer c) const
+WifiHelper::Install (const WifiPhyHelper &phyHelper,
+                     const WifiMacHelper &macHelper, NodeContainer c) const
 {
   NetDeviceContainer devices;
   for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
@@ -108,7 +89,7 @@
       Ptr<Node> node = *i;
       Ptr<WifiNetDevice> device = CreateObject<WifiNetDevice> ();
       Ptr<WifiRemoteStationManager> manager = m_stationManager.Create<WifiRemoteStationManager> ();
-      Ptr<WifiMac> mac = m_mac.Create<WifiMac> ();
+      Ptr<WifiMac> mac = macHelper.Create ();
       Ptr<WifiPhy> phy = phyHelper.Create (node, device);
       mac->SetAddress (Mac48Address::Allocate ());
       device->SetMac (mac);
@@ -120,16 +101,20 @@
     }
   return devices;
 }
+
 NetDeviceContainer 
-WifiHelper::Install (const WifiPhyHelper &phy, Ptr<Node> node) const
+WifiHelper::Install (const WifiPhyHelper &phy,
+                     const WifiMacHelper &mac, Ptr<Node> node) const
 {
-  return Install (phy, NodeContainer (node));
+  return Install (phy, mac, NodeContainer (node));
 }
+
 NetDeviceContainer 
-WifiHelper::Install (const WifiPhyHelper &phy, std::string nodeName) const
+WifiHelper::Install (const WifiPhyHelper &phy,
+                     const WifiMacHelper &mac, std::string nodeName) const
 {
   Ptr<Node> node = Names::Find<Node> (nodeName);
-  return Install (phy, NodeContainer (node));
+  return Install (phy, mac, NodeContainer (node));
 }
 
 } // namespace ns3
--- a/src/helper/wifi-helper.h	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/helper/wifi-helper.h	Wed Apr 29 18:26:25 2009 +0400
@@ -1,6 +1,7 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
  * Copyright (c) 2008 INRIA
+ * 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
@@ -16,6 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
  */
 #ifndef WIFI_HELPER_H
 #define WIFI_HELPER_H
@@ -29,6 +31,7 @@
 namespace ns3 {
 
 class WifiPhy;
+class WifiMac;
 class WifiNetDevice;
 class Node;
 
@@ -54,6 +57,25 @@
 };
 
 /**
+ * \brief create MAC objects
+ *
+ * This base class must be implemented by new MAC implementation which wish to integrate
+ * with the \ref ns3::WifiHelper class.
+ */
+class WifiMacHelper
+{
+public:
+  virtual ~WifiMacHelper ();
+  /**
+   * \returns a new MAC object.
+   *
+   * Subclasses must implement this method to allow the ns3::WifiHelper class
+   * to create MAC objects from ns3::WifiHelper::Install.
+   */
+  virtual Ptr<WifiMac> Create (void) const = 0;
+};
+
+/**
  * \brief helps to create WifiNetDevice objects
  *
  * This class can help to create a large set of similar
@@ -108,61 +130,33 @@
                                 std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
                                 std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
                                 std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
-
-  /**
-   * \param type the type of ns3::WifiMac to create.
-   * \param n0 the name of the attribute to set
-   * \param v0 the value of the attribute to set
-   * \param n1 the name of the attribute to set
-   * \param v1 the value of the attribute to set
-   * \param n2 the name of the attribute to set
-   * \param v2 the value of the attribute to set
-   * \param n3 the name of the attribute to set
-   * \param v3 the value of the attribute to set
-   * \param n4 the name of the attribute to set
-   * \param v4 the value of the attribute to set
-   * \param n5 the name of the attribute to set
-   * \param v5 the value of the attribute to set
-   * \param n6 the name of the attribute to set
-   * \param v6 the value of the attribute to set
-   * \param n7 the name of the attribute to set
-   * \param v7 the value of the attribute to set
-   *
-   * All the attributes specified in this method should exist
-   * in the requested mac.
-   */
-  void SetMac (std::string type,
-               std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
-               std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
-               std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
-               std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
-               std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
-               std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
-               std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
-               std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
-
   /**
    * \param phy the PHY helper to create PHY objects
+   * \param mac the MAC helper to create MAC objects
    * \param c the set of nodes on which a wifi device must be created
    * \returns a device container which contains all the devices created by this method.
    */
-  NetDeviceContainer Install (const WifiPhyHelper &phy, NodeContainer c) const;
+  NetDeviceContainer Install (const WifiPhyHelper &phy,
+                              const WifiMacHelper &mac, NodeContainer c) const;
   /**
    * \param phy the PHY helper to create PHY objects
+   * \param mac the MAC helper to create MAC objects
    * \param node the node on which a wifi device must be created
    * \returns a device container which contains all the devices created by this method.
    */
-  NetDeviceContainer Install (const WifiPhyHelper &phy, Ptr<Node> node) const;
+  NetDeviceContainer Install (const WifiPhyHelper &phy,
+                              const WifiMacHelper &mac, Ptr<Node> node) const;
   /**
    * \param phy the PHY helper to create PHY objects
+   * \param mac the MAC helper to create MAC objects
    * \param nodeName the name of node on which a wifi device must be created
    * \returns a device container which contains all the devices created by this method.
    */
-  NetDeviceContainer Install (const WifiPhyHelper &phy, std::string nodeName) const;
+  NetDeviceContainer Install (const WifiPhyHelper &phy,
+                              const WifiMacHelper &mac, std::string nodeName) const;
 
 private:
   ObjectFactory m_stationManager;
-  ObjectFactory m_mac;
 };
 
 } // namespace ns3
--- a/src/helper/wscript	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/helper/wscript	Wed Apr 29 18:26:25 2009 +0400
@@ -23,6 +23,8 @@
         'bridge-helper.cc',
         'yans-wifi-helper.cc',
         'v4ping-helper.cc',
+        'nqos-wifi-mac-helper.cc',
+        'qos-wifi-mac-helper.cc',
         ]
 
     headers = bld.new_task_gen('ns3header')
@@ -48,6 +50,8 @@
         'bridge-helper.h',
         'yans-wifi-helper.h',
         'v4ping-helper.h',
+        'nqos-wifi-mac-helper.h',
+        'qos-wifi-mac-helper.h',
         ]
 
     env = bld.env_of_name('default')
--- a/src/node/mac48-address.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/node/mac48-address.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -142,18 +142,6 @@
   return *this == GetBroadcast ();
 }
 bool 
-Mac48Address::IsMulticast (void) const
-{
-  uint8_t mcBuf[6];
-  CopyTo (mcBuf);
-  mcBuf[3] &= 0x80;
-  mcBuf[4] = 0;
-  mcBuf[5] = 0;
-  Mac48Address prefix;
-  prefix.CopyFrom (mcBuf);
-  return prefix == Mac48Address::GetMulticastPrefix ();
-}
-bool 
 Mac48Address::IsGroup (void) const
 {
   return (m_address[0] & 0x01) == 0x01;
--- a/src/node/mac48-address.h	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/node/mac48-address.h	Wed Apr 29 18:26:25 2009 +0400
@@ -90,10 +90,7 @@
    * \returns true if this is a broadcast address, false otherwise.
    */
   bool IsBroadcast (void) const;
-  /**
-   * \returns true if this is a multicast address, false otherwise.
-   */
-  bool IsMulticast (void) const;
+  
   /**
    * \returns true if the group bit is set, false otherwise.
    */
--- a/src/node/net-device.h	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/node/net-device.h	Wed Apr 29 18:26:25 2009 +0400
@@ -60,6 +60,17 @@
  * If you want to write a new MAC layer, you need to subclass
  * this base class and implement your own version of the
  * NetDevice::SendTo method.
+ *
+ * This class was designed to hide as many MAC-level details as 
+ * possible from the perspective of layer 3 to allow a single layer 3
+ * to work with any kind of MAC layer. Specifically, this class 
+ * encapsulates the specific format of MAC addresses used by a
+ * device such that the layer 3 does not need any modification
+ * to handle new address formats. This means obviously that the
+ * NetDevice class must know about the address format of all potential 
+ * layer 3 protocols through its GetMulticast methods: the current
+ * API has been optimized to make it easy to add new MAC protocols,
+ * not to add new layer 3 protocols.
  */
 class NetDevice : public Object
 {
--- a/src/node/simple-net-device.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/node/simple-net-device.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -54,7 +54,7 @@
     {
       packetType = NetDevice::PACKET_HOST;
     }
-  else if (to.IsMulticast ())
+  else if (to.IsGroup ())
     {
       packetType = NetDevice::PACKET_MULTICAST;
     }
--- a/src/simulator/high-precision-128.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/simulator/high-precision-128.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -19,6 +19,7 @@
  */
 #include "high-precision-128.h"
 #include "ns3/test.h"
+#include "ns3/fatal-error.h"
 #include <math.h>
 #include <iostream>
 
@@ -151,10 +152,69 @@
 {
   EnsureSlow ();
   const_cast<HighPrecision &> (o).EnsureSlow ();
-  cairo_int128_t other = _cairo_int128_rsa (o.m_slowValue, 64);
-  m_slowValue = _cairo_int128_mul (m_slowValue, other);
+  //use the 128 bits multiplication
+  m_slowValue = Mul128(m_slowValue,o.m_slowValue);
   return false;
 }
+/**
+ * this function multiplies two 128 bits fractions considering
+ * the high 64 bits as the integer part and the low 64 bits
+ * as the fractional part. It takes into account the sign
+ * of the operands to produce a signed 128 bits result.
+ */
+cairo_int128_t
+HighPrecision::Mul128(cairo_int128_t a, cairo_int128_t b )
+{
+  //Implement the 128 bits multiplication
+  cairo_int128_t result;
+  cairo_uint128_t hiPart,loPart,midPart;
+  bool resultNegative = false, signA = false,signB = false;
+
+  //take the sign of the operands
+  signA = _cairo_int128_negative (a);
+  signB = _cairo_int128_negative (b);
+  //the result is negative only if one of the operand is negative
+  if ((signA == true && signB == false) ||(signA == false && signB == true))
+    {
+  	 resultNegative = true;
+    }
+  //now take the absolute part to make sure that the resulting operands are positive
+  if (signA == true)
+  {
+	  a = _cairo_int128_negate (a);
+  }
+  if (signB == true)
+  {
+  	  b = _cairo_int128_negate (b);
+  }
+
+  //Multiplying (a.h 2^64 + a.l) x (b.h 2^64 + b.l) =
+  //			2^128 a.h b.h + 2^64*(a.h b.l+b.h a.l) + a.l b.l
+  //get the low part a.l b.l
+  //multiply the fractional part
+  loPart = _cairo_uint64x64_128_mul (a.lo, b.lo);
+  //compute the middle part 2^64*(a.h b.l+b.h a.l)
+  midPart = _cairo_uint128_add(_cairo_uint64x64_128_mul(a.lo, b.hi),
+		  _cairo_uint64x64_128_mul(a.hi, b.lo)) ;
+  //truncate the low part
+  result.lo = _cairo_uint64_add(loPart.hi,midPart.lo);
+  //compute the high part 2^128 a.h b.h
+  hiPart = _cairo_uint64x64_128_mul (a.hi, b.hi);
+  //truncate the high part and only use the low part
+  result.hi = _cairo_uint64_add(hiPart.lo,midPart.hi);
+  //if the high part is not zero, put a warning
+  if (hiPart.hi !=0)
+  {
+	  NS_FATAL_ERROR("High precision 128 bits multiplication error: multiplication overflow.");
+  }
+  //add the sign to the result
+  if (resultNegative)
+  {
+	 result = _cairo_int128_negate (result);
+  }
+  return result;
+}
+
 bool 
 HighPrecision::Div (HighPrecision const &o)
 {
@@ -351,6 +411,22 @@
   a = HighPrecision (0.1);
   a.Div (HighPrecision (1.25));
   NS_TEST_ASSERT_EQUAL (a.GetDouble (), 0.08);
+  //test the multiplication
+  a = HighPrecision (0.5);
+  a.Mul(HighPrecision (5));
+  NS_TEST_ASSERT_EQUAL (a.GetDouble (), 2.5);
+  //test the sign of multiplication, first operand negative
+  a = HighPrecision (-0.5);
+  a.Mul(HighPrecision (5));
+  NS_TEST_ASSERT_EQUAL (a.GetDouble (), -2.5);
+  //two negative
+  a = HighPrecision (-0.5);
+  a.Mul(HighPrecision (-5));
+  NS_TEST_ASSERT_EQUAL (a.GetDouble (), 2.5);
+  //second operand negative
+  a = HighPrecision (0.5);
+  a.Mul(HighPrecision (-5));
+  NS_TEST_ASSERT_EQUAL (a.GetDouble (), -2.5);
 
 
   return result;
--- a/src/simulator/high-precision-128.h	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/simulator/high-precision-128.h	Wed Apr 29 18:26:25 2009 +0400
@@ -47,6 +47,26 @@
  * If you want to monitor the efficiency of this strategy, you can 
  * enable the macro HP128INC below and call the HighPrecision::PrintStats
  * method at the end of the simulation.
+ *
+ *  Explanation of Slow and Fast values:
+ *
+ * HighPrecision class create a fastValue and a slowValue depending on the
+ * input number. If the input is an integer with 0 fractional part, it will
+ * use the fastValue which will contain the integer in a 64 bits format. If
+ * it has a fractional part, the slowValue will be used. It is represented
+ * simply as a high part slowValue.hi which will contain the integer part
+ * and the fractional part slowValue.lo which will contain the factional
+ * part as an integer (obtained by multiplying the fractional part by 2^64).
+ *
+ * Explanation of Slow and Fast operations:
+ *
+ * If both operands are fastValues, we will perform fast operations, i-e
+ * simply using integer operations. If we have though one of the value is
+ * slowValue we need to convert the fastValue into a slow one. It is simply
+ * obtained by putting the slowValue.lo = 0 and slowValue.hi = fastValue.
+ * After that we apply the slow operation which will be a 128 bits operation
+ * with two 128 bits operands.
+ *
  */
 
 
@@ -85,6 +105,7 @@
   bool SlowSub (HighPrecision const &o);
   bool SlowMul (HighPrecision const &o);
   int SlowCompare (HighPrecision const &o) const;
+  cairo_uint128_t  Mul128(cairo_uint128_t , cairo_uint128_t );
   inline void EnsureSlow (void);
 
   static const double MAX_64;
--- a/src/simulator/time.cc	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/simulator/time.cc	Wed Apr 29 18:26:25 2009 +0400
@@ -572,11 +572,11 @@
 
   Time t4;
   t4 = Seconds (10.0) * Scalar (1.5);
-  CheckTimeSec("old 11", t4.GetSeconds(), 10, ok);
+  CheckTimeSec("old 11", t4.GetSeconds(), 15, ok);
 
   Time t5;
   t5 = NanoSeconds (10) * Scalar (1.5);
-  CheckTime("old 12", t5.GetNanoSeconds(), 10, ok);
+  CheckTime("old 12", t5.GetNanoSeconds(), 15, ok);
 
   t4 = Seconds (10.0) * Scalar (15) / Scalar (10);
   CheckTimeSec("old 13", t4.GetSeconds(), 15, ok);
--- a/src/wscript	Wed Apr 29 18:59:48 2009 +0400
+++ b/src/wscript	Wed Apr 29 18:26:25 2009 +0400
@@ -74,7 +74,16 @@
     module.target = module.name
     module.add_objects = ['ns3-' + dep for dep in dependencies]
     module.module_deps = list(dependencies)
-    module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS'])
+    if not module.env['ENABLE_STATIC_NS3']:
+        module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS'])
+    elif module.env['CXX_NAME'] == 'gcc' and \
+            os.uname()[4] == 'x86_64' and \
+            module.env['ENABLE_PYTHON_BINDINGS']:
+        # enable that flag for static builds only on x86-64 platforms
+        # when gcc is present and only when we want python bindings
+        # (it's more efficient to not use this option if we can avoid it)
+        module.env.append_value('CXXFLAGS', '-mcmodel=large')
+        
     module.env.append_value('CXXDEFINES', "NS3_MODULE_COMPILATION")
     return module
 
--- a/utils/lcov/geninfo	Wed Apr 29 18:59:48 2009 +0400
+++ b/utils/lcov/geninfo	Wed Apr 29 18:26:25 2009 +0400
@@ -1292,6 +1292,12 @@
 				{
 					next;
 				}
+				#added because if length is zero the following
+				#reading process will die, it will read garbage
+				if ($length == 0)
+				{
+					next;
+				}
 				($blocks, $filename) =
 					read_gcno_string(*INPUT, $endianness);
 				if ($blocks > 1)
--- a/wscript	Wed Apr 29 18:59:48 2009 +0400
+++ b/wscript	Wed Apr 29 18:26:25 2009 +0400
@@ -156,6 +156,10 @@
                    help=('Path to the regression reference traces directory'),
                    default=None,
                    dest='regression_traces', type="string")
+    opt.add_option('--enable-static',
+                   help=('Compile NS-3 statically: works only on linux, without python'),
+                   dest='enable_static', action='store_true',
+                   default=False)
 
     # options provided in a script in a subdirectory named "src"
     opt.sub_options('src')
@@ -286,6 +290,10 @@
 
     conf.find_program('valgrind', var='VALGRIND')
 
+    if Options.options.enable_static and \
+            env['PLATFORM'].startswith('linux'):
+        conf.env['ENABLE_STATIC_NS3'] = Options.options.enable_static
+
     # Write a summary of optional features status
     print "---- Summary of optional NS-3 features:"
     for (name, caption, was_enabled, reason_not_enabled) in conf.env['NS3_OPTIONAL_FEATURES']:
@@ -351,6 +359,10 @@
     program.target = program.name
     program.uselib_local = 'ns3'
     program.ns3_module_dependencies = ['ns3-'+dep for dep in dependencies]
+    if program.env['ENABLE_STATIC_NS3']:
+        program.env.append_value('LINKFLAGS', '-Wl,--whole-archive,-Bstatic')
+        program.env.append_value('LINKFLAGS', '-lns3')
+        program.env.append_value('LINKFLAGS', '-Wl,-Bdynamic,--no-whole-archive')
     return program
 
 def add_scratch_programs(bld):
@@ -434,7 +446,11 @@
                 bld.all_task_gen.remove(obj)
 
     ## Create a single ns3 library containing all enabled modules
-    lib = bld.new_task_gen('cxx', 'shlib')
+    if env['ENABLE_STATIC_NS3']:
+        lib = bld.new_task_gen('cxx', 'staticlib')
+    else:
+        lib = bld.new_task_gen('cxx', 'shlib')
+
     lib.name = 'ns3'
     lib.target = 'ns3'
     if env['NS3_ENABLED_MODULES']: