merge with HEAD
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Mon, 24 Nov 2008 06:36:05 +0100
changeset 3914 18ac5bec5c49
parent 3913 a9162f5e5e2e (diff)
parent 3877 5091e3a14b26 (current diff)
child 3915 c798f3d5cb2e
merge with HEAD
bindings/python/callbacks_list.py
bindings/python/ns3_module_contrib.py
bindings/python/ns3_module_core.py
bindings/python/ns3_module_helper.py
bindings/python/ns3_module_wifi.py
src/core/type-id.cc
src/devices/wifi/wifi-net-device.cc
src/devices/wifi/wifi-net-device.h
src/helper/packet-socket-helper.cc
src/helper/wifi-helper.cc
src/helper/wifi-helper.h
src/helper/wscript
src/routing/olsr/routing-table.cc
src/routing/olsr/routing-table.h
--- a/bindings/python/callbacks_list.py	Wed Nov 19 16:41:17 2008 -0800
+++ b/bindings/python/callbacks_list.py	Mon Nov 24 06:36:05 2008 +0100
@@ -8,6 +8,4 @@
     ['bool', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet const>', 'unsigned short', 'ns3::Address const&', 'ns3::Address const&', 'ns3::NetDevice::PacketType'],
     ['bool', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet const>', 'unsigned short', 'ns3::Address const&', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet const>', 'unsigned short', 'ns3::Address const&', 'ns3::Address const&', 'ns3::NetDevice::PacketType'],
-    ['void', 'ns3::Ptr<ns3::Packet>', 'double', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
-    ['void', 'ns3::Ptr<ns3::Packet>', 'double', 'ns3::WifiMode', 'ns3::WifiPreamble', 'ns3::empty', 'ns3::empty'],
 ]
--- a/bindings/python/ns3_module_contrib.py	Wed Nov 19 16:41:17 2008 -0800
+++ b/bindings/python/ns3_module_contrib.py	Mon Nov 24 06:36:05 2008 +0100
@@ -19,6 +19,8 @@
     module.add_class('GtkConfigStore')
     ## config-store.h: ns3::ConfigStore [class]
     module.add_class('ConfigStore', parent=root_module['ns3::ObjectBase'])
+    ## flow-id-tag.h: ns3::FlowIdTag [class]
+    module.add_class('FlowIdTag', parent=root_module['ns3::Tag'])
     
     ## Register a nested module for the namespace Config
     
@@ -67,6 +69,7 @@
     register_Ns3GnuplotDataset_methods(root_module, root_module['ns3::GnuplotDataset'])
     register_Ns3GtkConfigStore_methods(root_module, root_module['ns3::GtkConfigStore'])
     register_Ns3ConfigStore_methods(root_module, root_module['ns3::ConfigStore'])
+    register_Ns3FlowIdTag_methods(root_module, root_module['ns3::FlowIdTag'])
     return
 
 def register_Ns3DelayJitterEstimation_methods(root_module, cls):
@@ -182,6 +185,59 @@
                    [])
     return
 
+def register_Ns3FlowIdTag_methods(root_module, cls):
+    ## flow-id-tag.h: ns3::FlowIdTag::FlowIdTag(ns3::FlowIdTag const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::FlowIdTag const &', 'arg0')])
+    ## flow-id-tag.h: static ns3::TypeId ns3::FlowIdTag::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## flow-id-tag.h: ns3::TypeId ns3::FlowIdTag::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## flow-id-tag.h: uint32_t ns3::FlowIdTag::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## flow-id-tag.h: void ns3::FlowIdTag::Serialize(ns3::TagBuffer buf) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::TagBuffer', 'buf')], 
+                   is_const=True, is_virtual=True)
+    ## flow-id-tag.h: void ns3::FlowIdTag::Deserialize(ns3::TagBuffer buf) [member function]
+    cls.add_method('Deserialize', 
+                   'void', 
+                   [param('ns3::TagBuffer', 'buf')], 
+                   is_virtual=True)
+    ## flow-id-tag.h: void ns3::FlowIdTag::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## flow-id-tag.h: ns3::FlowIdTag::FlowIdTag() [constructor]
+    cls.add_constructor([])
+    ## flow-id-tag.h: ns3::FlowIdTag::FlowIdTag(uint32_t flowId) [constructor]
+    cls.add_constructor([param('uint32_t', 'flowId')])
+    ## flow-id-tag.h: void ns3::FlowIdTag::SetFlowId(uint32_t flowId) [member function]
+    cls.add_method('SetFlowId', 
+                   'void', 
+                   [param('uint32_t', 'flowId')])
+    ## flow-id-tag.h: uint32_t ns3::FlowIdTag::GetFlowId() const [member function]
+    cls.add_method('GetFlowId', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True)
+    ## flow-id-tag.h: static uint32_t ns3::FlowIdTag::AllocateFlowId() [member function]
+    cls.add_method('AllocateFlowId', 
+                   'uint32_t', 
+                   [], 
+                   is_static=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_core.py	Wed Nov 19 16:41:17 2008 -0800
+++ b/bindings/python/ns3_module_core.py	Mon Nov 24 06:36:05 2008 +0100
@@ -77,6 +77,8 @@
     module.add_class('AttributeInfo', outer_class=root_module['ns3::TypeId'])
     ## random-variable.h: ns3::UniformVariable [class]
     module.add_class('UniformVariable', parent=root_module['ns3::RandomVariable'])
+    ## attribute-list.h: ns3::UnsafeAttributeList [class]
+    module.add_class('UnsafeAttributeList')
     ## random-variable.h: ns3::WeibullVariable [class]
     module.add_class('WeibullVariable', parent=root_module['ns3::RandomVariable'])
     ## empty.h: ns3::empty [class]
@@ -236,6 +238,7 @@
     register_Ns3TypeId_methods(root_module, root_module['ns3::TypeId'])
     register_Ns3TypeIdAttributeInfo_methods(root_module, root_module['ns3::TypeId::AttributeInfo'])
     register_Ns3UniformVariable_methods(root_module, root_module['ns3::UniformVariable'])
+    register_Ns3UnsafeAttributeList_methods(root_module, root_module['ns3::UnsafeAttributeList'])
     register_Ns3WeibullVariable_methods(root_module, root_module['ns3::WeibullVariable'])
     register_Ns3Empty_methods(root_module, root_module['ns3::empty'])
     register_Ns3AttributeAccessor_methods(root_module, root_module['ns3::AttributeAccessor'])
@@ -537,6 +540,10 @@
     cls.add_method('Set', 
                    'void', 
                    [param('std::string', 'name'), param('ns3::AttributeValue const &', 'value')])
+    ## object-factory.h: void ns3::ObjectFactory::Set(ns3::AttributeList const & list) [member function]
+    cls.add_method('Set', 
+                   'void', 
+                   [param('ns3::AttributeList const &', 'list')])
     ## object-factory.h: void ns3::ObjectFactory::SetTypeId(ns3::TypeId tid) [member function]
     cls.add_method('SetTypeId', 
                    'void', 
@@ -821,12 +828,12 @@
     cls.add_binary_comparison_operator('<')
     cls.add_output_stream_operator()
     cls.add_binary_comparison_operator('==')
-    ## type-id.h: ns3::TypeId::TypeId(ns3::TypeId const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::TypeId const &', 'arg0')])
     ## type-id.h: ns3::TypeId::TypeId(char const * name) [constructor]
     cls.add_constructor([param('char const *', 'name')])
     ## type-id.h: ns3::TypeId::TypeId() [constructor]
     cls.add_constructor([])
+    ## type-id.h: ns3::TypeId::TypeId(ns3::TypeId const & o) [copy constructor]
+    cls.add_constructor([param('ns3::TypeId const &', 'o')])
     ## type-id.h: ns3::TypeId ns3::TypeId::AddAttribute(std::string name, std::string help, ns3::AttributeValue const & initialValue, ns3::Ptr<ns3::AttributeAccessor const> accessor, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
     cls.add_method('AddAttribute', 
                    'ns3::TypeId', 
@@ -1016,6 +1023,22 @@
                    is_static=True)
     return
 
+def register_Ns3UnsafeAttributeList_methods(root_module, cls):
+    ## attribute-list.h: ns3::UnsafeAttributeList::UnsafeAttributeList() [constructor]
+    cls.add_constructor([])
+    ## attribute-list.h: ns3::UnsafeAttributeList::UnsafeAttributeList(ns3::UnsafeAttributeList const & o) [copy constructor]
+    cls.add_constructor([param('ns3::UnsafeAttributeList const &', 'o')])
+    ## attribute-list.h: void ns3::UnsafeAttributeList::Set(std::string name, ns3::AttributeValue const & param) [member function]
+    cls.add_method('Set', 
+                   'void', 
+                   [param('std::string', 'name'), param('ns3::AttributeValue const &', 'param')])
+    ## attribute-list.h: ns3::AttributeList ns3::UnsafeAttributeList::GetSafe(std::string name) const [member function]
+    cls.add_method('GetSafe', 
+                   'ns3::AttributeList', 
+                   [param('std::string', 'name')], 
+                   is_const=True)
+    return
+
 def register_Ns3WeibullVariable_methods(root_module, cls):
     ## random-variable.h: ns3::WeibullVariable::WeibullVariable(ns3::WeibullVariable const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::WeibullVariable const &', 'arg0')])
@@ -1879,7 +1902,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')])
@@ -1887,7 +1910,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')])
@@ -2035,7 +2058,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', 
@@ -2055,7 +2078,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 Nov 19 16:41:17 2008 -0800
+++ b/bindings/python/ns3_module_helper.py	Mon Nov 24 06:36:05 2008 +0100
@@ -45,6 +45,12 @@
     module.add_class('V4PingHelper', allow_subclassing=False)
     ## wifi-helper.h: ns3::WifiHelper [class]
     module.add_class('WifiHelper', allow_subclassing=False)
+    ## wifi-helper.h: ns3::WifiPhyHelper [class]
+    module.add_class('WifiPhyHelper', allow_subclassing=False)
+    ## yans-wifi-phy-helper.h: ns3::YansWifiChannelHelper [class]
+    module.add_class('YansWifiChannelHelper', allow_subclassing=False)
+    ## yans-wifi-phy-helper.h: ns3::YansWifiPhyHelper [class]
+    module.add_class('YansWifiPhyHelper', allow_subclassing=False, parent=root_module['ns3::WifiPhyHelper'])
     
     ## Register a nested module for the namespace Config
     
@@ -108,6 +114,9 @@
     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_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'])
     return
 
 def register_Ns3ApplicationContainer_methods(root_module, cls):
@@ -830,6 +839,11 @@
     cls.add_constructor([param('ns3::WifiHelper const &', 'arg0')])
     ## wifi-helper.h: ns3::WifiHelper::WifiHelper() [constructor]
     cls.add_constructor([])
+    ## wifi-helper.h: static ns3::WifiHelper ns3::WifiHelper::Default() [member function]
+    cls.add_method('Default', 
+                   'ns3::WifiHelper', 
+                   [], 
+                   is_static=True)
     ## wifi-helper.h: void ns3::WifiHelper::SetRemoteStationManager(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('SetRemoteStationManager', 
                    'void', 
@@ -838,70 +852,117 @@
     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: void ns3::WifiHelper::SetPhy(std::string phyType, 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('SetPhy', 
+    ## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::WifiPhyHelper const & phy, ns3::NodeContainer c) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::WifiPhyHelper const &', 'phy'), param('ns3::NodeContainer', 'c')], 
+                   is_const=True)
+    return
+
+def register_Ns3WifiPhyHelper_methods(root_module, cls):
+    ## wifi-helper.h: ns3::WifiPhyHelper::WifiPhyHelper(ns3::WifiPhyHelper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::WifiPhyHelper const &', 'arg0')])
+    ## wifi-helper.h: ns3::WifiPhyHelper::WifiPhyHelper() [constructor]
+    cls.add_constructor([])
+    ## wifi-helper.h: ns3::Ptr<ns3::WifiPhy> ns3::WifiPhyHelper::Create(ns3::Ptr<ns3::Node> node, ns3::Ptr<ns3::WifiNetDevice> device) const [member function]
+    cls.add_method('Create', 
+                   'ns3::Ptr< ns3::WifiPhy >', 
+                   [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::Ptr< ns3::WifiNetDevice >', 'device')], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    return
+
+def register_Ns3YansWifiChannelHelper_methods(root_module, cls):
+    ## yans-wifi-phy-helper.h: ns3::YansWifiChannelHelper::YansWifiChannelHelper(ns3::YansWifiChannelHelper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::YansWifiChannelHelper const &', 'arg0')])
+    ## yans-wifi-phy-helper.h: ns3::YansWifiChannelHelper::YansWifiChannelHelper() [constructor]
+    cls.add_constructor([])
+    ## yans-wifi-phy-helper.h: static ns3::YansWifiChannelHelper ns3::YansWifiChannelHelper::Default() [member function]
+    cls.add_method('Default', 
+                   'ns3::YansWifiChannelHelper', 
+                   [], 
+                   is_static=True)
+    ## yans-wifi-phy-helper.h: void ns3::YansWifiChannelHelper::AddPropagationLoss(std::string name, 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('AddPropagationLoss', 
+                   'void', 
+                   [param('std::string', 'name'), 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()')])
+    ## yans-wifi-phy-helper.h: void ns3::YansWifiChannelHelper::SetPropagationDelay(std::string name, 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('SetPropagationDelay', 
                    'void', 
-                   [param('std::string', 'phyType'), 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: static void ns3::WifiHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
+                   [param('std::string', 'name'), 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()')])
+    ## yans-wifi-phy-helper.h: ns3::Ptr<ns3::YansWifiChannel> ns3::YansWifiChannelHelper::Create() const [member function]
+    cls.add_method('Create', 
+                   'ns3::Ptr< ns3::YansWifiChannel >', 
+                   [], 
+                   is_const=True)
+    return
+
+def register_Ns3YansWifiPhyHelper_methods(root_module, cls):
+    ## yans-wifi-phy-helper.h: ns3::YansWifiPhyHelper::YansWifiPhyHelper(ns3::YansWifiPhyHelper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::YansWifiPhyHelper const &', 'arg0')])
+    ## yans-wifi-phy-helper.h: ns3::YansWifiPhyHelper::YansWifiPhyHelper() [constructor]
+    cls.add_constructor([])
+    ## yans-wifi-phy-helper.h: static ns3::YansWifiPhyHelper ns3::YansWifiPhyHelper::Default() [member function]
+    cls.add_method('Default', 
+                   'ns3::YansWifiPhyHelper', 
+                   [], 
+                   is_static=True)
+    ## yans-wifi-phy-helper.h: void ns3::YansWifiPhyHelper::SetChannel(ns3::Ptr<ns3::YansWifiChannel> channel) [member function]
+    cls.add_method('SetChannel', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::YansWifiChannel >', 'channel')])
+    ## yans-wifi-phy-helper.h: void ns3::YansWifiPhyHelper::Set(std::string name, ns3::AttributeValue const & v) [member function]
+    cls.add_method('Set', 
+                   'void', 
+                   [param('std::string', 'name'), param('ns3::AttributeValue const &', 'v')])
+    ## yans-wifi-phy-helper.h: void ns3::YansWifiPhyHelper::SetErrorRateModel(std::string name, 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('SetErrorRateModel', 
+                   'void', 
+                   [param('std::string', 'name'), 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()')])
+    ## yans-wifi-phy-helper.h: ns3::Ptr<ns3::WifiPhy> ns3::YansWifiPhyHelper::Create(ns3::Ptr<ns3::Node> node, ns3::Ptr<ns3::WifiNetDevice> device) const [member function]
+    cls.add_method('Create', 
+                   'ns3::Ptr< ns3::WifiPhy >', 
+                   [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::Ptr< ns3::WifiNetDevice >', 'device')], 
+                   is_const=True, is_virtual=True)
+    ## yans-wifi-phy-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
     cls.add_method('EnablePcap', 
                    'void', 
                    [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
                    is_static=True)
-    ## wifi-helper.h: static void ns3::WifiHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
+    ## yans-wifi-phy-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
     cls.add_method('EnablePcap', 
                    'void', 
                    [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')], 
                    is_static=True)
-    ## wifi-helper.h: static void ns3::WifiHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
+    ## yans-wifi-phy-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
     cls.add_method('EnablePcap', 
                    'void', 
                    [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')], 
                    is_static=True)
-    ## wifi-helper.h: static void ns3::WifiHelper::EnablePcapAll(std::string filename) [member function]
+    ## yans-wifi-phy-helper.h: static void ns3::YansWifiPhyHelper::EnablePcapAll(std::string filename) [member function]
     cls.add_method('EnablePcapAll', 
                    'void', 
                    [param('std::string', 'filename')], 
                    is_static=True)
-    ## wifi-helper.h: static void ns3::WifiHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
+    ## yans-wifi-phy-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
     cls.add_method('EnableAscii', 
                    'void', 
                    [param('std::ostream &', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
                    is_static=True)
-    ## wifi-helper.h: static void ns3::WifiHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function]
+    ## yans-wifi-phy-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function]
     cls.add_method('EnableAscii', 
                    'void', 
                    [param('std::ostream &', 'os'), param('ns3::NetDeviceContainer', 'd')], 
                    is_static=True)
-    ## wifi-helper.h: static void ns3::WifiHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
+    ## yans-wifi-phy-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
     cls.add_method('EnableAscii', 
                    'void', 
                    [param('std::ostream &', 'os'), param('ns3::NodeContainer', 'n')], 
                    is_static=True)
-    ## wifi-helper.h: static void ns3::WifiHelper::EnableAsciiAll(std::ostream & os) [member function]
+    ## yans-wifi-phy-helper.h: static void ns3::YansWifiPhyHelper::EnableAsciiAll(std::ostream & os) [member function]
     cls.add_method('EnableAsciiAll', 
                    'void', 
                    [param('std::ostream &', 'os')], 
                    is_static=True)
-    ## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::Ptr<ns3::Node> node) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::Ptr< ns3::Node >', 'node')], 
-                   is_const=True)
-    ## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::Ptr<ns3::Node> node, ns3::Ptr<ns3::WifiChannel> channel) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::Ptr< ns3::WifiChannel >', 'channel')], 
-                   is_const=True)
-    ## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::NodeContainer const & c) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::NodeContainer const &', 'c')], 
-                   is_const=True)
-    ## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::NodeContainer const & c, ns3::Ptr<ns3::WifiChannel> channel) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::NodeContainer const &', 'c'), param('ns3::Ptr< ns3::WifiChannel >', 'channel')], 
-                   is_const=True)
     return
 
 def register_functions(root_module):
--- a/bindings/python/ns3_module_wifi.py	Wed Nov 19 16:41:17 2008 -0800
+++ b/bindings/python/ns3_module_wifi.py	Mon Nov 24 06:36:05 2008 +0100
@@ -7,6 +7,10 @@
     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'])
+    ## interference-helper.h: ns3::InterferenceHelper [class]
+    module.add_class('InterferenceHelper', allow_subclassing=False)
+    ## interference-helper.h: ns3::InterferenceHelper::SnrPer [struct]
+    module.add_class('SnrPer', outer_class=root_module['ns3::InterferenceHelper'])
     ## ssid.h: ns3::Ssid [class]
     module.add_class('Ssid')
     ## supported-rates.h: ns3::SupportedRates [class]
@@ -59,6 +63,8 @@
     module.add_enum('State', ['SYNC', 'TX', 'CCA_BUSY', 'IDLE'], outer_class=root_module['ns3::WifiPhy'])
     ## wifi-remote-station-manager.h: ns3::WifiRemoteStationManager [class]
     module.add_class('WifiRemoteStationManager', parent=root_module['ns3::Object'])
+    ## yans-wifi-phy.h: ns3::YansWifiPhy [class]
+    module.add_class('YansWifiPhy', parent=root_module['ns3::WifiPhy'])
     ## aarf-wifi-manager.h: ns3::AarfWifiRemoteStation [class]
     module.add_class('AarfWifiRemoteStation', parent=root_module['ns3::ArfWifiRemoteStation'])
     ## adhoc-wifi-mac.h: ns3::AdhocWifiMac [class]
@@ -67,12 +73,12 @@
     module.add_class('AmrrWifiManager', parent=root_module['ns3::WifiRemoteStationManager'])
     ## arf-wifi-manager.h: ns3::ArfWifiManager [class]
     module.add_class('ArfWifiManager', parent=root_module['ns3::WifiRemoteStationManager'])
-    ## composite-propagation-loss-model.h: ns3::CompositePropagationLossModel [class]
-    module.add_class('CompositePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## 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'])
+    ## error-rate-model.h: ns3::ErrorRateModel [class]
+    module.add_class('ErrorRateModel', parent=root_module['ns3::Object'])
     ## propagation-loss-model.h: ns3::FriisPropagationLossModel [class]
     module.add_class('FriisPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## ideal-wifi-manager.h: ns3::IdealWifiManager [class]
@@ -93,6 +99,8 @@
     module.add_class('WifiChannel', parent=root_module['ns3::Channel'])
     ## wifi-net-device.h: ns3::WifiNetDevice [class]
     module.add_class('WifiNetDevice', parent=root_module['ns3::NetDevice'])
+    ## yans-wifi-channel.h: ns3::YansWifiChannel [class]
+    module.add_class('YansWifiChannel', parent=root_module['ns3::WifiChannel'])
     ## aarf-wifi-manager.h: ns3::AarfWifiManager [class]
     module.add_class('AarfWifiManager', parent=root_module['ns3::ArfWifiManager'])
     
@@ -137,6 +145,8 @@
     
 
 def register_methods(root_module):
+    register_Ns3InterferenceHelper_methods(root_module, root_module['ns3::InterferenceHelper'])
+    register_Ns3InterferenceHelperSnrPer_methods(root_module, root_module['ns3::InterferenceHelper::SnrPer'])
     register_Ns3Ssid_methods(root_module, root_module['ns3::Ssid'])
     register_Ns3SupportedRates_methods(root_module, root_module['ns3::SupportedRates'])
     register_Ns3ThresholdsItem_methods(root_module, root_module['ns3::ThresholdsItem'])
@@ -161,13 +171,14 @@
     register_Ns3WifiModeValue_methods(root_module, root_module['ns3::WifiModeValue'])
     register_Ns3WifiPhy_methods(root_module, root_module['ns3::WifiPhy'])
     register_Ns3WifiRemoteStationManager_methods(root_module, root_module['ns3::WifiRemoteStationManager'])
+    register_Ns3YansWifiPhy_methods(root_module, root_module['ns3::YansWifiPhy'])
     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_Ns3ArfWifiManager_methods(root_module, root_module['ns3::ArfWifiManager'])
-    register_Ns3CompositePropagationLossModel_methods(root_module, root_module['ns3::CompositePropagationLossModel'])
     register_Ns3ConstantRateWifiManager_methods(root_module, root_module['ns3::ConstantRateWifiManager'])
     register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, root_module['ns3::ConstantSpeedPropagationDelayModel'])
+    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'])
@@ -178,9 +189,65 @@
     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'])
+    register_Ns3YansWifiChannel_methods(root_module, root_module['ns3::YansWifiChannel'])
     register_Ns3AarfWifiManager_methods(root_module, root_module['ns3::AarfWifiManager'])
     return
 
+def register_Ns3InterferenceHelper_methods(root_module, cls):
+    ## interference-helper.h: ns3::InterferenceHelper::InterferenceHelper() [constructor]
+    cls.add_constructor([])
+    ## interference-helper.h: ns3::Ptr<ns3::InterferenceHelper::Event> ns3::InterferenceHelper::Add(uint32_t size, ns3::WifiMode payloadMode, ns3::WifiPreamble preamble, ns3::Time duration, double rxPower) [member function]
+    cls.add_method('Add', 
+                   'ns3::Ptr< ns3::InterferenceHelper::Event >', 
+                   [param('uint32_t', 'size'), param('ns3::WifiMode', 'payloadMode'), param('ns3::WifiPreamble', 'preamble'), param('ns3::Time', 'duration'), param('double', 'rxPower')])
+    ## interference-helper.h: ns3::InterferenceHelper::SnrPer ns3::InterferenceHelper::CalculateSnrPer(ns3::Ptr<ns3::InterferenceHelper::Event> event) [member function]
+    cls.add_method('CalculateSnrPer', 
+                   'ns3::InterferenceHelper::SnrPer', 
+                   [param('ns3::Ptr< ns3::InterferenceHelper::Event >', 'event')])
+    ## interference-helper.h: ns3::Time ns3::InterferenceHelper::CalculateTxDuration(uint32_t size, ns3::WifiMode payloadMode, ns3::WifiPreamble preamble) const [member function]
+    cls.add_method('CalculateTxDuration', 
+                   'ns3::Time', 
+                   [param('uint32_t', 'size'), param('ns3::WifiMode', 'payloadMode'), param('ns3::WifiPreamble', 'preamble')], 
+                   is_const=True)
+    ## interference-helper.h: void ns3::InterferenceHelper::Configure80211aParameters() [member function]
+    cls.add_method('Configure80211aParameters', 
+                   'void', 
+                   [])
+    ## interference-helper.h: ns3::Time ns3::InterferenceHelper::GetEnergyDuration(double energyW) [member function]
+    cls.add_method('GetEnergyDuration', 
+                   'ns3::Time', 
+                   [param('double', 'energyW')])
+    ## interference-helper.h: ns3::Ptr<ns3::ErrorRateModel> ns3::InterferenceHelper::GetErrorRateModel() const [member function]
+    cls.add_method('GetErrorRateModel', 
+                   'ns3::Ptr< ns3::ErrorRateModel >', 
+                   [], 
+                   is_const=True)
+    ## interference-helper.h: double ns3::InterferenceHelper::GetNoiseFloorW() const [member function]
+    cls.add_method('GetNoiseFloorW', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## interference-helper.h: void ns3::InterferenceHelper::SetErrorRateModel(ns3::Ptr<ns3::ErrorRateModel> rate) [member function]
+    cls.add_method('SetErrorRateModel', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::ErrorRateModel >', 'rate')])
+    ## interference-helper.h: void ns3::InterferenceHelper::SetNoiseFloorW(double noiseFloor) [member function]
+    cls.add_method('SetNoiseFloorW', 
+                   'void', 
+                   [param('double', 'noiseFloor')])
+    return
+
+def register_Ns3InterferenceHelperSnrPer_methods(root_module, cls):
+    ## interference-helper.h: ns3::InterferenceHelper::SnrPer::SnrPer() [constructor]
+    cls.add_constructor([])
+    ## interference-helper.h: ns3::InterferenceHelper::SnrPer::SnrPer(ns3::InterferenceHelper::SnrPer const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::InterferenceHelper::SnrPer const &', 'arg0')])
+    ## interference-helper.h: ns3::InterferenceHelper::SnrPer::per [variable]
+    cls.add_instance_attribute('per', 'double', is_const=False)
+    ## interference-helper.h: ns3::InterferenceHelper::SnrPer::snr [variable]
+    cls.add_instance_attribute('snr', 'double', is_const=False)
+    return
+
 def register_Ns3Ssid_methods(root_module, cls):
     cls.add_output_stream_operator()
     ## ssid.h: ns3::Ssid::Ssid(ns3::Ssid const & arg0) [copy constructor]
@@ -299,6 +366,8 @@
     cls.add_constructor([param('ns3::WifiMode const &', 'arg0')])
     ## wifi-mode.h: ns3::WifiMode::WifiMode() [constructor]
     cls.add_constructor([])
+    ## wifi-mode.h: ns3::WifiMode::WifiMode(std::string name) [constructor]
+    cls.add_constructor([param('std::string', 'name')])
     ## wifi-mode.h: uint32_t ns3::WifiMode::GetBandwidth() const [member function]
     cls.add_method('GetBandwidth', 
                    'uint32_t', 
@@ -391,8 +460,8 @@
                    'void', 
                    [param('ns3::Time', 'duration')], 
                    is_pure_virtual=True, is_virtual=True)
-    ## wifi-phy.h: void ns3::WifiPhyListener::NotifyCcaBusyStart(ns3::Time duration) [member function]
-    cls.add_method('NotifyCcaBusyStart', 
+    ## wifi-phy.h: void ns3::WifiPhyListener::NotifyMaybeCcaBusyStart(ns3::Time duration) [member function]
+    cls.add_method('NotifyMaybeCcaBusyStart', 
                    'void', 
                    [param('ns3::Time', 'duration')], 
                    is_pure_virtual=True, is_virtual=True)
@@ -935,20 +1004,27 @@
     return
 
 def register_Ns3PropagationLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: ns3::PropagationLossModel::PropagationLossModel(ns3::PropagationLossModel const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::PropagationLossModel const &', 'arg0')])
-    ## propagation-loss-model.h: ns3::PropagationLossModel::PropagationLossModel() [constructor]
-    cls.add_constructor([])
     ## propagation-loss-model.h: static ns3::TypeId ns3::PropagationLossModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
                    [], 
                    is_static=True)
+    ## propagation-loss-model.h: ns3::PropagationLossModel::PropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: void ns3::PropagationLossModel::SetNext(ns3::Ptr<ns3::PropagationLossModel> next) [member function]
+    cls.add_method('SetNext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::PropagationLossModel >', 'next')])
     ## propagation-loss-model.h: double ns3::PropagationLossModel::GetLoss(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
     cls.add_method('GetLoss', 
                    'double', 
                    [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_pure_virtual=True, is_const=True, is_virtual=True)
+                   is_const=True)
+    ## propagation-loss-model.h: double ns3::PropagationLossModel::DoGetLoss(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoGetLoss', 
+                   'double', 
+                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
     return
 
 def register_Ns3RandomPropagationDelayModel_methods(root_module, cls):
@@ -969,8 +1045,6 @@
     return
 
 def register_Ns3RandomPropagationLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: ns3::RandomPropagationLossModel::RandomPropagationLossModel(ns3::RandomPropagationLossModel const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::RandomPropagationLossModel const &', 'arg0')])
     ## propagation-loss-model.h: static ns3::TypeId ns3::RandomPropagationLossModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
@@ -978,11 +1052,11 @@
                    is_static=True)
     ## propagation-loss-model.h: ns3::RandomPropagationLossModel::RandomPropagationLossModel() [constructor]
     cls.add_constructor([])
-    ## propagation-loss-model.h: double ns3::RandomPropagationLossModel::GetLoss(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('GetLoss', 
+    ## propagation-loss-model.h: double ns3::RandomPropagationLossModel::DoGetLoss(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoGetLoss', 
                    'double', 
                    [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, is_virtual=True)
+                   is_const=True, visibility='private', is_virtual=True)
     return
 
 def register_Ns3RraaWifiRemoteStation_methods(root_module, cls):
@@ -1205,42 +1279,42 @@
     cls.add_method('Enqueue', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'to'), param('ns3::Mac48Address', 'from')], 
-                   is_pure_virtual=True, visibility='private', is_virtual=True)
+                   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]
     cls.add_method('Enqueue', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'to')], 
-                   is_pure_virtual=True, visibility='private', is_virtual=True)
+                   is_pure_virtual=True, is_virtual=True)
     ## wifi-mac.h: bool ns3::WifiMac::SupportsSendFrom() const [member function]
     cls.add_method('SupportsSendFrom', 
                    'bool', 
                    [], 
-                   is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
     ## wifi-mac.h: void ns3::WifiMac::SetWifiPhy(ns3::Ptr<ns3::WifiPhy> phy) [member function]
     cls.add_method('SetWifiPhy', 
                    'void', 
                    [param('ns3::Ptr< ns3::WifiPhy >', 'phy')], 
-                   is_pure_virtual=True, visibility='private', is_virtual=True)
+                   is_pure_virtual=True, is_virtual=True)
     ## wifi-mac.h: void ns3::WifiMac::SetWifiRemoteStationManager(ns3::Ptr<ns3::WifiRemoteStationManager> stationManager) [member function]
     cls.add_method('SetWifiRemoteStationManager', 
                    'void', 
                    [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'stationManager')], 
-                   is_pure_virtual=True, visibility='private', is_virtual=True)
+                   is_pure_virtual=True, is_virtual=True)
     ## wifi-mac.h: void ns3::WifiMac::SetForwardUpCallback(ns3::Callback<void, ns3::Ptr<ns3::Packet>, ns3::Mac48Address, ns3::Mac48Address, 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 >', 'upCallback')], 
-                   is_pure_virtual=True, visibility='private', is_virtual=True)
+                   is_pure_virtual=True, is_virtual=True)
     ## wifi-mac.h: void ns3::WifiMac::SetLinkUpCallback(ns3::Callback<void, 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 >', 'linkUp')], 
-                   is_pure_virtual=True, visibility='private', is_virtual=True)
+                   is_pure_virtual=True, is_virtual=True)
     ## wifi-mac.h: void ns3::WifiMac::SetLinkDownCallback(ns3::Callback<void, 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 >', 'linkDown')], 
-                   is_pure_virtual=True, visibility='private', is_virtual=True)
+                   is_pure_virtual=True, is_virtual=True)
     return
 
 def register_Ns3WifiModeChecker_methods(root_module, cls):
@@ -1284,167 +1358,131 @@
     return
 
 def register_Ns3WifiPhy_methods(root_module, cls):
-    ## wifi-phy.h: ns3::WifiPhy::WifiPhy() [constructor]
-    cls.add_constructor([])
-    ## wifi-phy.h: double ns3::WifiPhy::CalculateSnr(ns3::WifiMode txMode, double ber) const [member function]
-    cls.add_method('CalculateSnr', 
-                   'double', 
-                   [param('ns3::WifiMode', 'txMode'), param('double', 'ber')], 
-                   is_const=True)
-    ## wifi-phy.h: ns3::Time ns3::WifiPhy::CalculateTxDuration(uint32_t size, ns3::WifiMode payloadMode, ns3::WifiPreamble preamble) const [member function]
-    cls.add_method('CalculateTxDuration', 
-                   'ns3::Time', 
-                   [param('uint32_t', 'size'), param('ns3::WifiMode', 'payloadMode'), param('ns3::WifiPreamble', 'preamble')], 
-                   is_const=True)
-    ## wifi-phy.h: ns3::Ptr<ns3::WifiChannel> ns3::WifiPhy::GetChannel() const [member function]
-    cls.add_method('GetChannel', 
-                   'ns3::Ptr< ns3::WifiChannel >', 
-                   [], 
-                   is_const=True)
-    ## wifi-phy.h: ns3::Time ns3::WifiPhy::GetDelayUntilIdle() [member function]
-    cls.add_method('GetDelayUntilIdle', 
-                   'ns3::Time', 
-                   [])
-    ## wifi-phy.h: double ns3::WifiPhy::GetEdThreshold() const [member function]
-    cls.add_method('GetEdThreshold', 
-                   'double', 
-                   [], 
-                   is_const=True)
-    ## wifi-phy.h: ns3::Time ns3::WifiPhy::GetLastRxStartTime() const [member function]
-    cls.add_method('GetLastRxStartTime', 
-                   'ns3::Time', 
-                   [], 
-                   is_const=True)
-    ## wifi-phy.h: ns3::WifiMode ns3::WifiPhy::GetMode(uint32_t mode) const [member function]
-    cls.add_method('GetMode', 
-                   'ns3::WifiMode', 
-                   [param('uint32_t', 'mode')], 
-                   is_const=True)
-    ## wifi-phy.h: uint32_t ns3::WifiPhy::GetNModes() const [member function]
-    cls.add_method('GetNModes', 
-                   'uint32_t', 
-                   [], 
-                   is_const=True)
-    ## wifi-phy.h: uint32_t ns3::WifiPhy::GetNTxPower() const [member function]
-    cls.add_method('GetNTxPower', 
-                   'uint32_t', 
-                   [], 
-                   is_const=True)
-    ## wifi-phy.h: double ns3::WifiPhy::GetRxGain() const [member function]
-    cls.add_method('GetRxGain', 
-                   'double', 
-                   [], 
-                   is_const=True)
-    ## wifi-phy.h: double ns3::WifiPhy::GetRxNoise() const [member function]
-    cls.add_method('GetRxNoise', 
-                   'double', 
-                   [], 
-                   is_const=True)
-    ## wifi-phy.h: ns3::Time ns3::WifiPhy::GetStateDuration() [member function]
-    cls.add_method('GetStateDuration', 
-                   'ns3::Time', 
-                   [])
-    ## wifi-phy.h: double ns3::WifiPhy::GetTxGain() const [member function]
-    cls.add_method('GetTxGain', 
-                   'double', 
-                   [], 
-                   is_const=True)
-    ## wifi-phy.h: double ns3::WifiPhy::GetTxPowerEnd() const [member function]
-    cls.add_method('GetTxPowerEnd', 
-                   'double', 
-                   [], 
-                   is_const=True)
-    ## wifi-phy.h: double ns3::WifiPhy::GetTxPowerStart() const [member function]
-    cls.add_method('GetTxPowerStart', 
-                   'double', 
-                   [], 
-                   is_const=True)
+    ## wifi-phy.h: ns3::WifiPhy::g_6mba [variable]
+    cls.add_static_attribute('g_6mba', 'ns3::WifiMode', is_const=False)
+    ## wifi-phy.h: ns3::WifiPhy::g_9mba [variable]
+    cls.add_static_attribute('g_9mba', 'ns3::WifiMode', is_const=False)
+    ## wifi-phy.h: ns3::WifiPhy::g_12mba [variable]
+    cls.add_static_attribute('g_12mba', 'ns3::WifiMode', is_const=False)
+    ## wifi-phy.h: ns3::WifiPhy::g_18mba [variable]
+    cls.add_static_attribute('g_18mba', 'ns3::WifiMode', is_const=False)
+    ## wifi-phy.h: ns3::WifiPhy::g_24mba [variable]
+    cls.add_static_attribute('g_24mba', 'ns3::WifiMode', is_const=False)
+    ## wifi-phy.h: ns3::WifiPhy::g_36mba [variable]
+    cls.add_static_attribute('g_36mba', 'ns3::WifiMode', is_const=False)
+    ## wifi-phy.h: ns3::WifiPhy::g_48mba [variable]
+    cls.add_static_attribute('g_48mba', 'ns3::WifiMode', is_const=False)
+    ## wifi-phy.h: ns3::WifiPhy::g_54mba [variable]
+    cls.add_static_attribute('g_54mba', 'ns3::WifiMode', is_const=False)
+    ## wifi-phy.h: ns3::WifiPhy::WifiPhy(ns3::WifiPhy const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::WifiPhy const &', 'arg0')])
     ## wifi-phy.h: static ns3::TypeId ns3::WifiPhy::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
                    [], 
                    is_static=True)
-    ## wifi-phy.h: bool ns3::WifiPhy::IsStateBusy() [member function]
-    cls.add_method('IsStateBusy', 
-                   'bool', 
-                   [])
-    ## wifi-phy.h: bool ns3::WifiPhy::IsStateCcaBusy() [member function]
-    cls.add_method('IsStateCcaBusy', 
-                   'bool', 
-                   [])
-    ## wifi-phy.h: bool ns3::WifiPhy::IsStateIdle() [member function]
-    cls.add_method('IsStateIdle', 
-                   'bool', 
-                   [])
-    ## wifi-phy.h: bool ns3::WifiPhy::IsStateSync() [member function]
-    cls.add_method('IsStateSync', 
-                   'bool', 
-                   [])
-    ## wifi-phy.h: bool ns3::WifiPhy::IsStateTx() [member function]
-    cls.add_method('IsStateTx', 
-                   'bool', 
-                   [])
-    ## wifi-phy.h: void ns3::WifiPhy::RegisterListener(ns3::WifiPhyListener * listener) [member function]
-    cls.add_method('RegisterListener', 
+    ## wifi-phy.h: ns3::WifiPhy::WifiPhy() [constructor]
+    cls.add_constructor([])
+    ## wifi-phy.h: double ns3::WifiPhy::GetTxPowerStart() const [member function]
+    cls.add_method('GetTxPowerStart', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## wifi-phy.h: double ns3::WifiPhy::GetTxPowerEnd() const [member function]
+    cls.add_method('GetTxPowerEnd', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## wifi-phy.h: uint32_t ns3::WifiPhy::GetNTxPower() const [member function]
+    cls.add_method('GetNTxPower', 
+                   'uint32_t', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## wifi-phy.h: void ns3::WifiPhy::SetReceiveOkCallback(ns3::Callback<void,ns3::Ptr<ns3::Packet>,double,ns3::WifiMode,ns3::WifiPreamble,ns3::empty,ns3::empty> callback) [member function]
+    cls.add_method('SetReceiveOkCallback', 
                    'void', 
-                   [param('ns3::WifiPhyListener *', 'listener')])
+                   [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, double, ns3::WifiMode, ns3::WifiPreamble, ns3::empty, ns3::empty >', 'callback')], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## wifi-phy.h: void ns3::WifiPhy::SetReceiveErrorCallback(ns3::Callback<void,ns3::Ptr<const ns3::Packet>,double,ns3::empty,ns3::empty,ns3::empty,ns3::empty> callback) [member function]
+    cls.add_method('SetReceiveErrorCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::Ptr< ns3::Packet const >, double, 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]
     cls.add_method('SendPacket', 
                    'void', 
-                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMode', 'mode'), param('ns3::WifiPreamble', 'preamble'), param('uint8_t', 'txPowerLevel')])
-    ## wifi-phy.h: void ns3::WifiPhy::SetChannel(ns3::Ptr<ns3::WifiChannel> channel) [member function]
-    cls.add_method('SetChannel', 
-                   'void', 
-                   [param('ns3::Ptr< ns3::WifiChannel >', 'channel')])
-    ## wifi-phy.h: void ns3::WifiPhy::SetEdThreshold(double threshold) [member function]
-    cls.add_method('SetEdThreshold', 
-                   'void', 
-                   [param('double', 'threshold')])
-    ## wifi-phy.h: void ns3::WifiPhy::SetNTxPower(uint32_t n) [member function]
-    cls.add_method('SetNTxPower', 
-                   'void', 
-                   [param('uint32_t', 'n')])
-    ## wifi-phy.h: void ns3::WifiPhy::SetReceiveErrorCallback(ns3::Callback<void, ns3::Ptr<ns3::Packet>, double, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
-    cls.add_method('SetReceiveErrorCallback', 
-                   'void', 
-                   [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, double, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
-    ## wifi-phy.h: void ns3::WifiPhy::SetReceiveOkCallback(ns3::Callback<void, ns3::Ptr<ns3::Packet>, double, ns3::WifiMode, ns3::WifiPreamble, ns3::empty, ns3::empty> callback) [member function]
-    cls.add_method('SetReceiveOkCallback', 
-                   'void', 
-                   [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, double, ns3::WifiMode, ns3::WifiPreamble, ns3::empty, ns3::empty >', 'callback')])
-    ## wifi-phy.h: void ns3::WifiPhy::SetRxGain(double gain) [member function]
-    cls.add_method('SetRxGain', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMode', 'mode'), param('ns3::WifiPreamble', 'preamble'), param('uint8_t', 'txPowerLevel')], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## wifi-phy.h: void ns3::WifiPhy::RegisterListener(ns3::WifiPhyListener * listener) [member function]
+    cls.add_method('RegisterListener', 
                    'void', 
-                   [param('double', 'gain')])
-    ## wifi-phy.h: void ns3::WifiPhy::SetRxNoise(double ratio) [member function]
-    cls.add_method('SetRxNoise', 
-                   'void', 
-                   [param('double', 'ratio')])
-    ## wifi-phy.h: void ns3::WifiPhy::SetStandard(ns3::WifiPhyStandard standard) [member function]
-    cls.add_method('SetStandard', 
-                   'void', 
-                   [param('ns3::WifiPhyStandard', 'standard')])
-    ## wifi-phy.h: void ns3::WifiPhy::SetTxGain(double gain) [member function]
-    cls.add_method('SetTxGain', 
-                   'void', 
-                   [param('double', 'gain')])
-    ## wifi-phy.h: void ns3::WifiPhy::SetTxPowerEnd(double end) [member function]
-    cls.add_method('SetTxPowerEnd', 
-                   'void', 
-                   [param('double', 'end')])
-    ## wifi-phy.h: void ns3::WifiPhy::SetTxPowerStart(double start) [member function]
-    cls.add_method('SetTxPowerStart', 
-                   'void', 
-                   [param('double', 'start')])
-    ## wifi-phy.h: void ns3::WifiPhy::StartReceivePacket(ns3::Ptr<ns3::Packet> packet, double rxPowerDbm, ns3::WifiMode mode, ns3::WifiPreamble preamble) [member function]
-    cls.add_method('StartReceivePacket', 
-                   'void', 
-                   [param('ns3::Ptr< ns3::Packet >', 'packet'), param('double', 'rxPowerDbm'), param('ns3::WifiMode', 'mode'), param('ns3::WifiPreamble', 'preamble')])
-    ## wifi-phy.h: void ns3::WifiPhy::DoDispose() [member function]
-    cls.add_method('DoDispose', 
-                   'void', 
+                   [param('ns3::WifiPhyListener *', 'listener')], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## wifi-phy.h: bool ns3::WifiPhy::IsStateCcaBusy() [member function]
+    cls.add_method('IsStateCcaBusy', 
+                   'bool', 
+                   [], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## wifi-phy.h: bool ns3::WifiPhy::IsStateIdle() [member function]
+    cls.add_method('IsStateIdle', 
+                   'bool', 
+                   [], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## wifi-phy.h: bool ns3::WifiPhy::IsStateBusy() [member function]
+    cls.add_method('IsStateBusy', 
+                   'bool', 
+                   [], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## wifi-phy.h: bool ns3::WifiPhy::IsStateSync() [member function]
+    cls.add_method('IsStateSync', 
+                   'bool', 
+                   [], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## wifi-phy.h: bool ns3::WifiPhy::IsStateTx() [member function]
+    cls.add_method('IsStateTx', 
+                   'bool', 
+                   [], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## wifi-phy.h: ns3::Time ns3::WifiPhy::GetStateDuration() [member function]
+    cls.add_method('GetStateDuration', 
+                   'ns3::Time', 
                    [], 
-                   visibility='private', is_virtual=True)
+                   is_pure_virtual=True, is_virtual=True)
+    ## wifi-phy.h: ns3::Time ns3::WifiPhy::GetDelayUntilIdle() [member function]
+    cls.add_method('GetDelayUntilIdle', 
+                   'ns3::Time', 
+                   [], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## wifi-phy.h: ns3::Time ns3::WifiPhy::GetLastRxStartTime() const [member function]
+    cls.add_method('GetLastRxStartTime', 
+                   'ns3::Time', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## wifi-phy.h: ns3::Time ns3::WifiPhy::CalculateTxDuration(uint32_t size, ns3::WifiMode payloadMode, ns3::WifiPreamble preamble) const [member function]
+    cls.add_method('CalculateTxDuration', 
+                   'ns3::Time', 
+                   [param('uint32_t', 'size'), param('ns3::WifiMode', 'payloadMode'), param('ns3::WifiPreamble', 'preamble')], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## wifi-phy.h: uint32_t ns3::WifiPhy::GetNModes() const [member function]
+    cls.add_method('GetNModes', 
+                   'uint32_t', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## wifi-phy.h: ns3::WifiMode ns3::WifiPhy::GetMode(uint32_t mode) const [member function]
+    cls.add_method('GetMode', 
+                   'ns3::WifiMode', 
+                   [param('uint32_t', 'mode')], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## wifi-phy.h: double ns3::WifiPhy::CalculateSnr(ns3::WifiMode txMode, double ber) const [member function]
+    cls.add_method('CalculateSnr', 
+                   'double', 
+                   [param('ns3::WifiMode', 'txMode'), param('double', 'ber')], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## wifi-phy.h: ns3::Ptr<ns3::WifiChannel> ns3::WifiPhy::GetChannel() const [member function]
+    cls.add_method('GetChannel', 
+                   'ns3::Ptr< ns3::WifiChannel >', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
     return
 
 def register_Ns3WifiRemoteStationManager_methods(root_module, cls):
@@ -1556,6 +1594,216 @@
                    is_pure_virtual=True, visibility='private', is_virtual=True)
     return
 
+def register_Ns3YansWifiPhy_methods(root_module, cls):
+    ## yans-wifi-phy.h: static ns3::TypeId ns3::YansWifiPhy::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## yans-wifi-phy.h: ns3::YansWifiPhy::YansWifiPhy() [constructor]
+    cls.add_constructor([])
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetChannel(ns3::Ptr<ns3::YansWifiChannel> channel) [member function]
+    cls.add_method('SetChannel', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::YansWifiChannel >', 'channel')])
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::StartReceivePacket(ns3::Ptr<ns3::Packet> packet, double rxPowerDbm, ns3::WifiMode mode, ns3::WifiPreamble preamble) [member function]
+    cls.add_method('StartReceivePacket', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet >', 'packet'), param('double', 'rxPowerDbm'), param('ns3::WifiMode', 'mode'), param('ns3::WifiPreamble', 'preamble')])
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetStandard(ns3::WifiPhyStandard standard) [member function]
+    cls.add_method('SetStandard', 
+                   'void', 
+                   [param('ns3::WifiPhyStandard', 'standard')])
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetRxNoise(double ratio) [member function]
+    cls.add_method('SetRxNoise', 
+                   'void', 
+                   [param('double', 'ratio')])
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetTxPowerStart(double start) [member function]
+    cls.add_method('SetTxPowerStart', 
+                   'void', 
+                   [param('double', 'start')])
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetTxPowerEnd(double end) [member function]
+    cls.add_method('SetTxPowerEnd', 
+                   'void', 
+                   [param('double', 'end')])
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetNTxPower(uint32_t n) [member function]
+    cls.add_method('SetNTxPower', 
+                   'void', 
+                   [param('uint32_t', 'n')])
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetTxGain(double gain) [member function]
+    cls.add_method('SetTxGain', 
+                   'void', 
+                   [param('double', 'gain')])
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetRxGain(double gain) [member function]
+    cls.add_method('SetRxGain', 
+                   'void', 
+                   [param('double', 'gain')])
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetEdThreshold(double threshold) [member function]
+    cls.add_method('SetEdThreshold', 
+                   'void', 
+                   [param('double', 'threshold')])
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetCcaMode1Threshold(double threshold) [member function]
+    cls.add_method('SetCcaMode1Threshold', 
+                   'void', 
+                   [param('double', 'threshold')])
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetErrorRateModel(ns3::Ptr<ns3::ErrorRateModel> rate) [member function]
+    cls.add_method('SetErrorRateModel', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::ErrorRateModel >', 'rate')])
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetDevice(ns3::Ptr<ns3::Object> device) [member function]
+    cls.add_method('SetDevice', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Object >', 'device')])
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetMobility(ns3::Ptr<ns3::Object> mobility) [member function]
+    cls.add_method('SetMobility', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Object >', 'mobility')])
+    ## yans-wifi-phy.h: double ns3::YansWifiPhy::GetRxNoise() const [member function]
+    cls.add_method('GetRxNoise', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## yans-wifi-phy.h: double ns3::YansWifiPhy::GetTxGain() const [member function]
+    cls.add_method('GetTxGain', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## yans-wifi-phy.h: double ns3::YansWifiPhy::GetRxGain() const [member function]
+    cls.add_method('GetRxGain', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## yans-wifi-phy.h: double ns3::YansWifiPhy::GetEdThreshold() const [member function]
+    cls.add_method('GetEdThreshold', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## yans-wifi-phy.h: double ns3::YansWifiPhy::GetCcaMode1Threshold() const [member function]
+    cls.add_method('GetCcaMode1Threshold', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## yans-wifi-phy.h: ns3::Ptr<ns3::ErrorRateModel> ns3::YansWifiPhy::GetErrorRateModel() const [member function]
+    cls.add_method('GetErrorRateModel', 
+                   'ns3::Ptr< ns3::ErrorRateModel >', 
+                   [], 
+                   is_const=True)
+    ## yans-wifi-phy.h: ns3::Ptr<ns3::Object> ns3::YansWifiPhy::GetDevice() const [member function]
+    cls.add_method('GetDevice', 
+                   'ns3::Ptr< ns3::Object >', 
+                   [], 
+                   is_const=True)
+    ## yans-wifi-phy.h: ns3::Ptr<ns3::Object> ns3::YansWifiPhy::GetMobility() [member function]
+    cls.add_method('GetMobility', 
+                   'ns3::Ptr< ns3::Object >', 
+                   [])
+    ## yans-wifi-phy.h: double ns3::YansWifiPhy::GetTxPowerStart() const [member function]
+    cls.add_method('GetTxPowerStart', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## yans-wifi-phy.h: double ns3::YansWifiPhy::GetTxPowerEnd() const [member function]
+    cls.add_method('GetTxPowerEnd', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## yans-wifi-phy.h: uint32_t ns3::YansWifiPhy::GetNTxPower() const [member function]
+    cls.add_method('GetNTxPower', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetReceiveOkCallback(ns3::Callback<void,ns3::Ptr<ns3::Packet>,double,ns3::WifiMode,ns3::WifiPreamble,ns3::empty,ns3::empty> callback) [member function]
+    cls.add_method('SetReceiveOkCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, double, ns3::WifiMode, ns3::WifiPreamble, ns3::empty, ns3::empty >', 'callback')], 
+                   is_virtual=True)
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetReceiveErrorCallback(ns3::Callback<void,ns3::Ptr<const ns3::Packet>,double,ns3::empty,ns3::empty,ns3::empty,ns3::empty> callback) [member function]
+    cls.add_method('SetReceiveErrorCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::Ptr< ns3::Packet const >, double, 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]
+    cls.add_method('SendPacket', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMode', 'mode'), param('ns3::WifiPreamble', 'preamble'), param('uint8_t', 'txPowerLevel')], 
+                   is_virtual=True)
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::RegisterListener(ns3::WifiPhyListener * listener) [member function]
+    cls.add_method('RegisterListener', 
+                   'void', 
+                   [param('ns3::WifiPhyListener *', 'listener')], 
+                   is_virtual=True)
+    ## yans-wifi-phy.h: bool ns3::YansWifiPhy::IsStateCcaBusy() [member function]
+    cls.add_method('IsStateCcaBusy', 
+                   'bool', 
+                   [], 
+                   is_virtual=True)
+    ## yans-wifi-phy.h: bool ns3::YansWifiPhy::IsStateIdle() [member function]
+    cls.add_method('IsStateIdle', 
+                   'bool', 
+                   [], 
+                   is_virtual=True)
+    ## yans-wifi-phy.h: bool ns3::YansWifiPhy::IsStateBusy() [member function]
+    cls.add_method('IsStateBusy', 
+                   'bool', 
+                   [], 
+                   is_virtual=True)
+    ## yans-wifi-phy.h: bool ns3::YansWifiPhy::IsStateSync() [member function]
+    cls.add_method('IsStateSync', 
+                   'bool', 
+                   [], 
+                   is_virtual=True)
+    ## yans-wifi-phy.h: bool ns3::YansWifiPhy::IsStateTx() [member function]
+    cls.add_method('IsStateTx', 
+                   'bool', 
+                   [], 
+                   is_virtual=True)
+    ## yans-wifi-phy.h: ns3::Time ns3::YansWifiPhy::GetStateDuration() [member function]
+    cls.add_method('GetStateDuration', 
+                   'ns3::Time', 
+                   [], 
+                   is_virtual=True)
+    ## yans-wifi-phy.h: ns3::Time ns3::YansWifiPhy::GetDelayUntilIdle() [member function]
+    cls.add_method('GetDelayUntilIdle', 
+                   'ns3::Time', 
+                   [], 
+                   is_virtual=True)
+    ## yans-wifi-phy.h: ns3::Time ns3::YansWifiPhy::GetLastRxStartTime() const [member function]
+    cls.add_method('GetLastRxStartTime', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## yans-wifi-phy.h: ns3::Time ns3::YansWifiPhy::CalculateTxDuration(uint32_t size, ns3::WifiMode payloadMode, ns3::WifiPreamble preamble) const [member function]
+    cls.add_method('CalculateTxDuration', 
+                   'ns3::Time', 
+                   [param('uint32_t', 'size'), param('ns3::WifiMode', 'payloadMode'), param('ns3::WifiPreamble', 'preamble')], 
+                   is_const=True, is_virtual=True)
+    ## yans-wifi-phy.h: uint32_t ns3::YansWifiPhy::GetNModes() const [member function]
+    cls.add_method('GetNModes', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## yans-wifi-phy.h: ns3::WifiMode ns3::YansWifiPhy::GetMode(uint32_t mode) const [member function]
+    cls.add_method('GetMode', 
+                   'ns3::WifiMode', 
+                   [param('uint32_t', 'mode')], 
+                   is_const=True, is_virtual=True)
+    ## yans-wifi-phy.h: double ns3::YansWifiPhy::CalculateSnr(ns3::WifiMode txMode, double ber) const [member function]
+    cls.add_method('CalculateSnr', 
+                   'double', 
+                   [param('ns3::WifiMode', 'txMode'), param('double', 'ber')], 
+                   is_const=True, is_virtual=True)
+    ## yans-wifi-phy.h: ns3::Ptr<ns3::WifiChannel> ns3::YansWifiPhy::GetChannel() const [member function]
+    cls.add_method('GetChannel', 
+                   'ns3::Ptr< ns3::WifiChannel >', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## yans-wifi-phy.h: void ns3::YansWifiPhy::DoDispose() [member function]
+    cls.add_method('DoDispose', 
+                   'void', 
+                   [], 
+                   visibility='private', is_virtual=True)
+    return
+
 def register_Ns3AarfWifiRemoteStation_methods(root_module, cls):
     ## aarf-wifi-manager.h: ns3::AarfWifiRemoteStation::AarfWifiRemoteStation(ns3::AarfWifiRemoteStation const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::AarfWifiRemoteStation const &', 'arg0')])
@@ -1747,32 +1995,6 @@
                    visibility='private', is_virtual=True)
     return
 
-def register_Ns3CompositePropagationLossModel_methods(root_module, cls):
-    ## composite-propagation-loss-model.h: ns3::CompositePropagationLossModel::CompositePropagationLossModel(ns3::CompositePropagationLossModel const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::CompositePropagationLossModel const &', 'arg0')])
-    ## composite-propagation-loss-model.h: static ns3::TypeId ns3::CompositePropagationLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## composite-propagation-loss-model.h: ns3::CompositePropagationLossModel::CompositePropagationLossModel() [constructor]
-    cls.add_constructor([])
-    ## composite-propagation-loss-model.h: double ns3::CompositePropagationLossModel::GetLoss(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('GetLoss', 
-                   'double', 
-                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, is_virtual=True)
-    ## composite-propagation-loss-model.h: void ns3::CompositePropagationLossModel::AddPropagationLossModel(ns3::Ptr<ns3::PropagationLossModel> pl) [member function]
-    cls.add_method('AddPropagationLossModel', 
-                   'void', 
-                   [param('ns3::Ptr< ns3::PropagationLossModel >', 'pl')])
-    ## composite-propagation-loss-model.h: void ns3::CompositePropagationLossModel::AddDefaults() [member function]
-    cls.add_method('AddDefaults', 
-                   'void', 
-                   [], 
-                   visibility='protected', is_virtual=True)
-    return
-
 def register_Ns3ConstantRateWifiManager_methods(root_module, cls):
     ## constant-rate-wifi-manager.h: ns3::ConstantRateWifiManager::ConstantRateWifiManager(ns3::ConstantRateWifiManager const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::ConstantRateWifiManager const &', 'arg0')])
@@ -1826,9 +2048,29 @@
                    is_const=True)
     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')])
+    ## error-rate-model.h: static ns3::TypeId ns3::ErrorRateModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## error-rate-model.h: ns3::ErrorRateModel::ErrorRateModel() [constructor]
+    cls.add_constructor([])
+    ## error-rate-model.h: double ns3::ErrorRateModel::CalculateSnr(ns3::WifiMode txMode, double ber) const [member function]
+    cls.add_method('CalculateSnr', 
+                   'double', 
+                   [param('ns3::WifiMode', 'txMode'), param('double', 'ber')], 
+                   is_const=True)
+    ## error-rate-model.h: double ns3::ErrorRateModel::GetChunkSuccessRate(ns3::WifiMode mode, double snr, uint32_t nbits) const [member function]
+    cls.add_method('GetChunkSuccessRate', 
+                   'double', 
+                   [param('ns3::WifiMode', 'mode'), param('double', 'snr'), param('uint32_t', 'nbits')], 
+                   is_const=True)
+    return
+
 def register_Ns3FriisPropagationLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: ns3::FriisPropagationLossModel::FriisPropagationLossModel(ns3::FriisPropagationLossModel const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::FriisPropagationLossModel const &', 'arg0')])
     ## propagation-loss-model.h: static ns3::TypeId ns3::FriisPropagationLossModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
@@ -1867,11 +2109,11 @@
                    'double', 
                    [], 
                    is_const=True)
-    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetLoss(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('GetLoss', 
+    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::DoGetLoss(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoGetLoss', 
                    'double', 
                    [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, is_virtual=True)
+                   is_const=True, visibility='private', is_virtual=True)
     return
 
 def register_Ns3IdealWifiManager_methods(root_module, cls):
@@ -1906,8 +2148,6 @@
     return
 
 def register_Ns3JakesPropagationLossModel_methods(root_module, cls):
-    ## jakes-propagation-loss-model.h: ns3::JakesPropagationLossModel::JakesPropagationLossModel(ns3::JakesPropagationLossModel const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::JakesPropagationLossModel const &', 'arg0')])
     ## jakes-propagation-loss-model.h: static ns3::TypeId ns3::JakesPropagationLossModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
@@ -1915,11 +2155,6 @@
                    is_static=True)
     ## jakes-propagation-loss-model.h: ns3::JakesPropagationLossModel::JakesPropagationLossModel() [constructor]
     cls.add_constructor([])
-    ## jakes-propagation-loss-model.h: double ns3::JakesPropagationLossModel::GetLoss(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('GetLoss', 
-                   'double', 
-                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, is_virtual=True)
     ## jakes-propagation-loss-model.h: void ns3::JakesPropagationLossModel::SetNRays(uint8_t nRays) [member function]
     cls.add_method('SetNRays', 
                    'void', 
@@ -1928,11 +2163,14 @@
     cls.add_method('SetNOscillators', 
                    'void', 
                    [param('uint8_t', 'nOscillators')])
+    ## jakes-propagation-loss-model.h: double ns3::JakesPropagationLossModel::DoGetLoss(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoGetLoss', 
+                   'double', 
+                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
     return
 
 def register_Ns3LogDistancePropagationLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: ns3::LogDistancePropagationLossModel::LogDistancePropagationLossModel(ns3::LogDistancePropagationLossModel const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::LogDistancePropagationLossModel const &', 'arg0')])
     ## propagation-loss-model.h: static ns3::TypeId ns3::LogDistancePropagationLossModel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
@@ -1949,19 +2187,15 @@
                    'double', 
                    [], 
                    is_const=True)
-    ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetReferenceModel(ns3::Ptr<ns3::PropagationLossModel> model) [member function]
-    cls.add_method('SetReferenceModel', 
+    ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetReference(double referenceDistance, double referenceLoss) [member function]
+    cls.add_method('SetReference', 
                    'void', 
-                   [param('ns3::Ptr< ns3::PropagationLossModel >', 'model')])
-    ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetReferenceDistance(double referenceDistance) [member function]
-    cls.add_method('SetReferenceDistance', 
-                   'void', 
-                   [param('double', 'referenceDistance')])
-    ## propagation-loss-model.h: double ns3::LogDistancePropagationLossModel::GetLoss(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('GetLoss', 
+                   [param('double', 'referenceDistance'), param('double', 'referenceLoss')])
+    ## propagation-loss-model.h: double ns3::LogDistancePropagationLossModel::DoGetLoss(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoGetLoss', 
                    'double', 
                    [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, is_virtual=True)
+                   is_const=True, visibility='private', is_virtual=True)
     return
 
 def register_Ns3NqapWifiMac_methods(root_module, cls):
@@ -2324,40 +2558,13 @@
 def register_Ns3WifiChannel_methods(root_module, cls):
     ## wifi-channel.h: ns3::WifiChannel::WifiChannel(ns3::WifiChannel const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::WifiChannel const &', 'arg0')])
+    ## wifi-channel.h: ns3::WifiChannel::WifiChannel() [constructor]
+    cls.add_constructor([])
     ## wifi-channel.h: static ns3::TypeId ns3::WifiChannel::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
                    [], 
                    is_static=True)
-    ## wifi-channel.h: ns3::WifiChannel::WifiChannel() [constructor]
-    cls.add_constructor([])
-    ## wifi-channel.h: uint32_t ns3::WifiChannel::GetNDevices() const [member function]
-    cls.add_method('GetNDevices', 
-                   'uint32_t', 
-                   [], 
-                   is_const=True, is_virtual=True)
-    ## wifi-channel.h: ns3::Ptr<ns3::NetDevice> ns3::WifiChannel::GetDevice(uint32_t i) const [member function]
-    cls.add_method('GetDevice', 
-                   'ns3::Ptr< ns3::NetDevice >', 
-                   [param('uint32_t', 'i')], 
-                   is_const=True, is_virtual=True)
-    ## wifi-channel.h: void ns3::WifiChannel::SetPropagationLossModel(ns3::Ptr<ns3::PropagationLossModel> loss) [member function]
-    cls.add_method('SetPropagationLossModel', 
-                   'void', 
-                   [param('ns3::Ptr< ns3::PropagationLossModel >', 'loss')])
-    ## wifi-channel.h: void ns3::WifiChannel::SetPropagationDelayModel(ns3::Ptr<ns3::PropagationDelayModel> delay) [member function]
-    cls.add_method('SetPropagationDelayModel', 
-                   'void', 
-                   [param('ns3::Ptr< ns3::PropagationDelayModel >', 'delay')])
-    ## wifi-channel.h: void ns3::WifiChannel::Add(ns3::Ptr<ns3::NetDevice> device, ns3::Ptr<ns3::WifiPhy> phy) [member function]
-    cls.add_method('Add', 
-                   'void', 
-                   [param('ns3::Ptr< ns3::NetDevice >', 'device'), param('ns3::Ptr< ns3::WifiPhy >', 'phy')])
-    ## wifi-channel.h: void ns3::WifiChannel::Send(ns3::Ptr<ns3::WifiPhy> sender, ns3::Ptr<const ns3::Packet> packet, double txPowerDbm, ns3::WifiMode wifiMode, ns3::WifiPreamble preamble) const [member function]
-    cls.add_method('Send', 
-                   'void', 
-                   [param('ns3::Ptr< ns3::WifiPhy >', 'sender'), param('ns3::Ptr< ns3::Packet const >', 'packet'), param('double', 'txPowerDbm'), param('ns3::WifiMode', 'wifiMode'), param('ns3::WifiPreamble', 'preamble')], 
-                   is_const=True)
     return
 
 def register_Ns3WifiNetDevice_methods(root_module, cls):
@@ -2382,10 +2589,6 @@
     cls.add_method('SetRemoteStationManager', 
                    'void', 
                    [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'manager')])
-    ## wifi-net-device.h: void ns3::WifiNetDevice::SetChannel(ns3::Ptr<ns3::WifiChannel> channel) [member function]
-    cls.add_method('SetChannel', 
-                   'void', 
-                   [param('ns3::Ptr< ns3::WifiChannel >', 'channel')])
     ## wifi-net-device.h: ns3::Ptr<ns3::WifiMac> ns3::WifiNetDevice::GetMac() const [member function]
     cls.add_method('GetMac', 
                    'ns3::Ptr< ns3::WifiMac >', 
@@ -2528,6 +2731,45 @@
                    visibility='private', is_virtual=True)
     return
 
+def register_Ns3YansWifiChannel_methods(root_module, cls):
+    ## yans-wifi-channel.h: ns3::YansWifiChannel::YansWifiChannel(ns3::YansWifiChannel const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::YansWifiChannel const &', 'arg0')])
+    ## yans-wifi-channel.h: static ns3::TypeId ns3::YansWifiChannel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## yans-wifi-channel.h: ns3::YansWifiChannel::YansWifiChannel() [constructor]
+    cls.add_constructor([])
+    ## yans-wifi-channel.h: uint32_t ns3::YansWifiChannel::GetNDevices() const [member function]
+    cls.add_method('GetNDevices', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## yans-wifi-channel.h: ns3::Ptr<ns3::NetDevice> ns3::YansWifiChannel::GetDevice(uint32_t i) const [member function]
+    cls.add_method('GetDevice', 
+                   'ns3::Ptr< ns3::NetDevice >', 
+                   [param('uint32_t', 'i')], 
+                   is_const=True, is_virtual=True)
+    ## yans-wifi-channel.h: void ns3::YansWifiChannel::Add(ns3::Ptr<ns3::YansWifiPhy> phy) [member function]
+    cls.add_method('Add', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::YansWifiPhy >', 'phy')])
+    ## yans-wifi-channel.h: void ns3::YansWifiChannel::SetPropagationLossModel(ns3::Ptr<ns3::PropagationLossModel> loss) [member function]
+    cls.add_method('SetPropagationLossModel', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::PropagationLossModel >', 'loss')])
+    ## yans-wifi-channel.h: void ns3::YansWifiChannel::SetPropagationDelayModel(ns3::Ptr<ns3::PropagationDelayModel> delay) [member function]
+    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]
+    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')], 
+                   is_const=True)
+    return
+
 def register_Ns3AarfWifiManager_methods(root_module, cls):
     ## aarf-wifi-manager.h: ns3::AarfWifiManager::AarfWifiManager(ns3::AarfWifiManager const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::AarfWifiManager const &', 'arg0')])
--- a/examples/mixed-wireless.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/examples/mixed-wireless.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -132,10 +132,12 @@
   // Create the backbone wifi net devices and install them into the nodes in 
   // our container
   //
+  YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
+  YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
+  wifiPhy.SetChannel (wifiChannel.Create ());
   WifiHelper wifi;
   wifi.SetMac ("ns3::AdhocWifiMac");
-  wifi.SetPhy ("ns3::WifiPhy");
-  NetDeviceContainer backboneDevices = wifi.Install (backbone);
+  NetDeviceContainer backboneDevices = wifi.Install (wifiPhy, backbone);
   //
   // Add the IPv4 protocol stack to the nodes in our container
   //
@@ -244,8 +246,8 @@
       //
       WifiHelper wifiInfra;
       wifiInfra.SetMac ("ns3::AdhocWifiMac");
-      wifiInfra.SetPhy ("ns3::WifiPhy");
-      NetDeviceContainer infraDevices = wifiInfra.Install (infra);
+      wifiPhy.SetChannel (wifiChannel.Create ());
+      NetDeviceContainer infraDevices = wifiInfra.Install (wifiPhy, infra);
 
       // Add the IPv4 protocol stack to the nodes in our container
       //
@@ -332,14 +334,14 @@
   //
   std::ofstream ascii;
   ascii.open ("mixed-wireless.tr");
-  WifiHelper::EnableAsciiAll (ascii);
+  YansWifiPhyHelper::EnableAsciiAll (ascii);
   CsmaHelper::EnableAsciiAll (ascii);
   // Look at nodes 11, 13 only
   //WifiHelper::EnableAscii (ascii, 11, 0); 
   //WifiHelper::EnableAscii (ascii, 13, 0); 
 
   // Let's do a pcap trace on the backbone devices
-  WifiHelper::EnablePcap ("mixed-wireless", backboneDevices); 
+  YansWifiPhyHelper::EnablePcap ("mixed-wireless", backboneDevices); 
   // Let's additionally trace the application Sink, ifIndex 0
   CsmaHelper::EnablePcap ("mixed-wireless", appSink->GetId (), 0);
 
--- a/examples/stats/wifi-example-sim.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/examples/stats/wifi-example-sim.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -129,8 +129,10 @@
   NS_LOG_INFO("Installing WiFi and Internet stack.");
   WifiHelper wifi;
   wifi.SetMac("ns3::AdhocWifiMac");
-  wifi.SetPhy("ns3::WifiPhy");
-  NetDeviceContainer nodeDevices = wifi.Install(nodes);
+  YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
+  YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
+  wifiPhy.SetChannel (wifiChannel.Create ());
+  NetDeviceContainer nodeDevices = wifi.Install(wifiPhy, nodes);
 
   InternetStackHelper internet;
   internet.Install(nodes);
--- a/examples/wifi-adhoc.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/examples/wifi-adhoc.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -36,7 +36,7 @@
 public:
   Experiment ();
   Experiment (std::string name);
-  GnuplotDataset Run (const WifiHelper &wifi);
+  GnuplotDataset Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy, const YansWifiChannelHelper &wifiChannel);
 private:
   void ReceivePacket (Ptr<Socket> socket);
   void SetPosition (Ptr<Node> node, Vector position);
@@ -110,7 +110,7 @@
 }
 
 GnuplotDataset
-Experiment::Run (const WifiHelper &wifi)
+Experiment::Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy, const YansWifiChannelHelper &wifiChannel)
 {
   m_bytesTotal = 0;
 
@@ -120,7 +120,9 @@
   PacketSocketHelper packetSocket;
   packetSocket.Install (c);
 
-  NetDeviceContainer devices = wifi.Install (c);
+  YansWifiPhyHelper phy = wifiPhy;
+  phy.SetChannel (wifiChannel.Create ());
+  NetDeviceContainer devices = wifi.Install (phy, c);
 
   MobilityHelper mobility;
   Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
@@ -168,91 +170,92 @@
   Gnuplot gnuplot = Gnuplot ("reference-rates.png");
 
   Experiment experiment;
-  WifiHelper wifi;
+  WifiHelper wifi = WifiHelper::Default ();
+  YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
+  YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
   GnuplotDataset dataset;
 
   wifi.SetMac ("ns3::AdhocWifiMac");
-  wifi.SetPhy ("ns3::WifiPhy");
 
   NS_LOG_DEBUG ("54");
   experiment = Experiment ("54mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-54mbs"));
-  dataset = experiment.Run (wifi);
+  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("48");
   experiment = Experiment ("48mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-48mbs"));
-  dataset = experiment.Run (wifi);
+  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("36");
   experiment = Experiment ("36mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-36mbs"));
-  dataset = experiment.Run (wifi);
+  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("24");
   experiment = Experiment ("24mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-24mbs"));
-  dataset = experiment.Run (wifi);
+  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("18");
   experiment = Experiment ("18mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-18mbs"));
-  dataset = experiment.Run (wifi);
+  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("12");
   experiment = Experiment ("12mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-12mbs"));
-  dataset = experiment.Run (wifi);
+  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("9");
   experiment = Experiment ("9mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-9mbs"));
-  dataset = experiment.Run (wifi);
+  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("6");
   experiment = Experiment ("6mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                 "DataMode", StringValue ("wifia-6mbs"));
-  dataset = experiment.Run (wifi);
+  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   gnuplot.GenerateOutput (std::cout);
 
 
   gnuplot = Gnuplot ("rate-control.png");
-  Config::SetDefault ("ns3::WifiPhy::Standard", StringValue ("holland"));
+  Config::SetDefault ("ns3::YansWifiPhy::Standard", StringValue ("holland"));
 
 
   NS_LOG_DEBUG ("arf");
   experiment = Experiment ("arf");
   wifi.SetRemoteStationManager ("ns3::ArfWifiManager");
-  dataset = experiment.Run (wifi);
+  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("aarf");
   experiment = Experiment ("aarf");
   wifi.SetRemoteStationManager ("ns3::AarfWifiManager");
-  dataset = experiment.Run (wifi);
+  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("ideal");
   experiment = Experiment ("ideal");
   wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
-  dataset = experiment.Run (wifi);
+  dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
   gnuplot.AddDataset (dataset);
 
   gnuplot.GenerateOutput (std::cout);
--- a/examples/wifi-ap.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/examples/wifi-ap.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -117,7 +117,7 @@
   // disable fragmentation
   Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));
 
-  WifiHelper wifi;
+  WifiHelper wifi = WifiHelper::Default ();
   MobilityHelper mobility;
   NodeContainer stas;
   NodeContainer ap;
@@ -131,25 +131,21 @@
   packetSocket.Install (stas);
   packetSocket.Install (ap);
 
-  Ptr<WifiChannel> channel = CreateObject<WifiChannel> ();
-  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
-  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
-  log->SetReferenceModel (CreateObject<FriisPropagationLossModel> ());
-  channel->SetPropagationLossModel (log);
-
+  YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
+  YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
+  wifiPhy.SetChannel (wifiChannel.Create ());
   Ssid ssid = Ssid ("wifi-default");
-  wifi.SetPhy ("ns3::WifiPhy");
   wifi.SetRemoteStationManager ("ns3::ArfWifiManager");
   // setup stas.
   wifi.SetMac ("ns3::NqstaWifiMac", 
                "Ssid", SsidValue (ssid),
                "ActiveProbing", BooleanValue (false));
-  staDevs = wifi.Install (stas, channel);
+  staDevs = wifi.Install (wifiPhy, stas);
   // setup ap.
   wifi.SetMac ("ns3::NqapWifiMac", "Ssid", SsidValue (ssid),
                "BeaconGeneration", BooleanValue (true),
                "BeaconInterval", TimeValue (Seconds (2.5)));
-  wifi.Install (ap, channel);
+  wifi.Install (wifiPhy, ap);
 
   // mobility.
   mobility.Install (stas);
@@ -174,10 +170,10 @@
 
   Config::Connect ("/NodeList/*/DeviceList/*/Tx", MakeCallback (&DevTxTrace));
   Config::Connect ("/NodeList/*/DeviceList/*/Rx", MakeCallback (&DevRxTrace));
-  Config::Connect ("/NodeList/*/DeviceList/*/Phy/RxOk", MakeCallback (&PhyRxOkTrace));
-  Config::Connect ("/NodeList/*/DeviceList/*/Phy/RxError", MakeCallback (&PhyRxErrorTrace));
-  Config::Connect ("/NodeList/*/DeviceList/*/Phy/Tx", MakeCallback (&PhyTxTrace));
-  Config::Connect ("/NodeList/*/DeviceList/*/Phy/State", MakeCallback (&PhyStateTrace));
+  Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/RxOk", MakeCallback (&PhyRxOkTrace));
+  Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/RxError", MakeCallback (&PhyRxErrorTrace));
+  Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/Tx", MakeCallback (&PhyTxTrace));
+  Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/State", MakeCallback (&PhyStateTrace));
 
   Simulator::Run ();
 
--- a/examples/wifi-wired-bridging.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/examples/wifi-wired-bridging.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -14,17 +14,6 @@
 
 using namespace ns3;
 
-Ptr<WifiChannel>
-CreateChannel (void)
-{
-  Ptr<WifiChannel> channel = CreateObject<WifiChannel> ();
-  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
-  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
-  log->SetReferenceModel (CreateObject<FriisPropagationLossModel> ());
-  channel->SetPropagationLossModel (log);
-  return channel;
-}
-
 int main (int argc, char *argv[])
 {
   uint32_t nWifis = 2;
@@ -74,12 +63,12 @@
       Ipv4InterfaceContainer apInterface;
       MobilityHelper mobility;
       BridgeHelper bridge;
-      WifiHelper wifi;
-      Ptr<WifiChannel> channel;
+      WifiHelper wifi = WifiHelper::Default ();
+      YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
+      YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
+      wifiPhy.SetChannel (wifiChannel.Create ());
 
       sta.Create (nStas);
-      wifi.SetPhy ("ns3::WifiPhy");
-      channel = CreateChannel ();
       ip.NewNetwork ();
       mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
 				     "MinX", DoubleValue (wifiX),
@@ -97,7 +86,7 @@
 		   "Ssid", SsidValue (ssid),
 		   "BeaconGeneration", BooleanValue (true),
 		   "BeaconInterval", TimeValue (Seconds (2.5)));
-      apDev = wifi.Install (backboneNodes.Get (i), channel);
+      apDev = wifi.Install (wifiPhy, backboneNodes.Get (i));
       apInterface = ip.Assign (apDev);
       bridge.Install (backboneNodes.Get (i), NetDeviceContainer (apDev, backboneDevices.Get (i)));
 
@@ -112,7 +101,7 @@
       wifi.SetMac ("ns3::NqstaWifiMac",
 		   "Ssid", SsidValue (ssid),
 		   "ActiveProbing", BooleanValue (false));
-      staDev = wifi.Install (sta, channel);
+      staDev = wifi.Install (wifiPhy, sta);
       staInterface = ip.Assign (staDev);
 
       // save everything in containers.
@@ -151,8 +140,8 @@
   apps.Stop (Seconds (3.0));
   
 
-  WifiHelper::EnablePcap ("wifi-wire-bridging", staNodes[1].Get (1));
-  WifiHelper::EnablePcap ("wifi-wire-bridging", staNodes[0].Get (0));
+  YansWifiPhyHelper::EnablePcap ("wifi-wire-bridging", staNodes[1].Get (1));
+  YansWifiPhyHelper::EnablePcap ("wifi-wire-bridging", staNodes[0].Get (0));
   std::ofstream os;
   os.open ("wifi-wire-bridging.mob");
   MobilityHelper::EnableAsciiAll (os);
--- a/samples/main-propagation-loss.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/samples/main-propagation-loss.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -30,7 +30,6 @@
   Ptr<StaticMobilityModel> a = CreateObject<StaticMobilityModel> ();
   Ptr<StaticMobilityModel> b = CreateObject<StaticMobilityModel> ();
   Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
-  log->SetReferenceModel (CreateObject<FriisPropagationLossModel> ());
 
   Ptr<PropagationLossModel> model = log;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/flow-id-tag.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -0,0 +1,88 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * 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>
+ */
+#include "flow-id-tag.h"
+
+namespace ns3 {
+
+TypeId 
+FlowIdTag::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::FlowIdTag")
+    .SetParent<Tag> ()
+    .AddConstructor<FlowIdTag> ()
+    ;
+  return tid;
+}
+TypeId 
+FlowIdTag::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+uint32_t 
+FlowIdTag::GetSerializedSize (void) const
+{
+  return 4;
+}
+void 
+FlowIdTag::Serialize (TagBuffer buf) const
+{
+  buf.WriteU32 (m_flowId);
+}
+void 
+FlowIdTag::Deserialize (TagBuffer buf)
+{
+  m_flowId = buf.ReadU32 ();
+}
+void 
+FlowIdTag::Print (std::ostream &os) const
+{
+  os << "FlowId=" << m_flowId;
+}
+FlowIdTag::FlowIdTag ()
+  : Tag () 
+{}
+
+FlowIdTag::FlowIdTag (uint32_t id)
+  : Tag (),
+    m_flowId (id)
+{}
+
+void
+FlowIdTag::SetFlowId (uint32_t id)
+{
+  m_flowId = id;
+}
+uint32_t
+FlowIdTag::GetFlowId (void) const
+{
+  return m_flowId;
+}
+
+uint32_t 
+FlowIdTag::AllocateFlowId (void)
+{
+  static uint32_t nextFlowId = 1;
+  uint32_t flowId = nextFlowId;
+  nextFlowId++;
+  return flowId;
+}
+
+} // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/flow-id-tag.h	Mon Nov 24 06:36:05 2008 +0100
@@ -0,0 +1,47 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * 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>
+ */
+#ifndef FLOW_ID_TAG_H
+#define FLOW_ID_TAG_H
+
+#include "ns3/tag.h"
+
+namespace ns3 {
+
+class FlowIdTag : public Tag
+{
+public:
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (TagBuffer buf) const;
+  virtual void Deserialize (TagBuffer buf);
+  virtual void Print (std::ostream &os) const;
+  FlowIdTag ();
+  FlowIdTag (uint32_t flowId);
+  void SetFlowId (uint32_t flowId);
+  uint32_t GetFlowId (void) const;
+  static uint32_t AllocateFlowId (void);
+private:
+  uint32_t m_flowId;
+};
+
+} // namespace ns3
+
+#endif /* FLOW_ID_TAG_H */
--- a/src/contrib/wscript	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/contrib/wscript	Mon Nov 24 06:36:05 2008 +0100
@@ -20,6 +20,7 @@
         'delay-jitter-estimation.cc',
         'attribute-iterator.cc',
         'config-store.cc',
+        'flow-id-tag.cc',
         ]
 
     headers = bld.create_obj('ns3header')
@@ -29,6 +30,7 @@
         'gnuplot.h',
         'delay-jitter-estimation.h',
         'config-store.h',
+        'flow-id-tag.h',
         ]
 
     if bld.env()['ENABLE_GTK_CONFIG_STORE']:
--- a/src/core/attribute-list.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/core/attribute-list.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -256,4 +256,59 @@
   return true;
 }
 
+UnsafeAttributeList::UnsafeAttributeList ()
+{}
+UnsafeAttributeList::UnsafeAttributeList (const UnsafeAttributeList &o)
+{
+  for (uint32_t i = 0; i < o.m_attributes.size (); ++i)
+    {
+      Set (o.m_attributes[i].first, *(o.m_attributes[i].second));
+    }
+}
+UnsafeAttributeList &
+UnsafeAttributeList::operator = (const UnsafeAttributeList &o)
+{
+  m_attributes.clear ();
+  for (uint32_t i = 0; i < o.m_attributes.size (); ++i)
+    {
+      Set (o.m_attributes[i].first, *(o.m_attributes[i].second));
+    }
+  return *this;
+}
+
+UnsafeAttributeList::~UnsafeAttributeList ()
+{
+  m_attributes.clear ();
+}
+void 
+UnsafeAttributeList::Set (std::string name, const AttributeValue &param)
+{
+  if (name == "")
+    {
+      return;
+    }
+  for (uint32_t i = 0; i < m_attributes.size (); ++i)
+    {
+      if (m_attributes[i].first == name)
+        {
+          m_attributes[i].second = param.Copy ();
+          return;
+        }
+    }
+  m_attributes.push_back (std::make_pair (name, param.Copy ()));
+}
+
+AttributeList 
+UnsafeAttributeList::GetSafe (std::string tidName) const
+{
+  AttributeList list;
+  for (uint32_t i = 0; i < m_attributes.size (); ++i)
+    {
+      TypeId tid = TypeId::LookupByName (tidName);
+      list.SetWithTid (tid, m_attributes[i].first, *m_attributes[i].second);
+    }
+  return list;
+}
+
+
 } // namespace ns3
--- a/src/core/attribute-list.h	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/core/attribute-list.h	Mon Nov 24 06:36:05 2008 +0100
@@ -108,6 +108,21 @@
   Attrs m_attributes;
 };
 
+class UnsafeAttributeList
+{
+public:
+  UnsafeAttributeList ();
+  UnsafeAttributeList (const UnsafeAttributeList &o);
+  UnsafeAttributeList &operator = (const UnsafeAttributeList &o);
+  ~UnsafeAttributeList ();
+  
+  void Set (std::string name, const AttributeValue &param);
+
+  AttributeList GetSafe (std::string name) const;
+private:
+  std::vector<std::pair<std::string,Ptr<AttributeValue> > > m_attributes;
+};
+
 } // namespace ns3
 
 #endif /* ATTRIBUTE_LIST_H */
--- a/src/core/object-factory.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/core/object-factory.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -50,6 +50,12 @@
   m_parameters.SetWithTid (m_tid, name, value);
 }
 
+void 
+ObjectFactory::Set (const AttributeList &list)
+{
+  m_parameters = list;
+}
+
 TypeId 
 ObjectFactory::GetTypeId (void) const
 {
--- a/src/core/object-factory.h	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/core/object-factory.h	Mon Nov 24 06:36:05 2008 +0100
@@ -59,6 +59,8 @@
    */
   void Set (std::string name, const AttributeValue &value);
 
+  void Set (const AttributeList &list);
+
   /**
    * \returns the currently-selected TypeId to use to create an object
    *          instance.
--- a/src/core/type-id.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/core/type-id.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -132,7 +132,7 @@
 struct IidManager::IidInformation *
 IidManager::LookupInformation (uint16_t uid) const
 {
-  NS_ASSERT (uid <= m_information.size ());
+  NS_ASSERT (uid <= m_information.size () && uid != 0);
   return const_cast<struct IidInformation *> (&m_information[uid-1]);
 }
 
--- a/src/devices/wifi/composite-propagation-loss-model.cc	Wed Nov 19 16:41:17 2008 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 INRIA
- *
- * 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: Federico Maguolo <maguolof@dei.unipd.it>
- */
-
-#include "ns3/simulator.h"
-#include "ns3/uinteger.h"
-#include "ns3/double.h"
-#include "ns3/random-variable.h"
-#include "ns3/mobility-model.h"
-#include "composite-propagation-loss-model.h"
-#include <math.h>
-
-namespace ns3 {
-
-
-
-NS_OBJECT_ENSURE_REGISTERED (CompositePropagationLossModel);
-
-TypeId
-CompositePropagationLossModel::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::CompositePropagationLossModel")
-    .SetParent<PropagationLossModel> ()
-    .AddConstructor<CompositePropagationLossModel> ()
-    ;
-  return tid;
-}
-
-CompositePropagationLossModel::CompositePropagationLossModel ()
-{
-  AddDefaults ();
-}
-
-CompositePropagationLossModel::~CompositePropagationLossModel ()
-{}
-
-void
-CompositePropagationLossModel::AddDefaults ()
-{}
-
-void
-CompositePropagationLossModel::AddPropagationLossModel (Ptr<PropagationLossModel> pl)
-{
-  m_propagationModels.push_back (pl);
-}
-
-double
-CompositePropagationLossModel::GetLoss (Ptr<MobilityModel> a,
-				        Ptr<MobilityModel> b) const
-{
-  double rxc = 0.0;
-  for(PropagationModelList::const_iterator i = m_propagationModels.begin (); 
-                                           i != m_propagationModels.end (); 
-					   i++) {
-    rxc += (*i)->GetLoss (a, b);
-  }
-  
-  return rxc;
-}
-
-} // namespace ns3
-
--- a/src/devices/wifi/composite-propagation-loss-model.h	Wed Nov 19 16:41:17 2008 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 INRIA
- *
- * 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: Federico Maguolo <maguolof@dei.unipd.it>
- */
-#ifndef PROPAGATION_COMP_MODEL_H
-#define PROPAGATION_COMP_MODEL_H
-
-#include "ns3/nstime.h"
-#include "propagation-loss-model.h"
-
-namespace ns3 {
-
-/**
- * \brief a Composite propagation loss model
- *
- * This model is use to compute the receivng power
- * using more than one propagation loss model (e.g. distance loss 
- * and jakes).
- *
- * The received power is computed considering the cascade of the models
- */
-class CompositePropagationLossModel : public PropagationLossModel {
-public:
-  static TypeId GetTypeId (void);
-  CompositePropagationLossModel ();
-  virtual ~CompositePropagationLossModel ();
-
-  virtual double GetLoss (Ptr<MobilityModel> a,
-			  Ptr<MobilityModel> b) const;
-  /**
-   * \param pl the propagation loss model to add
-   *
-   * Insert a propagation loss model to the composite.
-   */
-  void AddPropagationLossModel (Ptr<PropagationLossModel> pl);
-protected:
-  virtual void AddDefaults (void);
-private:
-  typedef std::vector<Ptr<PropagationLossModel> > PropagationModelList;
-  PropagationModelList m_propagationModels;
-};
-
-
-} // namespace ns3
-
-#endif /* PROPAGATION_COMP_MODEL_H */
-
-
--- a/src/devices/wifi/dcf-manager.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/dcf-manager.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -180,8 +180,8 @@
   virtual void NotifyTxStart (Time duration) {
     m_dcf->NotifyTxStartNow (duration);
   }
-  virtual void NotifyCcaBusyStart (Time duration) {
-    m_dcf->NotifyCcaBusyStartNow (duration);
+  virtual void NotifyMaybeCcaBusyStart (Time duration) {
+    m_dcf->NotifyMaybeCcaBusyStartNow (duration);
   }
 private:
   ns3::DcfManager *m_dcf;
@@ -528,7 +528,7 @@
   m_lastTxDuration = duration;
 }
 void 
-DcfManager::NotifyCcaBusyStartNow (Time duration)
+DcfManager::NotifyMaybeCcaBusyStartNow (Time duration)
 {
   MY_DEBUG ("busy start for "<<duration);
   UpdateBackoff ();
--- a/src/devices/wifi/dcf-manager.h	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/dcf-manager.h	Mon Nov 24 06:36:05 2008 +0100
@@ -220,7 +220,7 @@
    *
    * Notify the DCF that a CCA busy period has just started.
    */
-  void NotifyCcaBusyStartNow (Time duration);
+  void NotifyMaybeCcaBusyStartNow (Time duration);
   /**
    * \param duration the value of the received NAV.
    *
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/error-rate-model.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -0,0 +1,294 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006 INRIA
+ *
+ * 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>
+ */
+#include "error-rate-model.h"
+#include "wifi-phy.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("ErrorRateModel");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (ErrorRateModel);
+
+TypeId 
+ErrorRateModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::ErrorRateModel")
+    .SetParent<Object> ()
+    .AddConstructor<ErrorRateModel> ()
+    ;
+  return tid;
+}
+
+ErrorRateModel::ErrorRateModel ()
+{}
+
+double 
+ErrorRateModel::CalculateSnr (WifiMode txMode, double ber) const
+{
+  // This is a very simple binary search.
+  double low, high, precision;
+  low = 1e-25;
+  high = 1e25;
+  precision = 1e-12;
+  while (high - low > precision) 
+    {
+      NS_ASSERT (high >= low);
+      double middle = low + (high - low) / 2;
+      if ((1 - GetChunkSuccessRate (txMode, middle, 1)) > ber) 
+        {
+          low = middle;
+        } 
+      else 
+        {
+          high = middle;
+        }
+    }
+  return low;
+}
+
+
+double 
+ErrorRateModel::Log2 (double val) const
+{
+  return log(val) / log(2.0);
+}
+double 
+ErrorRateModel::GetBpskBer (double snr, uint32_t signalSpread, uint32_t phyRate) const
+{
+  double EbNo = snr * signalSpread / phyRate;
+  double z = sqrt(EbNo);
+  double ber = 0.5 * erfc(z);
+  NS_LOG_INFO ("bpsk snr="<<snr<<" ber="<<ber);
+  return ber;
+}
+double 
+ErrorRateModel::GetQamBer (double snr, unsigned int m, uint32_t signalSpread, uint32_t phyRate) const
+{
+  double EbNo = snr * signalSpread / phyRate;
+  double z = sqrt ((1.5 * Log2 (m) * EbNo) / (m - 1.0));
+  double z1 = ((1.0 - 1.0 / sqrt (m)) * erfc (z)) ;
+  double z2 = 1 - pow ((1-z1), 2.0);
+  double ber = z2 / Log2 (m);
+  NS_LOG_INFO ("Qam m="<<m<<" rate=" << phyRate << " snr="<<snr<<" ber="<<ber);
+  return ber;
+}
+uint32_t
+ErrorRateModel::Factorial (uint32_t k) const
+{
+  uint32_t fact = 1;
+  while (k > 0) 
+    {
+      fact *= k;
+      k--;
+    }
+  return fact;
+}
+double 
+ErrorRateModel::Binomial (uint32_t k, double p, uint32_t n) const
+{
+  double retval = Factorial (n) / (Factorial (k) * Factorial (n-k)) * pow (p, k) * pow (1-p, n-k);
+  return retval;
+}
+double 
+ErrorRateModel::CalculatePdOdd (double ber, unsigned int d) const
+{
+  NS_ASSERT ((d % 2) == 1);
+  unsigned int dstart = (d + 1) / 2;
+  unsigned int dend = d;
+  double pd = 0;
+
+  for (unsigned int i = dstart; i < dend; i++) 
+    {
+      pd += Binomial (i, ber, d);
+    }
+  return pd;
+}
+double 
+ErrorRateModel::CalculatePdEven (double ber, unsigned int d) const
+{
+  NS_ASSERT ((d % 2) == 0);
+  unsigned int dstart = d / 2 + 1;
+  unsigned int dend = d;
+  double pd = 0;
+
+  for (unsigned int i = dstart; i < dend; i++)
+    {
+      pd +=  Binomial (i, ber, d);
+    }
+  pd += 0.5 * Binomial (d / 2, ber, d);
+
+  return pd;
+}
+
+double 
+ErrorRateModel::CalculatePd (double ber, unsigned int d) const
+{
+  double pd;
+  if ((d % 2) == 0) 
+    {
+      pd = CalculatePdEven (ber, d);
+    } 
+  else 
+    {
+      pd = CalculatePdOdd (ber, d);
+    }
+  return pd;
+}
+
+double
+ErrorRateModel::GetFecBpskBer (double snr, double nbits, 
+                         uint32_t signalSpread, uint32_t phyRate,
+                         uint32_t dFree, uint32_t adFree) const
+{
+  double ber = GetBpskBer (snr, signalSpread, phyRate);
+  if (ber == 0.0) 
+    {
+      return 1.0;
+    }
+  double pd = CalculatePd (ber, dFree);
+  double pmu = adFree * pd;
+  pmu = std::min (pmu, 1.0);
+  double pms = pow (1 - pmu, nbits);
+  return pms;
+}
+
+double
+ErrorRateModel::GetFecQamBer (double snr, uint32_t nbits, 
+                       uint32_t signalSpread,
+                       uint32_t phyRate,
+                       uint32_t m, uint32_t dFree,
+                       uint32_t adFree, uint32_t adFreePlusOne) const
+{
+  double ber = GetQamBer (snr, m, signalSpread, phyRate);
+  if (ber == 0.0) 
+    {
+      return 1.0;
+    }
+  /* first term */
+  double pd = CalculatePd (ber, dFree);
+  double pmu = adFree * pd;
+  /* second term */
+  pd = CalculatePd (ber, dFree + 1);
+  pmu += adFreePlusOne * pd;
+  pmu = std::min (pmu, 1.0);
+  double pms = pow (1 - pmu, nbits);
+  return pms;
+}
+
+double 
+ErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const
+{
+  if (mode == WifiPhy::g_6mba)
+    {
+      return GetFecBpskBer (snr, 
+                            nbits,
+                            mode.GetBandwidth (), // signal spread
+                            mode.GetPhyRate (), // phy rate
+                            10, // dFree
+                            11 // adFree
+                            );      
+    }
+  else if (mode == WifiPhy::g_9mba)
+    {
+      return GetFecBpskBer (snr, 
+                            nbits,
+                            mode.GetBandwidth (), // signal spread
+                            mode.GetPhyRate (), // phy rate
+                            5, // dFree
+                            8 // adFree
+                            );
+    }
+  else if (mode == WifiPhy::g_12mba)
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           4,  // m 
+                           10, // dFree
+                           11, // adFree
+                           0   // adFreePlusOne
+                           );
+    }
+  else if (mode == WifiPhy::g_18mba)
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           4, // m
+                           5, // dFree
+                           8, // adFree
+                           31 // adFreePlusOne
+                           );
+    }
+  else if (mode == WifiPhy::g_24mba)
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           16, // m
+                           10, // dFree
+                           11, // adFree
+                           0   // adFreePlusOne
+                           );
+    }
+  else if (mode == WifiPhy::g_36mba)
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           16, // m
+                           5,  // dFree
+                           8,  // adFree
+                           31  // adFreePlusOne
+                           );
+    }
+  else if (mode == WifiPhy::g_48mba)
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           64, // m
+                           6,  // dFree
+                           1,  // adFree
+                           16  // adFreePlusOne
+                           );
+    }
+  else if (mode == WifiPhy::g_54mba)
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           64, // m
+                           5,  // dFree
+                           8,  // adFree
+                           31  // adFreePlusOne
+                           );
+    }
+  return 0;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/error-rate-model.h	Mon Nov 24 06:36:05 2008 +0100
@@ -0,0 +1,68 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006 INRIA
+ *
+ * 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>
+ */
+#ifndef ERROR_RATE_MODEL_H
+#define ERROR_RATE_MODEL_H
+
+#include <stdint.h>
+#include "wifi-mode.h"
+#include "ns3/object.h"
+
+namespace ns3 {
+
+class ErrorRateModel : public Object
+{
+public:
+  static TypeId GetTypeId (void);
+
+  ErrorRateModel ();
+
+  /**
+   * \param txMode a specific transmission mode
+   * \param ber a target ber
+   * \returns the snr which corresponds to the requested
+   *          ber.
+   */
+  double CalculateSnr (WifiMode txMode, double ber) const;
+
+  double GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const;
+
+private:
+  double Log2 (double val) const;
+  double GetBpskBer (double snr, uint32_t signalSpread, uint32_t phyRate) const;
+  double GetQamBer (double snr, unsigned int m, uint32_t signalSpread, uint32_t phyRate) const;
+  uint32_t Factorial (uint32_t k) const;
+  double Binomial (uint32_t k, double p, uint32_t n) const;
+  double CalculatePdOdd (double ber, unsigned int d) const;
+  double CalculatePdEven (double ber, unsigned int d) const;
+  double CalculatePd (double ber, unsigned int d) const;
+  double GetFecBpskBer (double snr, double nbits, 
+                        uint32_t signalSpread, uint32_t phyRate,
+                        uint32_t dFree, uint32_t adFree) const;
+  double GetFecQamBer (double snr, uint32_t nbits, 
+                       uint32_t signalSpread,
+                       uint32_t phyRate,
+                       uint32_t m, uint32_t dfree,
+                       uint32_t adFree, uint32_t adFreePlusOne) const;
+};
+
+
+} // namespace ns3
+
+#endif /* ERROR_RATE_MODEL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/interference-helper.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -0,0 +1,445 @@
+#include "interference-helper.h"
+#include "wifi-phy.h"
+#include "error-rate-model.h"
+#include "ns3/simulator.h"
+#include "ns3/log.h"
+#include <algorithm>
+
+NS_LOG_COMPONENT_DEFINE ("InterferenceHelper");
+
+namespace ns3 {
+
+/****************************************************************
+ *       Phy event class
+ ****************************************************************/
+
+InterferenceHelper::Event::Event (uint32_t size, WifiMode payloadMode, 
+					       enum WifiPreamble preamble,
+					       Time duration, double rxPower)
+  : m_size (size),
+    m_payloadMode (payloadMode),
+    m_preamble (preamble),
+    m_startTime (Simulator::Now ()),
+    m_endTime (m_startTime + duration),
+    m_rxPowerW (rxPower)
+{}
+InterferenceHelper::Event::~Event ()
+{}
+  
+Time 
+InterferenceHelper::Event::GetDuration (void) const 
+{
+  return m_endTime - m_startTime;
+}
+Time 
+InterferenceHelper::Event::GetStartTime (void) const
+{
+  return m_startTime;
+}
+Time 
+InterferenceHelper::Event::GetEndTime (void) const
+{
+  return m_endTime;
+}
+bool 
+InterferenceHelper::Event::Overlaps (Time time) const
+{
+  if (m_startTime <= time &&
+      m_endTime >= time) 
+    {
+      return true;
+    } 
+  else 
+    {
+      return false;
+    }
+}
+double 
+InterferenceHelper::Event::GetRxPowerW (void) const
+{
+  return m_rxPowerW;
+}
+uint32_t 
+InterferenceHelper::Event::GetSize (void) const
+{
+  return m_size;
+}
+WifiMode 
+InterferenceHelper::Event::GetPayloadMode (void) const
+{
+  return m_payloadMode;
+}
+enum WifiPreamble 
+InterferenceHelper::Event::GetPreambleType (void) const
+{
+  return m_preamble;
+}
+
+/****************************************************************
+ *       Class which records SNIR change events for a 
+ *       short period of time.
+ ****************************************************************/
+
+InterferenceHelper::NiChange::NiChange (Time time, double delta)
+  : m_time (time), m_delta (delta) 
+{}
+Time
+InterferenceHelper::NiChange::GetTime (void) const
+{
+  return m_time;
+}
+double 
+InterferenceHelper::NiChange::GetDelta (void) const
+{
+  return m_delta;
+}
+bool 
+InterferenceHelper::NiChange::operator < (InterferenceHelper::NiChange const &o) const
+{
+  return (m_time < o.m_time)?true:false;
+}
+
+/****************************************************************
+ *       The actual InterferenceHelper
+ ****************************************************************/
+
+InterferenceHelper::InterferenceHelper ()
+  : m_80211a (false),
+    m_errorRateModel (0)
+{}
+InterferenceHelper::~InterferenceHelper ()
+{
+  m_errorRateModel = 0;
+}
+
+Ptr<InterferenceHelper::Event> 
+InterferenceHelper::Add (uint32_t size, WifiMode payloadMode, 
+			 enum WifiPreamble preamble,
+			 Time duration, double rxPowerW)
+{
+  Ptr<InterferenceHelper::Event> event;
+
+  event = Create<InterferenceHelper::Event> 
+    (size,
+     payloadMode,
+     preamble,
+     duration,
+     rxPowerW);
+
+  AppendEvent (event);
+  return event;
+}
+
+Time 
+InterferenceHelper::GetMaxPacketDuration (void) const
+{
+  return m_maxPacketDuration;
+}
+
+void 
+InterferenceHelper::SetNoiseFloorW (double noiseFloor)
+{
+  m_noiseFloorW = noiseFloor;
+}
+
+double 
+InterferenceHelper::GetNoiseFloorW (void) const
+{
+  return m_noiseFloorW;
+}
+
+void 
+InterferenceHelper::SetErrorRateModel (Ptr<ErrorRateModel> rate)
+{
+  m_errorRateModel = rate;
+}
+
+Ptr<ErrorRateModel> 
+InterferenceHelper::GetErrorRateModel (void) const
+{
+  return m_errorRateModel;
+}
+
+Time 
+InterferenceHelper::GetEnergyDuration (double energyW)
+{
+  Time now = Simulator::Now ();
+
+  // first, we iterate over all events and, each event
+  // which contributes energy to the channel now is 
+  // appended to the noise interference array.
+  Events::const_iterator i = m_events.begin ();
+  double noiseInterferenceW = 0.0;
+  NiChanges ni;
+  while (i != m_events.end ()) 
+    {
+      Ptr<Event> ev = *i;
+      NS_ASSERT (ev->GetStartTime () <= now);
+      if (ev->GetEndTime () > now)
+	{
+          ni.push_back (NiChange (ev->GetEndTime (), -ev->GetRxPowerW ()));
+          noiseInterferenceW += ev->GetRxPowerW ();
+	}
+      i++;
+    }
+  if (noiseInterferenceW < energyW)
+    {
+      return MicroSeconds (0);
+    }
+
+  /* quicksort vector of NI changes by time. 
+   */
+  std::sort (ni.begin (), ni.end (), std::less<NiChange> ());
+
+  // Now, we iterate the piecewise linear noise function
+  Time end = now;
+  for (NiChanges::const_iterator i = ni.begin (); i != ni.end (); i++) 
+    {
+      noiseInterferenceW += i->GetDelta ();
+      end = i->GetTime ();
+      if (noiseInterferenceW < energyW) 
+	{
+	  break;
+	}
+    }
+  return end - now;
+}
+
+Time
+InterferenceHelper::CalculateTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble) const
+{
+  NS_ASSERT (m_80211a);
+  uint64_t delay = 0;
+  delay += m_plcpLongPreambleDelayUs;
+  // symbol duration is 4us
+  delay += 4;
+  delay += lrint (ceil ((size * 8.0 + 16.0 + 6.0) / payloadMode.GetDataRate () / 4e-6) * 4);
+  return MicroSeconds (delay);
+}
+
+void
+InterferenceHelper::Configure80211aParameters (void)
+{
+  NS_LOG_FUNCTION (this);
+  m_80211a = true;
+  m_plcpLongPreambleDelayUs = 16;
+  m_plcpShortPreambleDelayUs = 16;
+  m_longPlcpHeaderMode = WifiPhy::g_6mba;
+  m_shortPlcpHeaderMode = WifiPhy::g_6mba;
+  m_plcpHeaderLength = 4 + 1 + 12 + 1 + 6;
+  /* 4095 bytes at a 6Mb/s rate with a 1/2 coding rate. */
+  m_maxPacketDuration = CalculateTxDuration (4095, WifiPhy::g_6mba, WIFI_PREAMBLE_LONG);
+}
+
+void 
+InterferenceHelper::AppendEvent (Ptr<InterferenceHelper::Event> event)
+{
+  /* attempt to remove the events which are 
+   * not useful anymore. 
+   * i.e.: all events which end _before_
+   *       now - m_maxPacketDuration
+   */
+  
+  if (Simulator::Now () > GetMaxPacketDuration ())
+    {
+      Time end = Simulator::Now () - GetMaxPacketDuration ();
+      Events::iterator i = m_events.begin ();
+      while (i != m_events.end () &&
+             (*i)->GetEndTime () <= end) 
+        {
+          i++;
+        }
+      m_events.erase (m_events.begin (), i);
+    } 
+  m_events.push_back (event);
+}
+
+
+double
+InterferenceHelper::CalculateSnr (double signal, double noiseInterference, WifiMode mode) const
+{
+  // thermal noise at 290K in J/s = W
+  static const double BOLTZMANN = 1.3803e-23;
+  double Nt = BOLTZMANN * 290.0 * mode.GetBandwidth ();
+  // receiver noise Floor (W)
+  double noiseFloor = m_noiseFloorW * Nt;
+  double noise = noiseFloor + noiseInterference;
+  double snr = signal / noise;
+  return snr;
+}
+
+double
+InterferenceHelper::CalculateNoiseInterferenceW (Ptr<InterferenceHelper::Event> event, NiChanges *ni) const
+{
+  Events::const_iterator i = m_events.begin ();
+  double noiseInterference = 0.0;
+  while (i != m_events.end ()) 
+    {
+      if (event == (*i)) 
+        {
+          i++;
+          continue;
+        }
+      if (event->Overlaps ((*i)->GetStartTime ())) 
+        {
+          ni->push_back (NiChange ((*i)->GetStartTime (), (*i)->GetRxPowerW ()));
+        }
+      if (event->Overlaps ((*i)->GetEndTime ())) 
+        {
+          ni->push_back (NiChange ((*i)->GetEndTime (), -(*i)->GetRxPowerW ()));
+        }
+      if ((*i)->Overlaps (event->GetStartTime ())) 
+        {
+          noiseInterference += (*i)->GetRxPowerW ();
+        }
+      i++;
+    }
+  ni->push_back (NiChange (event->GetStartTime (), noiseInterference));
+  ni->push_back (NiChange (event->GetEndTime (), 0));
+
+  /* quicksort vector of NI changes by time. */
+  std::sort (ni->begin (), ni->end (), std::less<NiChange> ());
+
+  return noiseInterference;
+}
+
+double
+InterferenceHelper::CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode) const
+{
+  if (duration == NanoSeconds (0)) {
+    return 1.0;
+  }
+  uint32_t rate = mode.GetPhyRate ();
+  uint64_t nbits = (uint64_t)(rate * duration.GetSeconds ());
+  double csr = m_errorRateModel->GetChunkSuccessRate (mode, snir, (uint32_t)nbits);
+  return csr;
+}
+
+double 
+InterferenceHelper::CalculatePer (Ptr<const InterferenceHelper::Event> event, NiChanges *ni) const
+{  
+  double psr = 1.0; /* Packet Success Rate */
+  NiChanges::iterator j = ni->begin ();
+  Time previous = (*j).GetTime ();
+  uint64_t plcpPreambleDelayUs;
+  WifiMode payloadMode = event->GetPayloadMode ();
+  WifiMode headerMode;
+  switch (event->GetPreambleType ()) {
+  case WIFI_PREAMBLE_LONG:
+    plcpPreambleDelayUs = m_plcpLongPreambleDelayUs;
+    headerMode = m_longPlcpHeaderMode;
+    break;
+  case WIFI_PREAMBLE_SHORT:
+    plcpPreambleDelayUs = m_plcpShortPreambleDelayUs;
+    headerMode = m_shortPlcpHeaderMode;
+    break;
+  default:
+    NS_ASSERT (false);
+    // only to quiet compiler. Really stupid.
+    plcpPreambleDelayUs = 0;
+    headerMode = m_shortPlcpHeaderMode;
+    break;
+  }
+  Time plcpHeaderStart = (*j).GetTime () + MicroSeconds (plcpPreambleDelayUs);
+  Time plcpPayloadStart = plcpHeaderStart + 
+    Seconds ((m_plcpHeaderLength + 0.0) / headerMode.GetDataRate ());
+  double noiseInterferenceW = (*j).GetDelta ();
+  double powerW = event->GetRxPowerW ();
+
+  j++;
+  while (ni->end () != j) 
+    {
+      Time current = (*j).GetTime ();
+      NS_ASSERT (current >= previous);
+    
+      if (previous >= plcpPayloadStart) 
+        {
+          psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
+                                                          noiseInterferenceW, 
+                                                          payloadMode), 
+                                            current - previous,
+                                            payloadMode);
+        } 
+      else if (previous >= plcpHeaderStart) 
+        {
+          if (current >= plcpPayloadStart) 
+            {
+              psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
+                                                              noiseInterferenceW, 
+                                                              headerMode), 
+                                                plcpPayloadStart - previous,
+                                                headerMode);
+              psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
+                                                              noiseInterferenceW, 
+                                                              payloadMode),
+                                                current - plcpPayloadStart,
+                                                payloadMode);
+            } 
+          else 
+            {
+              NS_ASSERT (current >= plcpHeaderStart);
+              psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
+                                                              noiseInterferenceW, 
+                                                              headerMode), 
+                                                current - previous,
+                                                headerMode);
+            }
+        } 
+      else 
+        {
+          if (current >= plcpPayloadStart) 
+            {
+              psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
+                                                              noiseInterferenceW, 
+                                                              headerMode), 
+                                                plcpPayloadStart - plcpHeaderStart,
+                                                headerMode);
+              psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
+                                                              noiseInterferenceW, 
+                                                              payloadMode), 
+                                                current - plcpPayloadStart,
+                                                payloadMode);
+            } 
+          else if (current >= plcpHeaderStart) 
+            {
+              psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
+                                                              noiseInterferenceW, 
+                                                              headerMode), 
+                                                current - plcpHeaderStart,
+                                                headerMode);
+            }
+        }
+
+      noiseInterferenceW += (*j).GetDelta ();
+      previous = (*j).GetTime ();
+      j++;
+    }
+
+  double per = 1 - psr;
+  return per;
+}
+
+
+struct InterferenceHelper::SnrPer 
+InterferenceHelper::CalculateSnrPer (Ptr<InterferenceHelper::Event> event)
+{
+  NiChanges ni;
+  double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
+  double snr = CalculateSnr (event->GetRxPowerW (),
+                             noiseInterferenceW,
+                             event->GetPayloadMode ());
+  
+  /* calculate the SNIR at the start of the packet and accumulate
+   * all SNIR changes in the snir vector.
+   */
+  double per = CalculatePer (event, &ni);
+
+  struct SnrPer snrPer;
+  snrPer.snr = snr;
+  snrPer.per = per;
+  return snrPer;
+}
+
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/interference-helper.h	Mon Nov 24 06:36:05 2008 +0100
@@ -0,0 +1,110 @@
+#ifndef INTERFERENCE_HELPER_H
+#define INTERFERENCE_HELPER_H
+
+#include <stdint.h>
+#include <vector>
+#include <list>
+#include "wifi-mode.h"
+#include "wifi-preamble.h"
+#include "ns3/nstime.h"
+#include "ns3/ref-count-base.h"
+
+namespace ns3 {
+
+class ErrorRateModel;
+
+class InterferenceHelper
+{
+public:
+  class Event : public RefCountBase
+  {
+  public:
+    Event (uint32_t size, WifiMode payloadMode, 
+	     enum WifiPreamble preamble,
+	     Time duration, double rxPower);
+    virtual ~Event ();
+  
+    Time GetDuration (void) const;
+    Time GetStartTime (void) const;
+    Time GetEndTime (void) const;
+    bool Overlaps (Time time) const;
+    double GetRxPowerW (void) const;
+    uint32_t GetSize (void) const;
+    WifiMode GetPayloadMode (void) const;
+    enum WifiPreamble GetPreambleType (void) const;
+  private:
+    uint32_t m_size;
+    WifiMode m_payloadMode;
+    enum WifiPreamble m_preamble;
+    Time m_startTime;
+    Time m_endTime;
+    double m_rxPowerW;
+  };
+  struct SnrPer 
+  {
+    double snr;
+    double per;
+  };
+
+  InterferenceHelper ();
+  ~InterferenceHelper ();
+
+  void Configure80211aParameters (void);
+  void SetNoiseFloorW (double noiseFloor);
+  void SetErrorRateModel (Ptr<ErrorRateModel> rate);
+
+  double GetNoiseFloorW (void) const;
+  Ptr<ErrorRateModel> GetErrorRateModel (void) const;
+
+
+  /**
+   * \param energyW the minimum energy (W) requested
+   * \returns the expected amount of time the observed 
+   *          energy on the medium will be higher than
+   *          the requested threshold.
+   */
+  Time GetEnergyDuration (double energyW);
+  Time CalculateTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble) const;
+  Ptr<InterferenceHelper::Event> Add (uint32_t size, WifiMode payloadMode, 
+				      enum WifiPreamble preamble,
+				      Time duration, double rxPower);
+
+  struct InterferenceHelper::SnrPer CalculateSnrPer (Ptr<InterferenceHelper::Event> event);
+private:
+  class NiChange {
+  public:
+    NiChange (Time time, double delta);
+    Time GetTime (void) const;
+    double GetDelta (void) const;
+    bool operator < (NiChange const &o) const;
+  private:
+    Time m_time;
+    double m_delta;
+  };
+  typedef std::vector <NiChange> NiChanges;
+  typedef std::list<Ptr<Event> > Events;
+
+  InterferenceHelper (const InterferenceHelper &o);
+  InterferenceHelper &operator = (const InterferenceHelper &o);
+  void AppendEvent (Ptr<Event> event);
+  double CalculateNoiseInterferenceW (Ptr<Event> event, NiChanges *ni) const;
+  double CalculateSnr (double signal, double noiseInterference, WifiMode mode) const;
+  double CalculateChunkSuccessRate (double snir, Time delay, WifiMode mode) const;
+  double CalculatePer (Ptr<const Event> event, NiChanges *ni) const;
+  Time GetMaxPacketDuration (void) const;
+
+  uint64_t m_plcpLongPreambleDelayUs;
+  uint64_t m_plcpShortPreambleDelayUs;
+  WifiMode m_longPlcpHeaderMode;
+  WifiMode m_shortPlcpHeaderMode;
+  uint32_t m_plcpHeaderLength;
+  Time m_maxPacketDuration;
+  double m_noiseFloorW;
+  Events m_events;
+  bool m_80211a;
+  Ptr<ErrorRateModel> m_errorRateModel;
+};
+
+} // namespace ns3
+
+#endif /* INTERFERENCE_HELPER_H */
--- a/src/devices/wifi/jakes-propagation-loss-model.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/jakes-propagation-loss-model.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -33,7 +33,8 @@
 
 
 
-class JakesPropagationLossModel::PathCoefficients {
+class JakesPropagationLossModel::PathCoefficients 
+{
 public:
   PathCoefficients (Ptr<const JakesPropagationLossModel> jakes,
                     Ptr<MobilityModel> receiver, 
@@ -198,7 +199,7 @@
 }
 
 double
-JakesPropagationLossModel::GetLoss (Ptr<MobilityModel> a,
+JakesPropagationLossModel::DoGetLoss (Ptr<MobilityModel> a,
 				    Ptr<MobilityModel> b) const
 {
   PathsList::iterator i = m_paths.end ();
--- a/src/devices/wifi/jakes-propagation-loss-model.h	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/jakes-propagation-loss-model.h	Mon Nov 24 06:36:05 2008 +0100
@@ -83,8 +83,6 @@
   JakesPropagationLossModel ();
   virtual ~JakesPropagationLossModel ();
 
-  virtual double GetLoss (Ptr<MobilityModel> a,
-			  Ptr<MobilityModel> b) const;
   /**
    * \param nRays Number of rays per path
    *
@@ -99,27 +97,31 @@
   void SetNOscillators (uint8_t nOscillators);
 
 private:
+  JakesPropagationLossModel (const JakesPropagationLossModel &o);
+  JakesPropagationLossModel & operator = (const JakesPropagationLossModel &o);
+  void DoConstruct (void);
+  virtual double DoGetLoss (Ptr<MobilityModel> a,
+			  Ptr<MobilityModel> b) const;
+
+
   class PathCoefficients;
   struct ComplexNumber {
     double real;
     double imag;
   };
   friend class PathCoefficents;
-  
-  static const double PI;
-  ComplexNumber* m_amp;
-  RandomVariable m_variable;
-  double m_fd;
-
   typedef std::vector<PathCoefficients *> DestinationList;
   struct PathsSet {
     Ptr<MobilityModel> sender;
     DestinationList receivers;
   };
   typedef std::vector<PathsSet *> PathsList;
+
   
-  void DoConstruct (void);
-
+  static const double PI;
+  ComplexNumber* m_amp;
+  RandomVariable m_variable;
+  double m_fd;  
   mutable PathsList m_paths;
   uint8_t m_nRays;
   uint8_t m_nOscillators;
--- a/src/devices/wifi/mac-low.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/mac-low.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -474,7 +474,7 @@
 }
 
 void
-MacLow::ReceiveError (Ptr<Packet> packet, double rxSnr)
+MacLow::ReceiveError (Ptr<const Packet> packet, double rxSnr)
 {
   NS_LOG_FUNCTION (this << packet << rxSnr);
   MY_DEBUG ("rx failed ");
--- a/src/devices/wifi/mac-low.h	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/mac-low.h	Mon Nov 24 06:36:05 2008 +0100
@@ -36,7 +36,6 @@
 
 namespace ns3 {
 
-class WifiNetDevice;
 class WifiPhy;
 class WifiMac;
 
@@ -352,7 +351,7 @@
    * This method is typically invoked by the lower PHY layer to notify
    * the MAC layer that a packet was unsuccessfully received.
    */
-  void ReceiveError (Ptr<Packet> packet, double rxSnr);
+  void ReceiveError (Ptr<const Packet> packet, double rxSnr);
 private:
   void CancelAllEvents (void);
   uint32_t GetAckSize (void) const;
--- a/src/devices/wifi/propagation-loss-model.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/propagation-loss-model.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -43,10 +43,32 @@
   return tid;
 }
 
+PropagationLossModel::PropagationLossModel ()
+  : m_next (0)
+{}
 
 PropagationLossModel::~PropagationLossModel ()
 {}
 
+void 
+PropagationLossModel::SetNext (Ptr<PropagationLossModel> next)
+{
+  m_next = next;
+}
+
+double 
+PropagationLossModel::GetLoss (Ptr<MobilityModel> a,
+                               Ptr<MobilityModel> b) const
+{
+  double self = DoGetLoss (a, b);
+  if (m_next != 0)
+    {
+      self += m_next->GetLoss (a, b);
+    }
+  return self;
+}
+
+
 NS_OBJECT_ENSURE_REGISTERED (RandomPropagationLossModel);
 
 TypeId 
@@ -63,14 +85,15 @@
   return tid;
 }
 RandomPropagationLossModel::RandomPropagationLossModel ()
+  : PropagationLossModel ()
 {}
 
 RandomPropagationLossModel::~RandomPropagationLossModel ()
 {}
 
 double 
-RandomPropagationLossModel::GetLoss (Ptr<MobilityModel> a,
-				     Ptr<MobilityModel> b) const
+RandomPropagationLossModel::DoGetLoss (Ptr<MobilityModel> a,
+                                       Ptr<MobilityModel> b) const
 {
   double rxc = -m_variable.GetValue ();
   NS_LOG_DEBUG ("attenuation coefficent="<<rxc<<"Db");
@@ -158,7 +181,7 @@
 
 
 double 
-FriisPropagationLossModel::GetLoss (Ptr<MobilityModel> a,
+FriisPropagationLossModel::DoGetLoss (Ptr<MobilityModel> a,
 				    Ptr<MobilityModel> b) const
 {
   /*
@@ -220,11 +243,11 @@
                    DoubleValue (1.0),
                    MakeDoubleAccessor (&LogDistancePropagationLossModel::m_referenceDistance),
                    MakeDoubleChecker<double> ())
-    .AddAttribute ("ReferenceModel",
-                   "The reference model at the reference distance.",
-                   PointerValue (),
-                   MakePointerAccessor (&LogDistancePropagationLossModel::m_reference),
-                   MakePointerChecker<PropagationLossModel> ())
+    .AddAttribute ("ReferenceLoss",
+                   "The reference loss at reference distance",
+                   DoubleValue (46.6777),
+                   MakeDoubleAccessor (&LogDistancePropagationLossModel::m_referenceLoss),
+                   MakeDoubleChecker<double> ())
     ;
   return tid;
                    
@@ -239,14 +262,10 @@
   m_exponent = n;
 }
 void 
-LogDistancePropagationLossModel::SetReferenceDistance (double referenceDistance)
+LogDistancePropagationLossModel::SetReference (double referenceDistance, double referenceLoss)
 {
   m_referenceDistance = referenceDistance;
-}
-void 
-LogDistancePropagationLossModel::SetReferenceModel (Ptr<PropagationLossModel> model)
-{
-  m_reference = model;
+  m_referenceLoss = referenceLoss;
 }
 double 
 LogDistancePropagationLossModel::GetPathLossExponent (void) const
@@ -255,7 +274,7 @@
 }
   
 double 
-LogDistancePropagationLossModel::GetLoss (Ptr<MobilityModel> a,
+LogDistancePropagationLossModel::DoGetLoss (Ptr<MobilityModel> a,
                                           Ptr<MobilityModel> b) const
 {
   double distance = a->GetDistanceFrom (b);
@@ -277,15 +296,10 @@
    *      
    * rx = rx0(tx) - 10 * n * log (d/d0)
    */
-  static Ptr<StaticMobilityModel> zero = CreateObject<StaticMobilityModel> ();
-  static Ptr<StaticMobilityModel> reference = CreateObject<StaticMobilityModel> ();
-  zero->SetPosition (Vector (0.0, 0.0, 0.0));
-  reference->SetPosition (Vector (m_referenceDistance, 0.0, 0.0));
-  double ref = m_reference->GetLoss (zero, reference);
   double pathLossDb = 10 * m_exponent * log10 (distance / m_referenceDistance);
-  double rxc = ref - pathLossDb;
-  NS_LOG_DEBUG ("distance="<<distance<<"m, reference-attenuation="<<ref<<"dB, "<<
-		"attenuation coefficient="<<rxc<<"dbm");
+  double rxc = -m_referenceLoss - pathLossDb;
+  NS_LOG_DEBUG ("distance="<<distance<<"m, reference-attenuation="<<-m_referenceLoss<<"dB, "<<
+		"attenuation coefficient="<<rxc<<"db");
   return rxc;
 }
 
--- a/src/devices/wifi/propagation-loss-model.h	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/propagation-loss-model.h	Mon Nov 24 06:36:05 2008 +0100
@@ -38,14 +38,25 @@
 public:
   static TypeId GetTypeId (void);
 
+  PropagationLossModel ();
   virtual ~PropagationLossModel ();
+
+  void SetNext (Ptr<PropagationLossModel> next);
+
   /**
    * \param a the mobility model of the source
    * \param b the mobility model of the destination
    * \returns the attenuation coefficient (dB)
    */
-  virtual double GetLoss (Ptr<MobilityModel> a,
-			  Ptr<MobilityModel> b) const = 0;
+  double GetLoss (Ptr<MobilityModel> a,
+                  Ptr<MobilityModel> b) const;
+private:
+  PropagationLossModel (const PropagationLossModel &o);
+  PropagationLossModel &operator = (const PropagationLossModel &o);
+  virtual double DoGetLoss (Ptr<MobilityModel> a,
+                            Ptr<MobilityModel> b) const = 0;
+
+  Ptr<PropagationLossModel> m_next;
 };
 
 /**
@@ -59,9 +70,11 @@
   RandomPropagationLossModel ();
   virtual ~RandomPropagationLossModel ();
 
-  virtual double GetLoss (Ptr<MobilityModel> a,
-			  Ptr<MobilityModel> b) const;
 private:
+  RandomPropagationLossModel (const RandomPropagationLossModel &o);
+  RandomPropagationLossModel & operator = (const RandomPropagationLossModel &o);
+  virtual double DoGetLoss (Ptr<MobilityModel> a,
+                            Ptr<MobilityModel> b) const;
   RandomVariable m_variable;
 };
 
@@ -147,9 +160,11 @@
    */
   double GetSystemLoss (void) const;
 
-  virtual double GetLoss (Ptr<MobilityModel> a,
-			  Ptr<MobilityModel> b) const;
 private:
+  FriisPropagationLossModel (const FriisPropagationLossModel &o);
+  FriisPropagationLossModel & operator = (const FriisPropagationLossModel &o);
+  virtual double DoGetLoss (Ptr<MobilityModel> a,
+                            Ptr<MobilityModel> b) const;
   double DbmToW (double dbm) const;
   double DbmFromW (double w) const;
 
@@ -193,21 +208,18 @@
    */
   double GetPathLossExponent (void) const;
 
-  /**
-   * \param model the reference propagation model
-   */
-  void SetReferenceModel (Ptr<PropagationLossModel> model);
-
-  void SetReferenceDistance (double referenceDistance);
+  void SetReference (double referenceDistance, double referenceLoss);
   
-  virtual double GetLoss (Ptr<MobilityModel> a,
-			  Ptr<MobilityModel> b) const;
 private:
+  LogDistancePropagationLossModel (const LogDistancePropagationLossModel &o);
+  LogDistancePropagationLossModel & operator = (const LogDistancePropagationLossModel &o);
+  virtual double DoGetLoss (Ptr<MobilityModel> a,
+                            Ptr<MobilityModel> b) const;
   static Ptr<PropagationLossModel> CreateDefaultReference (void);
 
   double m_exponent;
   double m_referenceDistance;
-  Ptr<PropagationLossModel> m_reference;
+  double m_referenceLoss;
 };
 
 } // namespace ns3
--- a/src/devices/wifi/wifi-channel.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/wifi-channel.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -24,7 +24,10 @@
 #include "ns3/node.h"
 #include "ns3/log.h"
 #include "ns3/pointer.h"
+#include "ns3/object-factory.h"
 #include "wifi-channel.h"
+#include "wifi-net-device.h"
+#include "yans-wifi-phy.h"
 #include "propagation-loss-model.h"
 #include "propagation-delay-model.h"
 
@@ -37,90 +40,8 @@
 {
   static TypeId tid = TypeId ("ns3::WifiChannel")
     .SetParent<Channel> ()
-    .AddConstructor<WifiChannel> ()
-    .AddAttribute ("PropagationLossModel", "A pointer to the propagation loss model attached to this channel.",
-                   PointerValue (),
-                   MakePointerAccessor (&WifiChannel::m_loss),
-                   MakePointerChecker<PropagationLossModel> ())
-    .AddAttribute ("PropagationDelayModel", "A pointer to the propagation delay model attached to this channel.",
-                   PointerValue (),
-                   MakePointerAccessor (&WifiChannel::m_delay),
-                   MakePointerChecker<PropagationDelayModel> ())
     ;
   return tid;
 }
 
-WifiChannel::WifiChannel ()
-{}
-WifiChannel::~WifiChannel ()
-{
-  m_deviceList.clear ();
-}
-
-void 
-WifiChannel::SetPropagationLossModel (Ptr<PropagationLossModel> loss)
-{
-  m_loss = loss;
-}
-void 
-WifiChannel::SetPropagationDelayModel (Ptr<PropagationDelayModel> delay)
-{
-  m_delay = delay;
-}
-
-void 
-WifiChannel::Add (Ptr<NetDevice> device, Ptr<WifiPhy> phy)
-{
-  m_deviceList.push_back (std::make_pair (device, phy));
-}
-void 
-WifiChannel::Send (Ptr<WifiPhy> sender, Ptr<const Packet> packet, double txPowerDbm,
-                   WifiMode wifiMode, WifiPreamble preamble) const
-{
-  Ptr<MobilityModel> senderMobility = 0;
-  for (DeviceList::const_iterator i = m_deviceList.begin (); i != m_deviceList.end (); i++)
-    {
-      if (sender == i->second)
-        {
-          senderMobility = i->first->GetNode ()->GetObject<MobilityModel> ();
-          break;
-        }
-    }
-  NS_ASSERT (senderMobility != 0);
-  uint32_t j = 0;
-  for (DeviceList::const_iterator i = m_deviceList.begin (); i != m_deviceList.end (); i++)
-    {
-      if (sender != i->second)
-        {
-          Ptr<MobilityModel> receiverMobility = i->first->GetNode ()->GetObject<MobilityModel> ();
-          Time delay = m_delay->GetDelay (senderMobility, receiverMobility);
-          double rxPowerDbm = txPowerDbm + m_loss->GetLoss (senderMobility, receiverMobility);
-          NS_LOG_DEBUG ("propagation: txPower="<<txPowerDbm<<"dbm, rxPower="<<rxPowerDbm<<"dbm, "<<
-                        "distance="<<senderMobility->GetDistanceFrom (receiverMobility)<<"m, delay="<<delay);
-          Ptr<Packet> copy = packet->Copy ();
-          Simulator::Schedule (delay, &WifiChannel::Receive, this, 
-                               j, copy, rxPowerDbm, wifiMode, preamble);
-        }
-      j++;
-    }
-}
-
-void
-WifiChannel::Receive (uint32_t i, Ptr<Packet> packet, double rxPowerDbm,
-                      WifiMode txMode, WifiPreamble preamble) const
-{
-  m_deviceList[i].second->StartReceivePacket (packet, rxPowerDbm, txMode, preamble);
-}
-
-uint32_t 
-WifiChannel::GetNDevices (void) const
-{
-  return m_deviceList.size ();
-}
-Ptr<NetDevice> 
-WifiChannel::GetDevice (uint32_t i) const
-{
-  return m_deviceList[i].first;
-}
-
 } // namespace ns3
--- a/src/devices/wifi/wifi-channel.h	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/wifi-channel.h	Mon Nov 24 06:36:05 2008 +0100
@@ -20,97 +20,29 @@
 #ifndef WIFI_CHANNEL_H
 #define WIFI_CHANNEL_H
 
-#include <vector>
-#include <stdint.h>
-#include "ns3/packet.h"
 #include "ns3/channel.h"
-#include "wifi-mode.h"
-#include "wifi-preamble.h"
-#include "wifi-phy.h"
+#include "ns3/attribute-list.h"
 
 namespace ns3 {
 
-class NetDevice;
-class PropagationLossModel;
-class PropagationDelayModel;
+class WifiNetDevice;
+class WifiPhy;
 
 /**
  * \brief A 802.11 Channel
  *
- * This channel subclass can be used to connect together a set of 
- * ns3::WifiNetDevice network interfaces. A WifiChannel contains
- * a ns3::PropagationLossModel and a ns3::PropagationDelayModel which can
- * be overriden by the WifiChannel::SetPropagationLossModel
- * and the WifiChannel::SetPropagationDelayModel methods. By default,
- * no propagation models are set.
+ * This class works in tandem with the ns3::WifiPhy class. If you want to
+ * provide a new Wifi PHY layer, you have to subclass both ns3::WifiChannel 
+ * and ns3::WifiPhy.
+ *
+ * Typically, MyWifiChannel will define a Send method whose job is to distribute
+ * packets from a MyWifiPhy source to a set of MyWifiPhy destinations. MyWifiPhy
+ * also typically defines a Receive method which is invoked by MyWifiPhy.
  */
 class WifiChannel : public Channel
 {
 public:
   static TypeId GetTypeId (void);
-
-  WifiChannel ();
-  virtual ~WifiChannel ();
-
-  /**
-   * \returns the number of network interfaces connected to 
-   *          this channel.
-   *
-   * Overriden from the NetDevice base class.
-   */
-  virtual uint32_t GetNDevices (void) const;
-
-  /**
-   * \param i index of the requested network interface.
-   * \returns the requested network interfaces connected to 
-   *          this channel.
-   *
-   * Overriden from the NetDevice base class.
-   * Indexes start at 0 and end at n-1.
-   */
-  virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
-
-  /**
-   * \param loss the new propagation loss model.
-   */
-  void SetPropagationLossModel (Ptr<PropagationLossModel> loss);
-  /**
-   * \param delay the new propagation delay model.
-   */
-  void SetPropagationDelayModel (Ptr<PropagationDelayModel> delay);
-
-  /**
-   * \param device the device to add to the list of connected
-   *        devices.
-   * \param phy the physical layer which will receive packets
-   *        on behalf of the device.
-   *
-   * This method should not be invoked by normal users. It is 
-   * currently invoked only from WifiPhy::SetChannel.
-   */
-  void Add (Ptr<NetDevice> device,  Ptr<WifiPhy> phy);
-  /**
-   * \param sender the device from which the packet is originating.
-   * \param packet the packet to send
-   * \param txPowerDbm the tx power associated to the packet
-   * \param wifiMode the tx mode associated to the packet
-   * \param preamble the preamble associated to the packet
-   *
-   * This method should not be invoked by normal users. It is 
-   * currently invoked only from WifiPhy::Send.
-   */
-  void Send (Ptr<WifiPhy> sender, Ptr<const Packet> packet, double txPowerDbm,
-             WifiMode wifiMode, WifiPreamble preamble) const;
-
-private:
-  typedef std::vector<std::pair<Ptr<NetDevice>, Ptr<WifiPhy> > > DeviceList;
-  void Receive (uint32_t i, Ptr<Packet> packet, double rxPowerDbm,
-                WifiMode txMode, WifiPreamble preamble) const;
-
-
-  DeviceList m_deviceList;
-  Ptr<PropagationLossModel> m_loss;
-  Ptr<PropagationDelayModel> m_delay;
 };
 
 } // namespace ns3
--- a/src/devices/wifi/wifi-mac.h	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/wifi-mac.h	Mon Nov 24 06:36:05 2008 +0100
@@ -134,8 +134,6 @@
    */
   virtual Mac48Address GetBssid (void) const = 0;
 
-private:
-  friend class WifiNetDevice;
   /**
    * \param packet the packet to send.
    * \param to the address to which the packet should be sent.
@@ -178,6 +176,8 @@
    * \param linkDown the callback to invoke when the link becomes down.
    */
   virtual void SetLinkDownCallback (Callback<void> linkDown) = 0;
+private:
+
 
 
   static Time GetDefaultMaxPropagationDelay (void);
--- a/src/devices/wifi/wifi-mode.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/wifi-mode.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -107,6 +107,13 @@
 WifiMode::WifiMode (uint32_t uid)
   : m_uid (uid)
 {}
+WifiMode::WifiMode (std::string name)
+{
+  if (!WifiModeFactory::GetFactory ()->Search (name, this))
+    {
+      NS_FATAL_ERROR ("Invalid requested wifi mode: " << name);
+    }
+}
 
 ATTRIBUTE_HELPER_CPP (WifiMode);
 
--- a/src/devices/wifi/wifi-mode.h	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/wifi-mode.h	Mon Nov 24 06:36:05 2008 +0100
@@ -106,7 +106,7 @@
    * its initialization.
    */
   WifiMode ();
-
+  WifiMode (std::string name);
 private:
   friend class WifiModeFactory;
   WifiMode (uint32_t uid);
--- a/src/devices/wifi/wifi-net-device.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/wifi-net-device.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -40,8 +40,7 @@
     .SetParent<NetDevice> ()
     .AddAttribute ("Channel", "The channel attached to this device",
                    PointerValue (),
-                   MakePointerAccessor (&WifiNetDevice::DoGetChannel,
-                                        &WifiNetDevice::SetChannel),
+                   MakePointerAccessor (&WifiNetDevice::DoGetChannel),
                    MakePointerChecker<WifiChannel> ())
     .AddAttribute ("Phy", "The PHY layer attached to this device.",
                    PointerValue (),
@@ -67,7 +66,8 @@
 }
 
 WifiNetDevice::WifiNetDevice ()
-  : m_mtu (0)
+  : m_mtu (0),
+    m_configComplete (false)
 {}
 WifiNetDevice::~WifiNetDevice ()
 {}
@@ -81,77 +81,48 @@
   m_stationManager->Dispose ();
   m_mac = 0;
   m_phy = 0;
-  m_channel = 0;
   m_stationManager = 0;
   // chain up.
   NetDevice::DoDispose ();
 }
+
+void
+WifiNetDevice::CompleteConfig (void)
+{
+  if (m_mac == 0 || 
+      m_phy == 0 || 
+      m_stationManager == 0 ||
+      m_node == 0 ||
+      m_configComplete)
+    {
+      return;
+    }
+  m_mac->SetWifiRemoteStationManager (m_stationManager);
+  m_mac->SetWifiPhy (m_phy);
+  m_mac->SetForwardUpCallback (MakeCallback (&WifiNetDevice::ForwardUp, this));
+  m_mac->SetLinkUpCallback (MakeCallback (&WifiNetDevice::LinkUp, this));
+  m_mac->SetLinkDownCallback (MakeCallback (&WifiNetDevice::LinkDown, this));
+  m_stationManager->SetupPhy (m_phy);
+  m_configComplete = true;
+}
   
 void 
 WifiNetDevice::SetMac (Ptr<WifiMac> mac)
 {
   m_mac = mac;
-  if (m_mac != 0)
-    {
-      if (m_stationManager != 0)
-        {
-          m_mac->SetWifiRemoteStationManager (m_stationManager);
-        }
-      if (m_phy != 0)
-        {
-          m_mac->SetWifiPhy (m_phy);
-        }
-      m_mac->SetForwardUpCallback (MakeCallback (&WifiNetDevice::ForwardUp, this));
-      m_mac->SetLinkUpCallback (MakeCallback (&WifiNetDevice::LinkUp, this));
-      m_mac->SetLinkDownCallback (MakeCallback (&WifiNetDevice::LinkDown, this));
-    }
+  CompleteConfig ();
 }
 void 
 WifiNetDevice::SetPhy (Ptr<WifiPhy> phy)
 {
   m_phy = phy;
-  if (m_phy != 0)
-    {
-      if (m_channel != 0)
-        {
-          m_channel->Add (this, m_phy);
-          m_phy->SetChannel (m_channel);
-        }
-      if (m_stationManager != 0)
-        {
-          m_stationManager->SetupPhy (m_phy);
-        }
-      if (m_mac != 0)
-        {
-          m_mac->SetWifiPhy (m_phy);
-        }
-    }
+  CompleteConfig ();
 }
 void 
 WifiNetDevice::SetRemoteStationManager (Ptr<WifiRemoteStationManager> manager)
 {
   m_stationManager = manager;
-  if (m_stationManager != 0)
-    {
-      if (m_phy != 0)
-        {
-          m_stationManager->SetupPhy (m_phy);
-        }
-      if (m_mac != 0)
-        {
-          m_mac->SetWifiRemoteStationManager (m_stationManager);
-        }
-    }
-}
-void 
-WifiNetDevice::SetChannel (Ptr<WifiChannel> channel)
-{
-  m_channel = channel;
-  if (m_channel != 0 && m_phy != 0)
-    {
-      m_channel->Add (this, m_phy);
-      m_phy->SetChannel (m_channel);
-    }
+  CompleteConfig ();
 }
 Ptr<WifiMac> 
 WifiNetDevice::GetMac (void) const
@@ -192,12 +163,12 @@
 Ptr<Channel> 
 WifiNetDevice::GetChannel (void) const
 {
-  return m_channel;
+  return m_phy->GetChannel ();
 }
 Ptr<WifiChannel> 
 WifiNetDevice::DoGetChannel (void) const
 {
-  return m_channel;
+  return m_phy->GetChannel ();
 }
 Address 
 WifiNetDevice::GetAddress (void) const
@@ -291,6 +262,7 @@
 WifiNetDevice::SetNode (Ptr<Node> node)
 {
   m_node = node;
+  CompleteConfig ();
 }
 bool 
 WifiNetDevice::NeedsArp (void) const
--- a/src/devices/wifi/wifi-net-device.h	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/wifi-net-device.h	Mon Nov 24 06:36:05 2008 +0100
@@ -61,10 +61,6 @@
    */
   void SetRemoteStationManager (Ptr<WifiRemoteStationManager> manager);
   /**
-   * \param channel the channel to connect to.
-   */
-  void SetChannel (Ptr<WifiChannel> channel);
-  /**
    * \returns the mac we are currently using.
    */
   Ptr<WifiMac> GetMac (void) const;
@@ -113,9 +109,10 @@
   void LinkDown (void);
   void Setup (void);
   Ptr<WifiChannel> DoGetChannel (void) const;
+  void CompleteConfig (void);
+
   Ptr<Node> m_node;
   Ptr<WifiPhy> m_phy;
-  Ptr<WifiChannel> m_channel;
   Ptr<WifiMac> m_mac;
   Ptr<WifiRemoteStationManager> m_stationManager;
   NetDevice::ReceiveCallback m_forwardUp;
@@ -127,6 +124,7 @@
   bool m_linkUp;
   Callback<void> m_linkChange;
   mutable uint16_t m_mtu;
+  bool m_configComplete;
 };
 
 } // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/wifi-phy-state-helper.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -0,0 +1,365 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006 INRIA
+ *
+ * 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>
+ */
+#include "wifi-phy-state-helper.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/trace-source-accessor.h"
+
+NS_LOG_COMPONENT_DEFINE ("WifiPhyStateHelper");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (WifiPhyStateHelper);
+
+TypeId 
+WifiPhyStateHelper::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::WifiPhyStateHelper")
+    .SetParent<Object> ()
+    .AddConstructor<WifiPhyStateHelper> ()
+    .AddTraceSource ("State",
+                     "The state of the PHY layer",
+                     MakeTraceSourceAccessor (&WifiPhyStateHelper::m_stateLogger))
+    .AddTraceSource ("RxOk",
+                     "A packet has been received successfully.",
+                     MakeTraceSourceAccessor (&WifiPhyStateHelper::m_rxOkTrace))
+    .AddTraceSource ("RxError",
+                     "A packet has been received unsuccessfully.",
+                     MakeTraceSourceAccessor (&WifiPhyStateHelper::m_rxErrorTrace))
+    .AddTraceSource ("Tx", "Packet transmission is starting.",
+                     MakeTraceSourceAccessor (&WifiPhyStateHelper::m_txTrace))
+    ;
+  return tid;
+}
+
+WifiPhyStateHelper::WifiPhyStateHelper ()
+  : m_syncing (false),
+    m_endTx (Seconds (0)),
+    m_endSync (Seconds (0)),
+    m_endCcaBusy (Seconds (0)),
+    m_startTx (Seconds (0)),
+    m_startSync (Seconds (0)),
+    m_startCcaBusy (Seconds (0)),
+    m_previousStateChangeTime (Seconds (0))
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void 
+WifiPhyStateHelper::SetReceiveOkCallback (WifiPhy::SyncOkCallback callback)
+{
+  m_syncOkCallback = callback;
+}
+void 
+WifiPhyStateHelper::SetReceiveErrorCallback (WifiPhy::SyncErrorCallback callback)
+{
+  m_syncErrorCallback = callback;
+}
+void 
+WifiPhyStateHelper::RegisterListener (WifiPhyListener *listener)
+{
+  m_listeners.push_back (listener);
+}
+
+bool 
+WifiPhyStateHelper::IsStateCcaBusy (void)
+{
+  return GetState () == WifiPhy::CCA_BUSY;
+}
+ 
+bool 
+WifiPhyStateHelper::IsStateIdle (void)
+{
+  return (GetState () == WifiPhy::IDLE)?true:false;
+}
+bool 
+WifiPhyStateHelper::IsStateBusy (void)
+{
+  return (GetState () != WifiPhy::IDLE)?true:false;
+}
+bool 
+WifiPhyStateHelper::IsStateSync (void)
+{
+  return (GetState () == WifiPhy::SYNC)?true:false;
+}
+bool 
+WifiPhyStateHelper::IsStateTx (void)
+{
+  return (GetState () == WifiPhy::TX)?true:false;
+}
+
+
+
+Time
+WifiPhyStateHelper::GetStateDuration (void)
+{
+  return Simulator::Now () - m_previousStateChangeTime;
+}
+
+Time
+WifiPhyStateHelper::GetDelayUntilIdle (void)
+{
+  Time retval;
+
+  switch (GetState ()) {
+  case WifiPhy::SYNC:
+    retval = m_endSync - Simulator::Now ();
+    break;
+  case WifiPhy::TX:
+    retval = m_endTx - Simulator::Now ();
+    break;
+  case WifiPhy::CCA_BUSY:
+    retval = m_endCcaBusy - Simulator::Now ();
+    break;
+  case WifiPhy::IDLE:
+    retval = Seconds (0);
+    break;
+  default:
+    NS_ASSERT (false);
+    // NOTREACHED
+    retval = Seconds (0);
+    break;
+  }
+  retval = Max (retval, Seconds (0));
+  return retval;
+}
+
+Time 
+WifiPhyStateHelper::GetLastRxStartTime (void) const
+{
+  return m_startSync;
+}
+
+char const *
+WifiPhyStateHelper::StateToString (enum WifiPhy::State state)
+{
+  switch (state) {
+  case WifiPhy::TX:
+    return "TX";
+    break;
+  case WifiPhy::CCA_BUSY:
+    return "CCA_BUSY";
+    break;
+  case WifiPhy::IDLE:
+    return "IDLE";
+    break;
+  case WifiPhy::SYNC:
+    return "SYNC";
+    break;
+  default:
+    NS_ASSERT (false);
+    // quiet compiler
+    return "INVALID";
+    break;
+  }
+}
+
+enum WifiPhy::State 
+WifiPhyStateHelper::GetState (void)
+{
+  if (m_endTx > Simulator::Now ()) 
+    {
+      return WifiPhy::TX;
+    } 
+  else if (m_syncing) 
+    {
+      return WifiPhy::SYNC;
+    } 
+  else if (m_endCcaBusy > Simulator::Now ()) 
+    {
+      return WifiPhy::CCA_BUSY;
+    } 
+  else 
+    {
+      return WifiPhy::IDLE;
+    }
+}
+
+
+void 
+WifiPhyStateHelper::NotifyTxStart (Time duration)
+{
+  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
+    (*i)->NotifyTxStart (duration);
+  }
+}
+void 
+WifiPhyStateHelper::NotifySyncStart (Time duration)
+{
+  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
+    (*i)->NotifyRxStart (duration);
+  }
+}
+void 
+WifiPhyStateHelper::NotifySyncEndOk (void)
+{
+  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
+    (*i)->NotifyRxEndOk ();
+  }
+}
+void 
+WifiPhyStateHelper::NotifySyncEndError (void)
+{
+  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
+    (*i)->NotifyRxEndError ();
+  }
+}
+void 
+WifiPhyStateHelper::NotifyMaybeCcaBusyStart (Time duration)
+{
+  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
+    (*i)->NotifyMaybeCcaBusyStart (duration);
+  }
+}
+
+void
+WifiPhyStateHelper::LogPreviousIdleAndCcaBusyStates (void)
+{
+  Time now = Simulator::Now ();
+  Time idleStart = Max (m_endCcaBusy, m_endSync);
+  idleStart = Max (idleStart, m_endTx);
+  NS_ASSERT (idleStart <= now);
+  if (m_endCcaBusy > m_endSync && 
+      m_endCcaBusy > m_endTx) {
+    Time ccaBusyStart = Max (m_endTx, m_endSync);
+    ccaBusyStart = Max (ccaBusyStart, m_startCcaBusy);
+    m_stateLogger (ccaBusyStart, idleStart - ccaBusyStart, WifiPhy::CCA_BUSY);
+  }
+  m_stateLogger (idleStart, now - idleStart, WifiPhy::IDLE);
+}
+
+void
+WifiPhyStateHelper::SwitchToTx (Time txDuration, Ptr<const Packet> packet, WifiMode txMode, 
+			  WifiPreamble preamble, uint8_t txPower)
+{
+  m_txTrace (packet, txMode, preamble, txPower);
+  NotifyTxStart (txDuration);
+  Time now = Simulator::Now ();
+  switch (GetState ()) {
+  case WifiPhy::SYNC:
+    /* The packet which is being received as well
+     * as its endSync event are cancelled by the caller.
+     */
+    m_syncing = false;
+    m_stateLogger (m_startSync, now - m_startSync, WifiPhy::SYNC);
+    m_endSync = now;
+    break;
+  case WifiPhy::CCA_BUSY: {
+    Time ccaStart = Max (m_endSync, m_endTx);
+    ccaStart = Max (ccaStart, m_startCcaBusy);
+    m_stateLogger (ccaStart, now - ccaStart, WifiPhy::CCA_BUSY);
+  } break;
+  case WifiPhy::IDLE:
+    LogPreviousIdleAndCcaBusyStates ();
+    break;
+  default:
+    NS_ASSERT (false);
+    break;
+  }
+  m_stateLogger (now, txDuration, WifiPhy::TX);
+  m_previousStateChangeTime = now;
+  m_endTx = now + txDuration;
+  m_startTx = now;
+}
+void
+WifiPhyStateHelper::SwitchToSync (Time rxDuration)
+{
+  NS_ASSERT (IsStateIdle () || IsStateCcaBusy ());
+  NS_ASSERT (!m_syncing);
+  NotifySyncStart (rxDuration);
+  Time now = Simulator::Now ();
+  switch (GetState ()) {
+  case WifiPhy::IDLE:
+    LogPreviousIdleAndCcaBusyStates ();
+    break;
+  case WifiPhy::CCA_BUSY: {
+    Time ccaStart = Max (m_endSync, m_endTx);
+    ccaStart = Max (ccaStart, m_startCcaBusy);
+    m_stateLogger (ccaStart, now - ccaStart, WifiPhy::CCA_BUSY);
+  } break;
+  case WifiPhy::SYNC:
+  case WifiPhy::TX:
+    NS_ASSERT (false);
+    break;
+  }
+  m_previousStateChangeTime = now;
+  m_syncing = true;
+  m_startSync = now;
+  m_endSync = now + rxDuration;
+  NS_ASSERT (IsStateSync ());
+}
+void 
+WifiPhyStateHelper::SwitchFromSyncEndOk (Ptr<Packet> packet, double snr, WifiMode mode, enum WifiPreamble preamble)
+{
+  m_rxOkTrace (packet, snr, mode, preamble);
+  NotifySyncEndOk ();
+  DoSwitchFromSync ();
+  if (!m_syncOkCallback.IsNull ())
+    {
+      m_syncOkCallback (packet, snr, mode, preamble);
+    }
+
+}
+void 
+WifiPhyStateHelper::SwitchFromSyncEndError (Ptr<const Packet> packet, double snr)
+{
+  m_rxErrorTrace (packet, snr);
+  NotifySyncEndError ();
+  DoSwitchFromSync ();
+  if (!m_syncErrorCallback.IsNull ())
+    {
+      m_syncErrorCallback (packet, snr);
+    }
+}
+
+void
+WifiPhyStateHelper::DoSwitchFromSync (void)
+{
+  NS_ASSERT (IsStateSync ());
+  NS_ASSERT (m_syncing);
+
+  Time now = Simulator::Now ();
+  m_stateLogger (m_startSync, now - m_startSync, WifiPhy::SYNC);
+  m_previousStateChangeTime = now;
+  m_syncing = false;
+
+  NS_ASSERT (IsStateIdle () || IsStateCcaBusy ());
+}
+void
+WifiPhyStateHelper::SwitchMaybeToCcaBusy (Time duration)
+{
+  NotifyMaybeCcaBusyStart (duration);
+  Time now = Simulator::Now ();
+  switch (GetState ()) {
+  case WifiPhy::IDLE:
+    LogPreviousIdleAndCcaBusyStates ();
+  break;
+  case WifiPhy::CCA_BUSY:
+    break;
+  case WifiPhy::SYNC:
+    break;
+  case WifiPhy::TX:
+    break;
+  }
+  m_startCcaBusy = now;
+  m_endCcaBusy = std::max (m_endCcaBusy, now + duration);
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/wifi-phy-state-helper.h	Mon Nov 24 06:36:05 2008 +0100
@@ -0,0 +1,90 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006 INRIA
+ *
+ * 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>
+ */
+#ifndef WIFI_PHY_STATE_HELPER_H
+#define WIFI_PHY_STATE_HELPER_H
+
+#include "wifi-phy.h"
+#include "ns3/traced-callback.h"
+#include "ns3/object.h"
+#include <vector>
+
+namespace ns3 {
+
+class WifiPhyStateHelper : public Object
+{
+public:
+  static TypeId GetTypeId (void);
+
+  WifiPhyStateHelper ();
+
+  void SetReceiveOkCallback (WifiPhy::SyncOkCallback callback);
+  void SetReceiveErrorCallback (WifiPhy::SyncErrorCallback callback);
+  void RegisterListener (WifiPhyListener *listener);
+  enum WifiPhy::State GetState (void);
+  bool IsStateCcaBusy (void);
+  bool IsStateIdle (void);
+  bool IsStateBusy (void);
+  bool IsStateSync (void);
+  bool IsStateTx (void);
+  Time GetStateDuration (void);
+  Time GetDelayUntilIdle (void);
+  Time GetLastRxStartTime (void) const;
+
+  void SwitchToTx (Time txDuration, Ptr<const Packet> packet, WifiMode txMode, WifiPreamble preamble, uint8_t txPower);
+  void SwitchToSync (Time syncDuration);
+  void SwitchFromSyncEndOk (Ptr<Packet> packet, double snr, WifiMode mode, enum WifiPreamble preamble);
+  void SwitchFromSyncEndError (Ptr<const Packet> packet, double snr);
+  void SwitchMaybeToCcaBusy (Time duration);
+
+  TracedCallback<Time,Time,enum WifiPhy::State> m_stateLogger;
+private:
+  typedef std::vector<WifiPhyListener *> Listeners;
+
+  char const *StateToString (enum WifiPhy::State state);
+  void LogPreviousIdleAndCcaBusyStates (void);
+
+  void NotifyTxStart (Time duration);
+  void NotifyWakeup (void);
+  void NotifySyncStart (Time duration);
+  void NotifySyncEndOk (void);
+  void NotifySyncEndError (void);
+  void NotifyMaybeCcaBusyStart (Time duration);
+  void DoSwitchFromSync (void);
+
+  bool m_syncing;
+  Time m_endTx;
+  Time m_endSync;
+  Time m_endCcaBusy;
+  Time m_startTx;
+  Time m_startSync;
+  Time m_startCcaBusy;
+  Time m_previousStateChangeTime;
+
+  Listeners m_listeners;
+  TracedCallback<Ptr<const Packet>, double, WifiMode, enum WifiPreamble> m_rxOkTrace;
+  TracedCallback<Ptr<const Packet>, double> m_rxErrorTrace;
+  TracedCallback<Ptr<const Packet>,WifiMode,WifiPreamble,uint8_t> m_txTrace;
+  WifiPhy::SyncOkCallback m_syncOkCallback;
+  WifiPhy::SyncErrorCallback m_syncErrorCallback;
+};
+
+} // namespace ns3
+
+#endif /* WIFI_PHY_STATE_HELPER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/wifi-phy-test.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -0,0 +1,431 @@
+#include "wifi-net-device.h"
+#include "yans-wifi-channel.h"
+#include "yans-wifi-phy.h"
+#include "propagation-loss-model.h"
+#include "propagation-delay-model.h"
+#include "error-rate-model.h"
+#include "ns3/ptr.h"
+#include "ns3/mobility-model.h"
+#include "ns3/static-mobility-model.h"
+#include "ns3/vector.h"
+#include "ns3/packet.h"
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/command-line.h"
+#include "ns3/flow-id-tag.h"
+
+using namespace ns3;
+
+class PsrExperiment
+{
+public:
+  struct Input
+  {
+    Input ();
+    double distance;
+    std::string txMode;
+    uint8_t txPowerLevel;
+    uint32_t packetSize;
+    uint32_t nPackets;
+  };
+  struct Output
+  {
+    uint32_t received;
+  };
+  PsrExperiment ();
+
+  struct PsrExperiment::Output Run (struct PsrExperiment::Input input);
+
+private:
+  void Send (void);
+  void Receive (Ptr<Packet> p, double snr, WifiMode mode, enum WifiPreamble preamble);
+  Ptr<WifiPhy> m_tx;
+  struct Input m_input;
+  struct Output m_output;
+};
+
+void 
+PsrExperiment::Send (void)
+{
+  Ptr<Packet> p = Create<Packet> (m_input.packetSize);
+  WifiMode mode = WifiMode (m_input.txMode);
+  m_tx->SendPacket (p, mode, WIFI_PREAMBLE_SHORT, m_input.txPowerLevel);
+}
+
+void 
+PsrExperiment::Receive (Ptr<Packet> p, double snr, WifiMode mode, enum WifiPreamble preamble)
+{
+  m_output.received++;
+}
+
+PsrExperiment::PsrExperiment ()
+{}
+PsrExperiment::Input::Input ()
+  : distance (5.0),
+    txMode ("wifia-6mbs"),
+    txPowerLevel (0),
+    packetSize (2304),
+    nPackets (400)
+{}
+
+struct PsrExperiment::Output
+PsrExperiment::Run (struct PsrExperiment::Input input)
+{
+  m_output.received = 0;
+  m_input = input;
+
+  Ptr<MobilityModel> posTx = CreateObject<StaticMobilityModel> ();
+  posTx->SetPosition (Vector (0.0, 0.0, 0.0));
+  Ptr<MobilityModel> posRx = CreateObject<StaticMobilityModel> ();
+  posRx->SetPosition (Vector (m_input.distance, 0.0, 0.0));
+
+  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
+  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
+  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
+  channel->SetPropagationLossModel (log);
+
+  Ptr<YansWifiPhy> tx = CreateObject<YansWifiPhy> ();
+  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
+  Ptr<ErrorRateModel> error = CreateObject<ErrorRateModel> ();
+  tx->SetErrorRateModel (error);
+  rx->SetErrorRateModel (error);
+  tx->SetChannel (channel);
+  rx->SetChannel (channel);
+  tx->SetMobility (posTx);
+  rx->SetMobility (posRx);
+
+  rx->SetReceiveOkCallback (MakeCallback (&PsrExperiment::Receive, this));
+
+  for (uint32_t i = 0; i < m_input.nPackets; ++i)
+    {
+      Simulator::Schedule (Seconds (i), &PsrExperiment::Send, this);
+    }
+  m_tx = tx;
+  Simulator::Run ();
+  return m_output;
+}
+
+
+class CollisionExperiment
+{
+public:
+  struct Input
+  {
+    Input ();
+    Time interval;
+    double xA;
+    double xB;
+    std::string txModeA;
+    std::string txModeB;
+    uint8_t txPowerLevelA;
+    uint8_t txPowerLevelB;
+    uint32_t packetSizeA;
+    uint32_t packetSizeB;
+    uint32_t nPackets;
+  };
+  struct Output
+  {
+    uint32_t receivedA;
+    uint32_t receivedB;
+  };
+  CollisionExperiment ();
+
+  struct CollisionExperiment::Output Run (struct CollisionExperiment::Input input);
+private:
+  void SendA (void) const;
+  void SendB (void) const;
+  void Receive (Ptr<Packet> p, double snr, WifiMode mode, enum WifiPreamble preamble);
+  Ptr<WifiPhy> m_txA;
+  Ptr<WifiPhy> m_txB;
+  uint32_t m_flowIdA;
+  uint32_t m_flowIdB;
+  struct Input m_input;
+  struct Output m_output;
+};
+
+void 
+CollisionExperiment::SendA (void) const
+{
+  Ptr<Packet> p = Create<Packet> (m_input.packetSizeA);
+  p->AddTag (FlowIdTag (m_flowIdA));
+  m_txA->SendPacket (p, WifiMode (m_input.txModeA), 
+		     WIFI_PREAMBLE_SHORT, m_input.txPowerLevelA);
+}
+
+void 
+CollisionExperiment::SendB (void) const
+{
+  Ptr<Packet> p = Create<Packet> (m_input.packetSizeB);
+  p->AddTag (FlowIdTag (m_flowIdB));
+  m_txB->SendPacket (p, WifiMode (m_input.txModeB), 
+		     WIFI_PREAMBLE_SHORT, m_input.txPowerLevelB);
+}
+
+void 
+CollisionExperiment::Receive (Ptr<Packet> p, double snr, WifiMode mode, enum WifiPreamble preamble)
+{
+  FlowIdTag tag;
+  p->FindFirstMatchingTag (tag);
+  if (tag.GetFlowId () == m_flowIdA)
+    {
+      m_output.receivedA++;
+    }
+  else if (tag.GetFlowId () == m_flowIdB)
+    {
+      m_output.receivedB++;
+    }
+}
+
+CollisionExperiment::CollisionExperiment ()
+{}
+CollisionExperiment::Input::Input ()
+  : interval (MicroSeconds (0)),
+    xA (-5),
+    xB (5),
+    txModeA ("wifia-6mbs"),
+    txModeB ("wifia-6mbs"),
+    txPowerLevelA (0),
+    txPowerLevelB (0),
+    packetSizeA (2304),
+    packetSizeB (2304),
+    nPackets (400)
+{}
+
+struct CollisionExperiment::Output
+CollisionExperiment::Run (struct CollisionExperiment::Input input)
+{
+  m_output.receivedA = 0;
+  m_output.receivedB = 0;
+  m_input = input;
+
+  m_flowIdA = FlowIdTag::AllocateFlowId ();
+  m_flowIdB = FlowIdTag::AllocateFlowId ();
+
+  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
+  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
+  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
+  channel->SetPropagationLossModel (log);
+
+  Ptr<MobilityModel> posTxA = CreateObject<StaticMobilityModel> ();
+  posTxA->SetPosition (Vector (input.xA, 0.0, 0.0));
+  Ptr<MobilityModel> posTxB = CreateObject<StaticMobilityModel> ();
+  posTxB->SetPosition (Vector (input.xB, 0.0, 0.0));
+  Ptr<MobilityModel> posRx = CreateObject<StaticMobilityModel> ();
+  posRx->SetPosition (Vector (0, 0.0, 0.0));
+
+  Ptr<YansWifiPhy> txA = CreateObject<YansWifiPhy> ();
+  Ptr<YansWifiPhy> txB = CreateObject<YansWifiPhy> ();
+  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
+
+  Ptr<ErrorRateModel> error = CreateObject<ErrorRateModel> ();
+  txA->SetErrorRateModel (error);
+  txB->SetErrorRateModel (error);
+  rx->SetErrorRateModel (error);
+  txA->SetChannel (channel);
+  txB->SetChannel (channel);
+  rx->SetChannel (channel);
+  txA->SetMobility (posTxA);
+  txB->SetMobility (posTxB);
+  rx->SetMobility (posRx);
+
+
+  rx->SetReceiveOkCallback (MakeCallback (&CollisionExperiment::Receive, this));
+
+  for (uint32_t i = 0; i < m_input.nPackets; ++i)
+    {
+      Simulator::Schedule (Seconds (i), &CollisionExperiment::SendA, this);
+    }
+  for (uint32_t i = 0; i < m_input.nPackets; ++i)
+    {
+      Simulator::Schedule (Seconds (i) + m_input.interval, &CollisionExperiment::SendB, this);
+    }
+  m_txA = txA;
+  m_txB = txB;
+  Simulator::Run ();
+  return m_output;
+}
+
+
+static void PrintPsr (int argc, char *argv[])
+{
+  PsrExperiment experiment;
+  struct PsrExperiment::Input input;
+
+  CommandLine cmd;
+  cmd.AddValue ("Distance", "The distance between two phys", input.distance);
+  cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize);
+  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
+  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
+  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
+  cmd.Parse (argc, argv);
+
+  struct PsrExperiment::Output output;
+  output = experiment.Run (input);
+
+  double psr = output.received;
+  psr /= input.nPackets ;
+  
+  std::cout << psr << std::endl;
+}
+
+double CalcPsr (struct PsrExperiment::Output output, struct PsrExperiment::Input input)
+{
+  double psr = output.received;
+  psr /= input.nPackets ;
+  return psr;
+}
+
+static void PrintPsrVsDistance (int argc, char *argv[])
+{
+  struct PsrExperiment::Input input;
+  CommandLine cmd;
+  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);  
+  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
+  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
+  cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize);
+  cmd.Parse (argc, argv);
+  for (input.distance = 1.0; input.distance < 165; input.distance += 2.0)
+    {
+      std::cout << input.distance;
+      PsrExperiment experiment;
+      struct PsrExperiment::Output output;
+
+      input.txMode = "wifia-6mbs";
+      output = experiment.Run (input);
+      std::cout << " " << CalcPsr (output, input);
+    
+      input.txMode = "wifia-9mbs";
+      output = experiment.Run (input);
+      std::cout << " " << CalcPsr (output, input);
+
+      input.txMode = "wifia-12mbs";
+      output = experiment.Run (input);
+      std::cout << " " << CalcPsr (output, input);
+
+      input.txMode = "wifia-18mbs";
+      output = experiment.Run (input);
+      std::cout << " " << CalcPsr (output, input);
+
+      input.txMode = "wifia-24mbs";
+      output = experiment.Run (input);
+      std::cout << " " << CalcPsr (output, input);
+
+      input.txMode = "wifia-36mbs";
+      output = experiment.Run (input);
+      std::cout << " " << CalcPsr (output, input);
+
+      input.txMode = "wifia-48mbs";
+      output = experiment.Run (input);
+      std::cout << " " << CalcPsr (output, input);
+
+      input.txMode = "wifia-54mbs";
+      output = experiment.Run (input);
+      std::cout << " " << CalcPsr (output, input);
+
+      std::cout << std::endl;
+    }
+}
+
+static void PrintSizeVsRange (int argc, char *argv[])
+{
+  double targetPsr = 0.05;
+  struct PsrExperiment::Input input;
+  CommandLine cmd;
+  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);  
+  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
+  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
+  cmd.AddValue ("TargetPsr", "The psr needed to assume that we are within range", targetPsr);
+  cmd.Parse (argc, argv);
+  for (input.packetSize = 10; input.packetSize < 3000; input.packetSize += 40)
+    {
+      double precision = 0.1;
+      double low = 1.0;
+      double high = 200.0;
+      while (high - low > precision)
+	{
+	  double middle = low + (high - low) / 2;
+	  struct PsrExperiment::Output output;
+	  PsrExperiment experiment;
+	  input.distance = middle;
+	  output = experiment.Run (input);
+	  double psr = CalcPsr (output, input);
+	  if (psr >= targetPsr)
+	    {
+	      low = middle;
+	    }
+	  else
+	    {
+	      high = middle;
+	    }
+	}
+      std::cout << input.packetSize << " " << input.distance << std::endl;
+    }
+}
+
+static void PrintPsrVsCollisionInterval (int argc, char *argv[])
+{
+  CollisionExperiment::Input input;
+  input.nPackets = 100;
+  CommandLine cmd;
+  cmd.AddValue ("NPackets", "The number of packets to send for each transmitter", input.nPackets);
+  cmd.AddValue ("xA", "the position of transmitter A", input.xA);
+  cmd.AddValue ("xB", "the position of transmitter B", input.xB);
+  for (uint32_t i = 0; i < 100; i += 1)
+    {
+      CollisionExperiment experiment;
+      CollisionExperiment::Output output;
+      input.interval = MicroSeconds (i);
+      output = experiment.Run (input);
+      double perA = (output.receivedA+0.0) / (input.nPackets+0.0);
+      double perB = (output.receivedB+0.0) / (input.nPackets+0.0);
+      std::cout << i << " " << perA << " " << perB << std::endl;
+    }
+  for (uint32_t i = 100; i < 4000; i += 50)
+    {
+      CollisionExperiment experiment;
+      CollisionExperiment::Output output;
+      input.interval = MicroSeconds (i);
+      output = experiment.Run (input);
+      double perA = (output.receivedA+0.0) / (input.nPackets+0.0);
+      double perB = (output.receivedB+0.0) / (input.nPackets+0.0);
+      std::cout << i << " " << perA << " " << perB << std::endl;
+    }
+}
+
+
+
+int main (int argc, char *argv[])
+{
+  if (argc <= 1)
+    {
+      std::cout << "Available experiments: "
+		<< "Psr "
+		<< "SizeVsRange "
+		<< "PsrVsDistance "
+		<< "PsrVsCollisionInterval "
+		<< std::endl;
+      return -1;
+    }
+  std::string type = argv[1];
+  argc--;
+  argv[1] = argv[0];
+  argv++;
+  if (type == "Psr")
+    {
+      PrintPsr (argc, argv);
+    }
+  else if (type == "SizeVsRange")
+    {
+      PrintSizeVsRange (argc, argv);
+    }
+  else if (type == "PsrVsDistance")
+    {
+      PrintPsrVsDistance (argc, argv);
+    }
+  else if (type == "PsrVsCollisionInterval")
+    {
+      PrintPsrVsCollisionInterval (argc, argv);
+    }
+
+  return 0;
+}
--- a/src/devices/wifi/wifi-phy.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/wifi-phy.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -37,32 +37,32 @@
 
 namespace ns3 {
 
-  // Define all the WifiMode needed for 802.11a
-static WifiMode g_6mba = WifiModeFactory::CreateBpsk ("wifia-6mbs",
-                                                      true,
-                                                      20000000, 6000000, 12000000);
-static WifiMode g_9mba = WifiModeFactory::CreateBpsk ("wifia-9mbs",
-                                                      false,
-                                                      20000000, 9000000, 12000000);
+// Define all the WifiMode needed for 802.11a
+WifiMode WifiPhy::g_6mba = WifiModeFactory::CreateBpsk ("wifia-6mbs",
+                                                        true,
+                                                        20000000, 6000000, 12000000);
+WifiMode WifiPhy::g_9mba = WifiModeFactory::CreateBpsk ("wifia-9mbs",
+                                                        false,
+                                                        20000000, 9000000, 12000000);
 // XXX explain why Bpsk rather than Qpsk
-static WifiMode g_12mba = WifiModeFactory::CreateBpsk ("wifia-12mbs",
-                                                       true,
-                                                       20000000, 12000000, 24000000);
-static WifiMode g_18mba = WifiModeFactory::CreateBpsk ("wifia-18mbs",
-                                                       false,
-                                                       20000000, 18000000, 24000000);
-static WifiMode g_24mba = WifiModeFactory::CreateBpsk ("wifia-24mbs",
-                                                       true,
-                                                       20000000, 24000000, 48000000);
-static WifiMode g_36mba = WifiModeFactory::CreateBpsk ("wifia-36mbs",
-                                                       false,
-                                                       20000000, 36000000, 48000000);
-static WifiMode g_48mba = WifiModeFactory::CreateBpsk ("wifia-48mbs",
-                                                       false,
-                                                       20000000, 48000000, 72000000);
-static WifiMode g_54mba = WifiModeFactory::CreateBpsk ("wifia-54mbs",
-                                                       false,
-                                                       20000000, 54000000, 72000000);
+WifiMode WifiPhy::g_12mba = WifiModeFactory::CreateBpsk ("wifia-12mbs",
+                                                         true,
+                                                         20000000, 12000000, 24000000);
+WifiMode WifiPhy::g_18mba = WifiModeFactory::CreateBpsk ("wifia-18mbs",
+                                                         false,
+                                                         20000000, 18000000, 24000000);
+WifiMode WifiPhy::g_24mba = WifiModeFactory::CreateBpsk ("wifia-24mbs",
+                                                         true,
+                                                         20000000, 24000000, 48000000);
+WifiMode WifiPhy::g_36mba = WifiModeFactory::CreateBpsk ("wifia-36mbs",
+                                                         false,
+                                                         20000000, 36000000, 48000000);
+WifiMode WifiPhy::g_48mba = WifiModeFactory::CreateBpsk ("wifia-48mbs",
+                                                         false,
+                                                         20000000, 48000000, 72000000);
+WifiMode WifiPhy::g_54mba = WifiModeFactory::CreateBpsk ("wifia-54mbs",
+                                                         false,
+                                                         20000000, 54000000, 72000000);
 
 
 /****************************************************************
@@ -72,106 +72,6 @@
 WifiPhyListener::~WifiPhyListener ()
 {}
 
-
-/****************************************************************
- *       Phy event class
- ****************************************************************/
-
-class RxEvent
-{
-public:
-  RxEvent (uint32_t size, WifiMode payloadMode, 
-           enum WifiPreamble preamble,
-           Time duration, double rxPower)
-    : m_size (size),
-      m_payloadMode (payloadMode),
-      m_preamble (preamble),
-      m_startTime (Simulator::Now ()),
-      m_endTime (m_startTime + duration),
-      m_rxPowerW (rxPower),
-      m_refCount (1)
-  {}
-  ~RxEvent ()
-  {
-    NS_ASSERT (m_refCount == 0);
-  }
-  
-  void Ref (void) const {
-    m_refCount++;
-  }
-  void Unref (void) const {
-    m_refCount--;
-    if (m_refCount == 0) {
-      delete this;
-    }
-  }
-  Time GetDuration (void) const {
-    return m_endTime - m_startTime;
-  }
-  Time GetStartTime (void) const {
-    return m_startTime;
-  }
-  Time GetEndTime (void) const {
-    return m_endTime;
-  }
-  bool Overlaps (Time time) const {
-    if (m_startTime <= time &&
-        m_endTime >= time) {
-      return true;
-    } else {
-      return false;
-    }
-  }
-  double GetRxPowerW (void) const {
-    return m_rxPowerW;
-  }
-  uint32_t GetSize (void) const {
-    return m_size;
-  }
-  WifiMode GetPayloadMode (void) const {
-    return m_payloadMode;
-  }
-  enum WifiPreamble GetPreambleType (void) const {
-    return m_preamble;
-  }
-
-private:
-  uint32_t m_size;
-  WifiMode m_payloadMode;
-  enum WifiPreamble m_preamble;
-  Time m_startTime;
-  Time m_endTime;
-  double m_rxPowerW;
-  mutable int m_refCount;
-};
-
-
-/****************************************************************
- *       Class which records SNIR change events for a 
- *       short period of time.
- ****************************************************************/
-
-WifiPhy::NiChange::NiChange (Time time, double delta)
-  : m_time (time), m_delta (delta) 
-{}
-Time
-WifiPhy::NiChange::GetTime (void) const
-{
-  return m_time;
-}
-double 
-WifiPhy::NiChange::GetDelta (void) const
-{
-  return m_delta;
-}
-bool 
-WifiPhy::NiChange::operator < (WifiPhy::NiChange const &o) const
-{
-  return (m_time < o.m_time)?true:false;
-}
-
-
-
 /****************************************************************
  *       The actual WifiPhy class
  ****************************************************************/
@@ -183,82 +83,11 @@
 {
   static TypeId tid = TypeId ("ns3::WifiPhy")
     .SetParent<Object> ()
-    .AddConstructor<WifiPhy> ()
-    .AddAttribute ("EnergyDetectionThreshold",
-                   "The energy of a received signal should be higher than "
-                   "this threshold (dbm) to allow the PHY layer to detect the signal.",
-                   DoubleValue (-140.0),
-                   MakeDoubleAccessor (&WifiPhy::SetEdThreshold,
-                                       &WifiPhy::GetEdThreshold),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("TxGain",
-                   "Transmission gain (dB).",
-                   DoubleValue (1.0),
-                   MakeDoubleAccessor (&WifiPhy::SetTxGain,
-                                       &WifiPhy::GetTxGain),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("RxGain",
-                   "Reception gain (dB).",
-                   DoubleValue (1.0),
-                   MakeDoubleAccessor (&WifiPhy::SetRxGain,
-                                       &WifiPhy::GetRxGain),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("TxPowerLevels",
-                   "Number of transmission power levels available between "
-                   "TxPowerBase and TxPowerEnd included.",
-                   UintegerValue (1),
-                   MakeUintegerAccessor (&WifiPhy::m_nTxPower),
-                   MakeUintegerChecker<uint32_t> ())
-    .AddAttribute ("TxPowerEnd",
-                   "Maximum available transmission level (dbm).",
-                   DoubleValue (16.0206),
-                   MakeDoubleAccessor (&WifiPhy::SetTxPowerEnd, 
-                                       &WifiPhy::GetTxPowerEnd),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("TxPowerStart",
-                   "Minimum available transmission level (dbm).",
-                   DoubleValue (16.0206),
-                   MakeDoubleAccessor (&WifiPhy::SetTxPowerStart, 
-                                       &WifiPhy::GetTxPowerStart),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("RxNoise",
-                   "Ratio of energy lost by receiver (dB).",
-                   DoubleValue (7),
-                   MakeDoubleAccessor (&WifiPhy::SetRxNoise,
-                                       &WifiPhy::GetRxNoise),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("Standard", "The standard chosen configures a set of transmission modes"
-                   " and some PHY-specific constants.",
-                   EnumValue (WIFI_PHY_STANDARD_80211a),
-                   MakeEnumAccessor (&WifiPhy::SetStandard),
-                   MakeEnumChecker (WIFI_PHY_STANDARD_80211a, "802.11a",
-                                    WIFI_PHY_STANDARD_holland, "holland"))
-    .AddTraceSource ("State",
-                     "The WifiPhy state",
-                     MakeTraceSourceAccessor (&WifiPhy::m_stateLogger))
-    .AddTraceSource ("RxOk",
-                     "A packet has been received successfully.",
-                     MakeTraceSourceAccessor (&WifiPhy::m_rxOkTrace))
-    .AddTraceSource ("RxError",
-                     "A packet has been received unsuccessfully.",
-                     MakeTraceSourceAccessor (&WifiPhy::m_rxErrorTrace))
-    .AddTraceSource ("Tx", "Packet transmission is starting.",
-                     MakeTraceSourceAccessor (&WifiPhy::m_txTrace))
     ;
   return tid;
 }
 
 WifiPhy::WifiPhy ()
-  : m_syncing (false),
-    m_endTx (Seconds (0)),
-    m_endSync (Seconds (0)),
-    m_endCcaBusy (Seconds (0)),
-    m_startTx (Seconds (0)),
-    m_startSync (Seconds (0)),
-    m_startCcaBusy (Seconds (0)),
-    m_previousStateChangeTime (Seconds (0)),
-    m_endSyncEvent (),
-    m_random (0.0, 1.0)
 {
   NS_LOG_FUNCTION (this);
 }
@@ -268,1124 +97,4 @@
   NS_LOG_FUNCTION (this);
 }
 
-void
-WifiPhy::DoDispose (void)
-{
-  NS_LOG_FUNCTION (this);
-  m_channel = 0;
-  m_events.clear ();
-  m_modes.clear ();
-}
-
-void
-WifiPhy::SetStandard (enum WifiPhyStandard standard)
-{
-  NS_LOG_FUNCTION (this << standard);
-  m_standard = standard;
-  switch (standard) {
-  case WIFI_PHY_STANDARD_80211a:
-    Configure80211a ();
-    break;
-  case WIFI_PHY_STANDARD_holland:
-    ConfigureHolland ();
-    break;
-  default:
-    NS_ASSERT (false);
-    break;
-  }
-}
-
-
-void 
-WifiPhy::SetRxNoise (double db)
-{
-  NS_LOG_FUNCTION (this << db);
-  m_rxNoiseRatio = DbToRatio (db);
-}
-void 
-WifiPhy::SetTxPowerStart (double start)
-{
-  NS_LOG_FUNCTION (this << start);
-  m_txPowerBaseDbm = start;
-}
-void 
-WifiPhy::SetTxPowerEnd (double end)
-{
-  NS_LOG_FUNCTION (this << end);
-  m_txPowerEndDbm = end;
-}
-void 
-WifiPhy::SetNTxPower (uint32_t n)
-{
-  NS_LOG_FUNCTION (this << n);
-  m_nTxPower = n;
-}
-void 
-WifiPhy::SetTxGain (double gain)
-{
-  NS_LOG_FUNCTION (this << gain);
-  m_txGainDb = gain;
-}
-void 
-WifiPhy::SetRxGain (double gain)
-{
-  NS_LOG_FUNCTION (this << gain);
-  m_rxGainDb = gain;
-}
-void 
-WifiPhy::SetEdThreshold (double threshold)
-{
-  NS_LOG_FUNCTION (this << threshold);
-  m_edThresholdW = DbmToW (threshold);
-}
-double 
-WifiPhy::GetRxNoise (void) const
-{
-  return RatioToDb (m_rxNoiseRatio);
-}
-double 
-WifiPhy::GetTxPowerStart (void) const
-{
-  return m_txPowerBaseDbm;
-}
-double 
-WifiPhy::GetTxPowerEnd (void) const
-{
-  return m_txPowerEndDbm;
-}
-double 
-WifiPhy::GetTxGain (void) const
-{
-  return m_txGainDb;
-}
-double 
-WifiPhy::GetRxGain (void) const
-{
-  return m_rxGainDb;
-}
-
-double 
-WifiPhy::GetEdThreshold (void) const
-{
-  return WToDbm (m_edThresholdW);
-}
-
-Ptr<WifiChannel> 
-WifiPhy::GetChannel (void) const
-{
-  return m_channel;
-}
-
-void 
-WifiPhy::SetChannel (Ptr<WifiChannel> channel)
-{
-  m_channel = channel;
-}
-
-void 
-WifiPhy::SetReceiveOkCallback (SyncOkCallback callback)
-{
-  m_syncOkCallback = callback;
-}
-void 
-WifiPhy::SetReceiveErrorCallback (SyncErrorCallback callback)
-{
-  m_syncErrorCallback = callback;
-}
-void 
-WifiPhy::StartReceivePacket (Ptr<Packet> packet, 
-                             double rxPowerDbm,
-                             WifiMode txMode,
-                             enum WifiPreamble preamble)
-{
-  NS_LOG_FUNCTION (this << packet << rxPowerDbm << txMode << preamble);
-  rxPowerDbm += m_rxGainDb;
-  double rxPowerW = DbmToW (rxPowerDbm);
-  Time rxDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble);
-  Time endRx = Simulator::Now () + rxDuration;
-
-  Ptr<RxEvent> event = Create<RxEvent> (packet->GetSize (), 
-                                        txMode,
-                                        preamble,
-                                        rxDuration,
-                                        rxPowerW);
-  AppendEvent (event);
-
-  switch (GetState ()) {
-  case WifiPhy::SYNC:
-    NS_LOG_DEBUG ("drop packet because already in Sync (power="<<
-                  rxPowerW<<"W)");
-    if (endRx > m_endSync) 
-      {
-        goto maybeCcaBusy;
-      }
-    break;
-  case WifiPhy::TX:
-    NS_LOG_DEBUG ("drop packet because already in Tx (power="<<
-                  rxPowerW<<"W)");
-    if (endRx > m_endTx) 
-      {
-        goto maybeCcaBusy;
-      }
-    break;
-  case WifiPhy::CCA_BUSY:
-  case WifiPhy::IDLE:
-    if (rxPowerW > m_edThresholdW) 
-      {
-        NS_LOG_DEBUG ("sync (power="<<rxPowerW<<"W)");
-        // sync to signal
-        NotifySyncStart (rxDuration);
-        SwitchToSync (rxDuration);
-        NS_ASSERT (m_endSyncEvent.IsExpired ());
-        m_endSyncEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndSync, this, 
-                                              packet,
-                                              event);
-      }
-    else 
-      {
-        NS_LOG_DEBUG ("drop packet because signal power too Small ("<<
-                      rxPowerW<<"<"<<m_edThresholdW<<")");
-        goto maybeCcaBusy;
-      }
-    break;
-  }
-
-  return;
-
- maybeCcaBusy:
-
-  if (rxPowerW > m_edThresholdW) 
-    {
-      SwitchMaybeToCcaBusy (rxDuration);
-      NotifyCcaBusyStart (rxDuration);
-    } 
-  else 
-    {
-      double threshold = m_edThresholdW - rxPowerW;
-      NiChanges ni;
-      CalculateNoiseInterferenceW (event, &ni);
-      double noiseInterferenceW = 0.0;
-      Time end = Simulator::Now ();
-      for (NiChanges::const_iterator i = ni.begin (); i != ni.end (); i++) 
-        {
-          noiseInterferenceW += i->GetDelta ();
-          if (noiseInterferenceW < threshold) 
-            {
-              break;
-            }
-          end = i->GetTime ();
-        }
-      if (end > Simulator::Now ()) 
-        {
-          Time delta = end - Simulator::Now ();
-          SwitchMaybeToCcaBusy (delta);
-          NotifyCcaBusyStart (delta);
-        }
-    }
-
-}
-void 
-WifiPhy::SendPacket (Ptr<const Packet> packet, WifiMode txMode, WifiPreamble preamble, uint8_t txPower)
-{
-  NS_LOG_FUNCTION (this << packet << txMode << preamble << (uint32_t)txPower);
-  /* Transmission can happen if:
-   *  - we are syncing on a packet. It is the responsability of the
-   *    MAC layer to avoid doing this but the PHY does nothing to 
-   *    prevent it.
-   *  - we are idle
-   */
-  NS_ASSERT (!IsStateTx ());
-
-  m_txTrace (packet, txMode, preamble, txPower);
-  Time txDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble);
-  NotifyTxStart (txDuration);
-  SwitchToTx (txDuration);
-  m_channel->Send (this, packet, GetPowerDbm (txPower) + m_txGainDb, txMode, preamble);
-}
-
-uint32_t 
-WifiPhy::GetNModes (void) const
-{
-  return m_modes.size ();
-}
-WifiMode 
-WifiPhy::GetMode (uint32_t mode) const
-{
-  return m_modes[mode];
-}
-uint32_t 
-WifiPhy::GetNTxPower (void) const
-{
-  return m_nTxPower;
-}
-
-double 
-WifiPhy::CalculateSnr (WifiMode txMode, double ber) const
-{
-  double low, high, precision;
-  low = 1e-25;
-  high = 1e25;
-  precision = 1e-12;
-  while (high - low > precision) 
-    {
-      NS_ASSERT (high >= low);
-      double middle = low + (high - low) / 2;
-      if ((1 - GetChunkSuccessRate (txMode, middle, 1)) > ber) 
-        {
-          low = middle;
-        } 
-      else 
-        {
-          high = middle;
-        }
-    }
-  return low;
-}
-
-void
-WifiPhy::Configure80211aParameters (void)
-{
-  NS_LOG_FUNCTION (this);
-  m_plcpLongPreambleDelayUs = 16;
-  m_plcpShortPreambleDelayUs = 16;
-  m_longPlcpHeaderMode = g_6mba;
-  m_shortPlcpHeaderMode = g_6mba;
-  m_plcpHeaderLength = 4 + 1 + 12 + 1 + 6;
-  /* 4095 bytes at a 6Mb/s rate with a 1/2 coding rate. */
-  m_maxPacketDuration = CalculateTxDuration (4095, g_6mba, WIFI_PREAMBLE_LONG);
-}
-
-void
-WifiPhy::PrintModes (void) const
-{
-#if 0
-  for (double db = -10; db < 30; db+= 0.5) {
-    double snr = DbToRatio (db);
-    std::cout <<snr<<" ";
-    for (uint8_t i = 0; i < GetNModes (); i++) {
-      WifiMode mode = GetMode (i);
-      double ber = 1-GetChunkSuccessRate (mode,snr, 2000*8);
-      std::cout <<ber<< " ";
-    }
-    std::cout << std::endl;
-  }
-#endif
-}
-
-void
-WifiPhy::Configure80211a (void)
-{
-  NS_LOG_FUNCTION (this);
-  Configure80211aParameters ();
-  m_modes.push_back (g_6mba);
-  m_modes.push_back (g_9mba);
-  m_modes.push_back (g_12mba);
-  m_modes.push_back (g_18mba);
-  m_modes.push_back (g_24mba);
-  m_modes.push_back (g_36mba);
-  m_modes.push_back (g_48mba);
-  m_modes.push_back (g_54mba);
-
-  PrintModes ();
-}
-
-void
-WifiPhy::ConfigureHolland (void)
-{
-  NS_LOG_FUNCTION (this);
-  Configure80211aParameters ();
-  m_modes.push_back (g_6mba);
-  m_modes.push_back (g_12mba);
-  m_modes.push_back (g_18mba);
-  m_modes.push_back (g_36mba);
-  m_modes.push_back (g_54mba);
-
-  PrintModes ();
-}
-
-void 
-WifiPhy::RegisterListener (WifiPhyListener *listener)
-{
-  m_listeners.push_back (listener);
-}
-
-bool 
-WifiPhy::IsStateCcaBusy (void)
-{
-  return GetState () == CCA_BUSY;
-}
-
-bool 
-WifiPhy::IsStateIdle (void)
-{
-  return (GetState () == IDLE)?true:false;
-}
-bool 
-WifiPhy::IsStateBusy (void)
-{
-  return (GetState () != IDLE)?true:false;
-}
-bool 
-WifiPhy::IsStateSync (void)
-{
-  return (GetState () == SYNC)?true:false;
-}
-bool 
-WifiPhy::IsStateTx (void)
-{
-  return (GetState () == TX)?true:false;
-}
-
-Time
-WifiPhy::GetStateDuration (void)
-{
-  return Simulator::Now () - m_previousStateChangeTime;
-}
-Time
-WifiPhy::GetDelayUntilIdle (void)
-{
-  Time retval;
-
-  switch (GetState ()) {
-  case SYNC:
-    retval = m_endSync - Simulator::Now ();
-    break;
-  case TX:
-    retval = m_endTx - Simulator::Now ();
-    break;
-  case CCA_BUSY:
-    retval = m_endCcaBusy - Simulator::Now ();
-    break;
-  case IDLE:
-    retval = Seconds (0);
-    break;
-  default:
-    NS_ASSERT (false);
-    // NOTREACHED
-    retval = Seconds (0);
-    break;
-  }
-  retval = Max (retval, Seconds (0));
-  return retval;
-}
-
-Time 
-WifiPhy::GetLastRxStartTime (void) const
-{
-  return m_startSync;
-}
-
-
-Time
-WifiPhy::CalculateTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble) const
-{
-  uint64_t delay = 0;
-  switch (m_standard) {
-  case WIFI_PHY_STANDARD_80211a:
-  case WIFI_PHY_STANDARD_holland: {
-    delay += m_plcpLongPreambleDelayUs;
-    // symbol duration is 4us
-    delay += 4;
-    delay += lrint (ceil ((size * 8.0 + 16.0 + 6.0) / payloadMode.GetDataRate () / 4e-6) * 4);
-  } break;
-  default:
-    // quiet compiler.
-    NS_ASSERT (false);
-    break;
-  }
-  return MicroSeconds (delay);
-}
-
-char const *
-WifiPhy::StateToString (enum State state)
-{
-  switch (state) {
-  case TX:
-    return "TX";
-    break;
-  case CCA_BUSY:
-    return "CCA_BUSY";
-    break;
-  case IDLE:
-    return "IDLE";
-    break;
-  case SYNC:
-    return "SYNC";
-    break;
-  default:
-    NS_ASSERT (false);
-    // quiet compiler
-    return "INVALID";
-    break;
-  }
-}
-enum WifiPhy::State 
-WifiPhy::GetState (void)
-{
-  if (m_endTx > Simulator::Now ()) 
-    {
-      return WifiPhy::TX;
-    } 
-  else if (m_syncing) 
-    {
-      return WifiPhy::SYNC;
-    } 
-  else if (m_endCcaBusy > Simulator::Now ()) 
-    {
-      return WifiPhy::CCA_BUSY;
-    } 
-  else 
-    {
-      return WifiPhy::IDLE;
-    }
-}
-
-double 
-WifiPhy::DbToRatio (double dB) const
-{
-  double ratio = pow(10.0,dB/10.0);
-  return ratio;
-}
-
-double 
-WifiPhy::DbmToW (double dBm) const
-{
-  double mW = pow(10.0,dBm/10.0);
-  return mW / 1000.0;
-}
-
-double
-WifiPhy::WToDbm (double w) const
-{
-  return 10.0 * log10(w * 1000.0);
-}
-
-double
-WifiPhy::RatioToDb (double ratio) const
-{
-  return 10.0 * log10(ratio);
-}
-
-double
-WifiPhy::GetEdThresholdW (void) const
-{
-  return m_edThresholdW;
-}
-
-Time
-WifiPhy::GetMaxPacketDuration (void) const
-{
-  return m_maxPacketDuration;
-}
-
-double 
-WifiPhy::GetPowerDbm (uint8_t power) const
-{
-  NS_ASSERT (m_txPowerBaseDbm <= m_txPowerEndDbm);
-  NS_ASSERT (m_nTxPower > 0);
-  double dbm = m_txPowerBaseDbm + power * (m_txPowerEndDbm - m_txPowerBaseDbm) / m_nTxPower;
-  return dbm;
-}
-
-void 
-WifiPhy::NotifyTxStart (Time duration)
-{
-  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
-    (*i)->NotifyTxStart (duration);
-  }
-}
-void 
-WifiPhy::NotifySyncStart (Time duration)
-{
-  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
-    (*i)->NotifyRxStart (duration);
-  }
-}
-void 
-WifiPhy::NotifySyncEndOk (void)
-{
-  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
-    (*i)->NotifyRxEndOk ();
-  }
-}
-void 
-WifiPhy::NotifySyncEndError (void)
-{
-  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
-    (*i)->NotifyRxEndError ();
-  }
-}
-void 
-WifiPhy::NotifyCcaBusyStart (Time duration)
-{
-  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
-    (*i)->NotifyCcaBusyStart (duration);
-  }
-}
-
-void
-WifiPhy::LogPreviousIdleAndCcaBusyStates (void)
-{
-  Time now = Simulator::Now ();
-  Time idleStart = Max (m_endCcaBusy, m_endSync);
-  idleStart = Max (idleStart, m_endTx);
-  NS_ASSERT (idleStart <= now);
-  if (m_endCcaBusy > m_endSync && 
-      m_endCcaBusy > m_endTx) {
-    Time ccaBusyStart = Max (m_endTx, m_endSync);
-    ccaBusyStart = Max (ccaBusyStart, m_startCcaBusy);
-    m_stateLogger (ccaBusyStart, idleStart - ccaBusyStart, WifiPhy::CCA_BUSY);
-  }
-  m_stateLogger (idleStart, now - idleStart, WifiPhy::IDLE);
-}
-
-void
-WifiPhy::SwitchToTx (Time txDuration)
-{
-  Time now = Simulator::Now ();
-  switch (GetState ()) {
-  case WifiPhy::SYNC:
-    /* The packet which is being received as well
-     * as its endSync event are cancelled by the caller.
-     */
-    m_syncing = false;
-    m_stateLogger (m_startSync, now - m_startSync, WifiPhy::SYNC);
-    m_endSyncEvent.Cancel ();
-    m_endSync = now;
-    break;
-  case WifiPhy::CCA_BUSY: {
-    Time ccaStart = Max (m_endSync, m_endTx);
-    ccaStart = Max (ccaStart, m_startCcaBusy);
-    m_stateLogger (ccaStart, now - ccaStart, WifiPhy::CCA_BUSY);
-  } break;
-  case WifiPhy::IDLE:
-    LogPreviousIdleAndCcaBusyStates ();
-    break;
-  default:
-    NS_ASSERT (false);
-    break;
-  }
-  m_stateLogger (now, txDuration, WifiPhy::TX);
-  m_previousStateChangeTime = now;
-  m_endTx = now + txDuration;
-  m_startTx = now;
-}
-void
-WifiPhy::SwitchToSync (Time rxDuration)
-{
-  NS_ASSERT (IsStateIdle () || IsStateCcaBusy ());
-  NS_ASSERT (!m_syncing);
-  Time now = Simulator::Now ();
-  switch (GetState ()) {
-  case WifiPhy::IDLE:
-    LogPreviousIdleAndCcaBusyStates ();
-    break;
-  case WifiPhy::CCA_BUSY: {
-    Time ccaStart = Max (m_endSync, m_endTx);
-    ccaStart = Max (ccaStart, m_startCcaBusy);
-    m_stateLogger (ccaStart, now - ccaStart, WifiPhy::CCA_BUSY);
-  } break;
-  case WifiPhy::SYNC:
-  case WifiPhy::TX:
-    NS_ASSERT (false);
-    break;
-  }
-  m_previousStateChangeTime = now;
-  m_syncing = true;
-  m_startSync = now;
-  m_endSync = now + rxDuration;
-  NS_ASSERT (IsStateSync ());
-}
-void
-WifiPhy::SwitchFromSync (void)
-{
-  NS_ASSERT (IsStateSync ());
-  NS_ASSERT (m_syncing);
-
-  Time now = Simulator::Now ();
-  m_stateLogger (m_startSync, now - m_startSync, WifiPhy::SYNC);
-  m_previousStateChangeTime = now;
-  m_syncing = false;
-
-  NS_ASSERT (IsStateIdle () || IsStateCcaBusy ());
-}
-void
-WifiPhy::SwitchMaybeToCcaBusy (Time duration)
-{
-  Time now = Simulator::Now ();
-  switch (GetState ()) {
-  case WifiPhy::IDLE:
-    LogPreviousIdleAndCcaBusyStates ();
-  break;
-  case WifiPhy::CCA_BUSY:
-    break;
-  case WifiPhy::SYNC:
-    break;
-  case WifiPhy::TX:
-    break;
-  }
-  m_startCcaBusy = now;
-  m_endCcaBusy = Max (m_endCcaBusy, now + duration);
-}
-
-void 
-WifiPhy::AppendEvent (Ptr<RxEvent> event)
-{
-  /* attempt to remove the events which are 
-   * not useful anymore. 
-   * i.e.: all events which end _before_
-   *       now - m_maxPacketDuration
-   */
-  
-  if (Simulator::Now () > GetMaxPacketDuration ())
-    {
-      Time end = Simulator::Now () - GetMaxPacketDuration ();
-      Events::iterator i = m_events.begin ();
-      while (i != m_events.end () &&
-             (*i)->GetEndTime () <= end) 
-        {
-          i++;
-        }
-      m_events.erase (m_events.begin (), i);
-    } 
-  m_events.push_back (event);
-}
-
-
-
-/**
- * Stuff specific to the BER model here.
- */
-double 
-WifiPhy::Log2 (double val) const
-{
-  return log(val) / log(2.0);
-}
-double 
-WifiPhy::GetBpskBer (double snr, uint32_t signalSpread, uint32_t phyRate) const
-{
-  double EbNo = snr * signalSpread / phyRate;
-  double z = sqrt(EbNo);
-  double ber = 0.5 * erfc(z);
-  NS_LOG_INFO ("bpsk snr="<<snr<<" ber="<<ber);
-  return ber;
-}
-double 
-WifiPhy::GetQamBer (double snr, unsigned int m, uint32_t signalSpread, uint32_t phyRate) const
-{
-  double EbNo = snr * signalSpread / phyRate;
-  double z = sqrt ((1.5 * Log2 (m) * EbNo) / (m - 1.0));
-  double z1 = ((1.0 - 1.0 / sqrt (m)) * erfc (z)) ;
-  double z2 = 1 - pow ((1-z1), 2.0);
-  double ber = z2 / Log2 (m);
-  NS_LOG_INFO ("Qam m="<<m<<" rate=" << phyRate << " snr="<<snr<<" ber="<<ber);
-  return ber;
-}
-uint32_t
-WifiPhy::Factorial (uint32_t k) const
-{
-  uint32_t fact = 1;
-  while (k > 0) 
-    {
-      fact *= k;
-      k--;
-    }
-  return fact;
-}
-double 
-WifiPhy::Binomial (uint32_t k, double p, uint32_t n) const
-{
-  double retval = Factorial (n) / (Factorial (k) * Factorial (n-k)) * pow (p, k) * pow (1-p, n-k);
-  return retval;
-}
-double 
-WifiPhy::CalculatePdOdd (double ber, unsigned int d) const
-{
-  NS_ASSERT ((d % 2) == 1);
-  unsigned int dstart = (d + 1) / 2;
-  unsigned int dend = d;
-  double pd = 0;
-
-  for (unsigned int i = dstart; i < dend; i++) 
-    {
-      pd += Binomial (i, ber, d);
-    }
-  return pd;
-}
-double 
-WifiPhy::CalculatePdEven (double ber, unsigned int d) const
-{
-  NS_ASSERT ((d % 2) == 0);
-  unsigned int dstart = d / 2 + 1;
-  unsigned int dend = d;
-  double pd = 0;
-
-  for (unsigned int i = dstart; i < dend; i++)
-    {
-      pd +=  Binomial (i, ber, d);
-    }
-  pd += 0.5 * Binomial (d / 2, ber, d);
-
-  return pd;
-}
-
-double 
-WifiPhy::CalculatePd (double ber, unsigned int d) const
-{
-  double pd;
-  if ((d % 2) == 0) 
-    {
-      pd = CalculatePdEven (ber, d);
-    } 
-  else 
-    {
-      pd = CalculatePdOdd (ber, d);
-    }
-  return pd;
-}
-
-double
-WifiPhy::GetFecBpskBer (double snr, double nbits, 
-                         uint32_t signalSpread, uint32_t phyRate,
-                         uint32_t dFree, uint32_t adFree) const
-{
-  double ber = GetBpskBer (snr, signalSpread, phyRate);
-  if (ber == 0.0) 
-    {
-      return 1.0;
-    }
-  double pd = CalculatePd (ber, dFree);
-  double pmu = adFree * pd;
-  pmu = std::min (pmu, 1.0);
-  double pms = pow (1 - pmu, nbits);
-  return pms;
-}
-
-double
-WifiPhy::GetFecQamBer (double snr, uint32_t nbits, 
-                       uint32_t signalSpread,
-                       uint32_t phyRate,
-                       uint32_t m, uint32_t dFree,
-                       uint32_t adFree, uint32_t adFreePlusOne) const
-{
-  double ber = GetQamBer (snr, m, signalSpread, phyRate);
-  if (ber == 0.0) 
-    {
-      return 1.0;
-    }
-  /* first term */
-  double pd = CalculatePd (ber, dFree);
-  double pmu = adFree * pd;
-  /* second term */
-  pd = CalculatePd (ber, dFree + 1);
-  pmu += adFreePlusOne * pd;
-  pmu = std::min (pmu, 1.0);
-  double pms = pow (1 - pmu, nbits);
-  return pms;
-}
-
-double 
-WifiPhy::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const
-{
-  if (mode.GetUid () == g_6mba.GetUid ())
-    {
-      return GetFecBpskBer (snr, 
-                            nbits,
-                            mode.GetBandwidth (), // signal spread
-                            mode.GetPhyRate (), // phy rate
-                            10, // dFree
-                            11 // adFree
-                            );      
-    }
-  else if (mode.GetUid () == g_9mba.GetUid ())
-    {
-      return GetFecBpskBer (snr, 
-                            nbits,
-                            mode.GetBandwidth (), // signal spread
-                            mode.GetPhyRate (), // phy rate
-                            5, // dFree
-                            8 // adFree
-                            );
-    }
-  else if (mode.GetUid () == g_12mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           4,  // m 
-                           10, // dFree
-                           11, // adFree
-                           0   // adFreePlusOne
-                           );
-    }
-  else if (mode.GetUid () == g_18mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           4, // m
-                           5, // dFree
-                           8, // adFree
-                           31 // adFreePlusOne
-                           );
-    }
-  else if (mode.GetUid () == g_24mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           16, // m
-                           10, // dFree
-                           11, // adFree
-                           0   // adFreePlusOne
-                           );
-    }
-  else if (mode.GetUid () == g_36mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           16, // m
-                           5,  // dFree
-                           8,  // adFree
-                           31  // adFreePlusOne
-                           );
-    }
-  else if (mode.GetUid () == g_48mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           64, // m
-                           6,  // dFree
-                           1,  // adFree
-                           16  // adFreePlusOne
-                           );
-    }
-  else if (mode.GetUid () == g_54mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           64, // m
-                           5,  // dFree
-                           8,  // adFree
-                           31  // adFreePlusOne
-                           );
-    }
-  return 0;
-}
-
-double
-WifiPhy::CalculateSnr (double signal, double noiseInterference, WifiMode mode) const
-{
-  // thermal noise at 290K in J/s = W
-  static const double BOLTZMANN = 1.3803e-23;
-  double Nt = BOLTZMANN * 290.0 * mode.GetBandwidth ();
-  // receiver noise Floor (W)
-  double noiseFloor = m_rxNoiseRatio * Nt;
-  double noise = noiseFloor + noiseInterference;
-  double snr = signal / noise;
-  return snr;
-}
-
-double
-WifiPhy::CalculateNoiseInterferenceW (Ptr<RxEvent> event, NiChanges *ni) const
-{
-  Events::const_iterator i = m_events.begin ();
-  double noiseInterference = 0.0;
-  while (i != m_events.end ()) 
-    {
-      if (event == (*i)) 
-        {
-          i++;
-          continue;
-        }
-      if (event->Overlaps ((*i)->GetStartTime ())) 
-        {
-          ni->push_back (NiChange ((*i)->GetStartTime (), (*i)->GetRxPowerW ()));
-        }
-      if (event->Overlaps ((*i)->GetEndTime ())) 
-        {
-          ni->push_back (NiChange ((*i)->GetEndTime (), -(*i)->GetRxPowerW ()));
-        }
-      if ((*i)->Overlaps (event->GetStartTime ())) 
-        {
-          noiseInterference += (*i)->GetRxPowerW ();
-        }
-      i++;
-    }
-  ni->push_back (NiChange (event->GetStartTime (), noiseInterference));
-  ni->push_back (NiChange (event->GetEndTime (), 0));
-
-  /* quicksort vector of NI changes by time. */
-  std::sort (ni->begin (), ni->end (), std::less<NiChange> ());
-
-  return noiseInterference;
-}
-
-double
-WifiPhy::CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode) const
-{
-  if (duration == NanoSeconds (0)) {
-    return 1.0;
-  }
-  uint32_t rate = mode.GetPhyRate ();
-  uint64_t nbits = (uint64_t)(rate * duration.GetSeconds ());
-  double csr = GetChunkSuccessRate (mode, snir, (uint32_t)nbits);
-  return csr;
-}
-
-double 
-WifiPhy::CalculatePer (Ptr<const RxEvent> event, NiChanges *ni) const
-{  
-  double psr = 1.0; /* Packet Success Rate */
-  NiChanges::iterator j = ni->begin ();
-  Time previous = (*j).GetTime ();
-  uint64_t plcpPreambleDelayUs;
-  WifiMode payloadMode = event->GetPayloadMode ();
-  WifiMode headerMode;
-  switch (event->GetPreambleType ()) {
-  case WIFI_PREAMBLE_LONG:
-    plcpPreambleDelayUs = m_plcpLongPreambleDelayUs;
-    headerMode = m_longPlcpHeaderMode;
-    break;
-  case WIFI_PREAMBLE_SHORT:
-    plcpPreambleDelayUs = m_plcpShortPreambleDelayUs;
-    headerMode = m_shortPlcpHeaderMode;
-    break;
-  default:
-    NS_ASSERT (false);
-    // only to quiet compiler. Really stupid.
-    plcpPreambleDelayUs = 0;
-    headerMode = m_shortPlcpHeaderMode;
-    break;
-  }
-  Time plcpHeaderStart = (*j).GetTime () + MicroSeconds (plcpPreambleDelayUs);
-  Time plcpPayloadStart = plcpHeaderStart + 
-    Seconds ((m_plcpHeaderLength + 0.0) / headerMode.GetDataRate ());
-  double noiseInterferenceW = (*j).GetDelta ();
-  double powerW = event->GetRxPowerW ();
-
-  j++;
-  while (ni->end () != j) 
-    {
-      Time current = (*j).GetTime ();
-      NS_ASSERT (current >= previous);
-    
-      if (previous >= plcpPayloadStart) 
-        {
-          psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
-                                                          noiseInterferenceW, 
-                                                          payloadMode), 
-                                            current - previous,
-                                            payloadMode);
-        } 
-      else if (previous >= plcpHeaderStart) 
-        {
-          if (current >= plcpPayloadStart) 
-            {
-              psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
-                                                              noiseInterferenceW, 
-                                                              headerMode), 
-                                                plcpPayloadStart - previous,
-                                                headerMode);
-              psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
-                                                              noiseInterferenceW, 
-                                                              payloadMode),
-                                                current - plcpPayloadStart,
-                                                payloadMode);
-            } 
-          else 
-            {
-              NS_ASSERT (current >= plcpHeaderStart);
-              psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
-                                                              noiseInterferenceW, 
-                                                              headerMode), 
-                                                current - previous,
-                                                headerMode);
-            }
-        } 
-      else 
-        {
-          if (current >= plcpPayloadStart) 
-            {
-              psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
-                                                              noiseInterferenceW, 
-                                                              headerMode), 
-                                                plcpPayloadStart - plcpHeaderStart,
-                                                headerMode);
-              psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
-                                                              noiseInterferenceW, 
-                                                              payloadMode), 
-                                                current - plcpPayloadStart,
-                                                payloadMode);
-            } 
-          else if (current >= plcpHeaderStart) 
-            {
-              psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
-                                                              noiseInterferenceW, 
-                                                              headerMode), 
-                                                current - plcpHeaderStart,
-                                                headerMode);
-            }
-        }
-
-      noiseInterferenceW += (*j).GetDelta ();
-      previous = (*j).GetTime ();
-      j++;
-    }
-
-  double per = 1 - psr;
-  return per;
-}
-
-
-void
-WifiPhy::EndSync (Ptr<Packet> packet, Ptr<RxEvent> event)
-{
-  NS_LOG_FUNCTION (this << packet << event);
-  NS_ASSERT (IsStateSync ());
-  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
-
-  NiChanges ni;
-  double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
-  double snr = CalculateSnr (event->GetRxPowerW (),
-                             noiseInterferenceW,
-                             event->GetPayloadMode ());
-  
-  /* calculate the SNIR at the start of the packet and accumulate
-   * all SNIR changes in the snir vector.
-   */
-  double per = CalculatePer (event, &ni);
-  NS_LOG_DEBUG ("mode="<<(event->GetPayloadMode ().GetDataRate ())<<
-                ", ber="<<(1-GetChunkSuccessRate (event->GetPayloadMode (), snr, 1))<<
-                ", snr="<<snr<<", per="<<per<<", size="<<packet->GetSize ());
-  
-  if (m_random.GetValue () > per) 
-    {
-      NotifySyncEndOk ();
-      SwitchFromSync ();
-      m_rxOkTrace (packet, snr, event->GetPayloadMode (), event->GetPreambleType ());
-      m_syncOkCallback (packet, snr, event->GetPayloadMode (), event->GetPreambleType ());
-    } 
-  else 
-    {
-      /* failure. */
-      NotifySyncEndError ();
-      SwitchFromSync ();
-      m_rxErrorTrace (packet, snr);
-      m_syncErrorCallback (packet, snr);
-    }
-}
-
-
-
-
 } // namespace ns3
--- a/src/devices/wifi/wifi-phy.h	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/wifi-phy.h	Mon Nov 24 06:36:05 2008 +0100
@@ -21,17 +21,12 @@
 #ifndef WIFI_PHY_H
 #define WIFI_PHY_H
 
-#include <vector>
-#include <list>
 #include <stdint.h>
 #include "ns3/callback.h"
-#include "ns3/event-id.h"
 #include "ns3/packet.h"
 #include "ns3/object.h"
-#include "ns3/traced-callback.h"
 #include "ns3/nstime.h"
 #include "ns3/ptr.h"
-#include "ns3/random-variable.h"
 #include "wifi-mode.h"
 #include "wifi-preamble.h"
 #include "wifi-phy-standard.h"
@@ -39,11 +34,8 @@
 
 namespace ns3 {
 
-class RandomUniform;
-class RxEvent;
-class TraceContainer;
-class WifiNetDevice;
 class WifiChannel;
+class NetDevice;
 
 /**
  * \brief receive notifications about phy events.
@@ -55,22 +47,24 @@
   /**
    * \param duration the expected duration of the packet reception.
    *
-   * we have received the first bit of a packet. We decided
+   * We have received the first bit of a packet. We decided
    * that we could synchronize on this packet. It does not mean
    * we will be able to successfully receive completely the
-   * whole packet. It means we will report a BUSY status.
-   * NotifyRxEndOk or NotifyRxEndError will be invoked later 
-   * to report whether or not the packet was successfully received.
+   * whole packet. It means that we will report a BUSY status until
+   * one of the following happens:
+   *   - NotifyRxEndOk
+   *   - NotifyExEndError
+   *   - NotifyTxStart
    */
   virtual void NotifyRxStart (Time duration) = 0;
   /**
-   * we have received the last bit of a packet for which
+   * We have received the last bit of a packet for which
    * NotifyRxStart was invoked first and, the packet has
    * been successfully received.
    */
   virtual void NotifyRxEndOk (void) = 0;  
   /**
-   * we have received the last bit of a packet for which
+   * We have received the last bit of a packet for which
    * NotifyRxStart was invoked first and, the packet has
    * _not_ been successfully received.
    */
@@ -79,30 +73,34 @@
    * \param duration the expected transmission duration.
    *
    * We are about to send the first bit of the packet.
+   * We do not send any event to notify the end of 
+   * transmission. Listeners should assume that the
+   * channel implicitely reverts to the idle state
+   * unless they have received a cca busy report.
    */
   virtual void NotifyTxStart (Time duration) = 0;
   /**
    * \param duration the expected busy duration.
    *
-   * We are going to be cca-busy for a while.
+   * This method does not really report a real state
+   * change as opposed to the other methods in this class.
+   * It merely reports that, unless the medium is reported
+   * busy through NotifyTxStart or NotifyRxStart/End, 
+   * it will be busy as defined by the currently selected 
+   * CCA mode.
+   *
+   * Typical client code which wants to have a clear picture
+   * of the CCA state will need to keep track of the time at
+   * which the last NotifyCcaBusyStart method is called and
+   * what duration it reported.
    */
-  virtual void NotifyCcaBusyStart (Time duration) = 0;
+  virtual void NotifyMaybeCcaBusyStart (Time duration) = 0;
 };
 
 
 /**
  * \brief 802.11 PHY layer model
  *
- * This PHY implements a model of 802.11a. The model
- * implemented here is based on the model described
- * in "Yet Another Network Simulator", 
- * (http://cutebugs.net/files/wns2-yans.pdf).
- *
- *
- * This PHY model depends on a channel loss and delay
- * model as provided by the ns3::PropagationLossModel
- * and ns3::PropagationDelayModel classes, both of which are
- * members of the ns3::WifiChannel class.
  */
 class WifiPhy : public Object
 {
@@ -140,48 +138,30 @@
    * arg1: packet received unsuccessfully
    * arg2: snr of packet
    */
-  typedef Callback<void,Ptr<Packet>, double> SyncErrorCallback;
+  typedef Callback<void,Ptr<const Packet>, double> SyncErrorCallback;
 
   static TypeId GetTypeId (void);
 
   WifiPhy ();
   virtual ~WifiPhy ();
 
-  void SetStandard (enum WifiPhyStandard standard);
-  void SetRxNoise (double ratio);
-  void SetTxPowerStart (double start);
-  void SetTxPowerEnd (double end);
-  void SetNTxPower (uint32_t n);
-  void SetTxGain (double gain);
-  void SetRxGain (double gain);
-  void SetEdThreshold (double threshold);
-  double GetRxNoise (void) const;
-  double GetTxPowerStart (void) const;
-  double GetTxPowerEnd (void) const;
+  virtual double GetTxPowerStart (void) const = 0;
+  virtual double GetTxPowerEnd (void) const = 0;
   /**
    * \returns the number of tx power levels available for this PHY.
    */
-  uint32_t GetNTxPower (void) const;
-  double GetTxGain (void) const;
-  double GetRxGain (void) const;
-  double GetEdThreshold (void) const;
-
-
-  /**
-   * \param channel the channel to connect to.
-   */
-  void SetChannel (Ptr<WifiChannel> channel);
+  virtual uint32_t GetNTxPower (void) const = 0;
 
   /**
    * \param callback the callback to invoke
    *        upon successful packet reception.
    */
-  void SetReceiveOkCallback (SyncOkCallback callback);
+  virtual void SetReceiveOkCallback (SyncOkCallback callback) = 0;
   /**
    * \param callback the callback to invoke
    *        upon erronous packet reception.
    */
-  void SetReceiveErrorCallback (SyncErrorCallback callback);
+  virtual void SetReceiveErrorCallback (SyncErrorCallback callback) = 0;
 
   /**
    * \param packet the packet to send
@@ -190,7 +170,7 @@
    * \param txPowerLevel a power level to use to send this packet. The real
    *        transmission power is calculated as txPowerMin + txPowerLevel * (txPowerMax - txPowerMin) / nTxLevels
    */
-  void SendPacket (Ptr<const Packet> packet, WifiMode mode, enum WifiPreamble preamble, uint8_t txPowerLevel);
+  virtual void SendPacket (Ptr<const Packet> packet, WifiMode mode, enum WifiPreamble preamble, uint8_t txPowerLevel) = 0;
 
   /**
    * \param listener the new listener
@@ -198,41 +178,41 @@
    * Add the input listener to the list of objects to be notified of
    * PHY-level events.
    */
-  void RegisterListener (WifiPhyListener *listener);
+  virtual void RegisterListener (WifiPhyListener *listener) = 0;
 
   /**
-   * \returns true of the current state of the PHY layer is WifiPhy:LCCA_BUSY, false otherwise.
+   * \returns true of the current state of the PHY layer is WifiPhy::CCA_BUSY, false otherwise.
    */
-  bool IsStateCcaBusy (void);
+  virtual bool IsStateCcaBusy (void) = 0;
   /**
    * \returns true of the current state of the PHY layer is WifiPhy::IDLE, false otherwise.
    */
-  bool IsStateIdle (void);
+  virtual bool IsStateIdle (void) = 0;
   /**
    * \returns true of the current state of the PHY layer is not WifiPhy::IDLE, false otherwise.
    */
-  bool IsStateBusy (void);
+  virtual bool IsStateBusy (void) = 0;
   /**
    * \returns true of the current state of the PHY layer is WifiPhy::SYNC, false otherwise.
    */
-  bool IsStateSync (void);
+  virtual bool IsStateSync (void) = 0;
   /**
    * \returns true of the current state of the PHY layer is WifiPhy::TX, false otherwise.
    */
-  bool IsStateTx (void);
+  virtual bool IsStateTx (void) = 0;
   /**
    * \returns the amount of time since the current state has started.
    */
-  Time GetStateDuration (void);
+  virtual Time GetStateDuration (void) = 0;
   /**
    * \returns the predicted delay until this PHY can become WifiPhy::IDLE.
    *
    * The PHY will never become WifiPhy::IDLE _before_ the delay returned by
    * this method but it could become really idle later.
    */
-  Time GetDelayUntilIdle (void);
+  virtual Time GetDelayUntilIdle (void) = 0;
 
-  Time GetLastRxStartTime (void) const;
+  virtual Time GetLastRxStartTime (void) const = 0;
 
   /**
    * \param size the number of bytes in the packet to send
@@ -241,142 +221,35 @@
    * \returns the total amount of time this PHY will stay busy for
    *          the transmission of these bytes.
    */
-  Time CalculateTxDuration (uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble) const;
-
+  virtual Time CalculateTxDuration (uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble) const = 0;
+  
   /**
    * \returns the number of transmission modes supported by this PHY.
    */
-  uint32_t GetNModes (void) const;
+  virtual uint32_t GetNModes (void) const = 0;
   /**
    * \param mode index in array of supported modes
    * \returns the mode whose index is specified.
    */
-  WifiMode GetMode (uint32_t mode) const;
-  /* return snr: W/W */
+  virtual WifiMode GetMode (uint32_t mode) const = 0;
   /**
    * \param txMode the transmission mode
    * \param ber the probability of bit error rate
    * \returns the minimum snr which is required to achieve
-   *          the requested ber for the specified transmission mode.
+   *          the requested ber for the specified transmission mode. (W/W)
    */
-  double CalculateSnr (WifiMode txMode, double ber) const;
-
-  /* rxPower unit is Watt */
-  void StartReceivePacket (Ptr<Packet> packet,
-                           double rxPowerDbm,
-                           WifiMode mode,
-                           WifiPreamble preamble);
-
-  Ptr<WifiChannel> GetChannel (void) const;
+  virtual double CalculateSnr (WifiMode txMode, double ber) const = 0;
 
-private:
-  class NiChange {
-  public:
-    NiChange (Time time, double delta);
-    Time GetTime (void) const;
-    double GetDelta (void) const;
-    bool operator < (NiChange const &o) const;
-  private:
-    Time m_time;
-    double m_delta;
-  };
-  typedef std::vector<WifiMode> Modes;
-  typedef std::list<WifiPhyListener *> Listeners;
-  typedef std::list<Ptr<RxEvent> > Events;
-  typedef std::vector <NiChange> NiChanges;
+  virtual Ptr<WifiChannel> GetChannel (void) const = 0;
 
-private:
-  virtual void DoDispose (void);
-  void Configure80211aParameters (void);
-  void PrintModes (void) const;
-  void Configure80211a (void);
-  void ConfigureHolland (void);
-  char const *StateToString (enum State state);
-  enum WifiPhy::State GetState (void);
-  double GetEdThresholdW (void) const;
-  double DbmToW (double dbm) const;
-  double DbToRatio (double db) const;
-  double WToDbm (double w) const;
-  double RatioToDb (double ratio) const;
-  Time GetMaxPacketDuration (void) const;
-  void CancelRx (void);
-  double GetPowerDbm (uint8_t power) const;
-  void NotifyTxStart (Time duration);
-  void NotifyWakeup (void);
-  void NotifySyncStart (Time duration);
-  void NotifySyncEndOk (void);
-  void NotifySyncEndError (void);
-  void NotifyCcaBusyStart (Time duration);
-  void LogPreviousIdleAndCcaBusyStates (void);
-  void SwitchToTx (Time txDuration);
-  void SwitchToSync (Time syncDuration);
-  void SwitchFromSync (void);
-  void SwitchMaybeToCcaBusy (Time duration);
-  void AppendEvent (Ptr<RxEvent> event);
-  double CalculateNoiseInterferenceW (Ptr<RxEvent> event, NiChanges *ni) const;
-  double CalculateSnr (double signal, double noiseInterference, WifiMode mode) const;
-  double CalculateChunkSuccessRate (double snir, Time delay, WifiMode mode) const;
-  double CalculatePer (Ptr<const RxEvent> event, NiChanges *ni) const;
-  void EndSync (Ptr<Packet> packet, Ptr<RxEvent> event);
-  double Log2 (double val) const;
-  double GetBpskBer (double snr, uint32_t signalSpread, uint32_t phyRate) const;
-  double GetQamBer (double snr, unsigned int m, uint32_t signalSpread, uint32_t phyRate) const;
-  uint32_t Factorial (uint32_t k) const;
-  double Binomial (uint32_t k, double p, uint32_t n) const;
-  double CalculatePdOdd (double ber, unsigned int d) const;
-  double CalculatePdEven (double ber, unsigned int d) const;
-  double CalculatePd (double ber, unsigned int d) const;
-  double GetFecBpskBer (double snr, double nbits, 
-                        uint32_t signalSpread, uint32_t phyRate,
-                        uint32_t dFree, uint32_t adFree) const;
-  double GetFecQamBer (double snr, uint32_t nbits, 
-                       uint32_t signalSpread,
-                       uint32_t phyRate,
-                       uint32_t m, uint32_t dfree,
-                       uint32_t adFree, uint32_t adFreePlusOne) const;
-  double GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const;
-  WifiPhy (const WifiPhy & ctor_arg);
-
-private:
-  uint64_t m_txPrepareDelayUs;
-  uint64_t m_plcpLongPreambleDelayUs;
-  uint64_t m_plcpShortPreambleDelayUs;
-  WifiMode m_longPlcpHeaderMode;
-  WifiMode m_shortPlcpHeaderMode;
-  uint32_t m_plcpHeaderLength;
-  Time     m_maxPacketDuration;
-
-  double   m_edThresholdW; /* unit: W */
-  double   m_txGainDb;
-  double   m_rxGainDb;
-  double   m_rxNoiseRatio;
-  double   m_txPowerBaseDbm;
-  double   m_txPowerEndDbm;
-  uint32_t m_nTxPower;
-
-  
-  bool m_syncing;
-  Time m_endTx;
-  Time m_endSync;
-  Time m_endCcaBusy;
-  Time m_startTx;
-  Time m_startSync;
-  Time m_startCcaBusy;
-  Time m_previousStateChangeTime;
-
-  Ptr<WifiChannel> m_channel;
-  SyncOkCallback m_syncOkCallback;
-  SyncErrorCallback m_syncErrorCallback;
-  TracedCallback<Ptr<const Packet>, double, WifiMode, enum WifiPreamble> m_rxOkTrace;
-  TracedCallback<Ptr<const Packet>, double> m_rxErrorTrace;
-  TracedCallback<Ptr<const Packet>,WifiMode,WifiPreamble,uint8_t> m_txTrace;
-  Modes m_modes;
-  Listeners m_listeners;
-  EventId m_endSyncEvent;
-  Events m_events;
-  UniformVariable m_random;
-  TracedCallback<Time,Time,enum WifiPhy::State> m_stateLogger;
-  WifiPhyStandard m_standard;
+  static WifiMode g_6mba;
+  static WifiMode g_9mba;
+  static WifiMode g_12mba;
+  static WifiMode g_18mba;
+  static WifiMode g_24mba;
+  static WifiMode g_36mba;
+  static WifiMode g_48mba;
+  static WifiMode g_54mba;
 };
 
 } // namespace ns3
--- a/src/devices/wifi/wifi-test.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/wifi-test.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -1,12 +1,13 @@
 #ifdef RUN_SELF_TESTS
 
 #include "wifi-net-device.h"
-#include "wifi-channel.h"
+#include "yans-wifi-channel.h"
 #include "adhoc-wifi-mac.h"
-#include "wifi-phy.h"
+#include "yans-wifi-phy.h"
 #include "arf-wifi-manager.h"
 #include "propagation-delay-model.h"
 #include "propagation-loss-model.h"
+#include "error-rate-model.h"
 #include "ns3/static-mobility-model.h"
 #include "ns3/node.h"
 #include "ns3/simulator.h"
@@ -23,7 +24,7 @@
   virtual bool RunTests (void);
 private:
   void RunOne (void);
-  void CreateOne (Vector pos, Ptr<WifiChannel> channel);
+  void CreateOne (Vector pos, Ptr<YansWifiChannel> channel);
   void SendOnePacket (Ptr<WifiNetDevice> dev);
 
   ObjectFactory m_manager;
@@ -43,14 +44,19 @@
 }
 
 void 
-WifiTest::CreateOne (Vector pos, Ptr<WifiChannel> channel)
+WifiTest::CreateOne (Vector pos, Ptr<YansWifiChannel> channel)
 {
   Ptr<Node> node = CreateObject<Node> ();
   Ptr<WifiNetDevice> dev = CreateObject<WifiNetDevice> ();
 
   Ptr<WifiMac> mac = m_mac.Create<WifiMac> ();
   Ptr<StaticMobilityModel> mobility = CreateObject<StaticMobilityModel> ();
-  Ptr<WifiPhy> phy = CreateObject<WifiPhy> ();
+  Ptr<YansWifiPhy> phy = CreateObject<YansWifiPhy> ();
+  Ptr<ErrorRateModel> error = CreateObject<ErrorRateModel> ();
+  phy->SetErrorRateModel (error);
+  phy->SetChannel (channel);
+  phy->SetDevice (dev);
+  phy->SetMobility (node);
   Ptr<WifiRemoteStationManager> manager = m_manager.Create<WifiRemoteStationManager> ();
 
   mobility->SetPosition (pos);
@@ -59,7 +65,6 @@
   dev->SetMac (mac);
   dev->SetPhy (phy);
   dev->SetRemoteStationManager (manager);
-  dev->SetChannel (channel);
   node->AddDevice (dev);
 
   Simulator::Schedule (Seconds (1.0), &WifiTest::SendOnePacket, this, dev);
@@ -68,7 +73,7 @@
 void
 WifiTest::RunOne (void)
 {
-  Ptr<WifiChannel> channel = CreateObject<WifiChannel> ();
+  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
   Ptr<PropagationDelayModel> propDelay = m_propDelay.Create<PropagationDelayModel> ();
   Ptr<PropagationLossModel> propLoss = CreateObject<RandomPropagationLossModel> ();
   channel->SetPropagationDelayModel (propDelay);
--- a/src/devices/wifi/wscript	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/devices/wifi/wscript	Mon Nov 24 06:36:05 2008 +0100
@@ -5,12 +5,16 @@
     obj.source = [
         'propagation-delay-model.cc',
         'propagation-loss-model.cc',
-        'composite-propagation-loss-model.cc',
         'jakes-propagation-loss-model.cc',
         'wifi-channel.cc',
         'wifi-mode.cc',
         'ssid.cc',
         'wifi-phy.cc',
+        'wifi-phy-state-helper.cc',
+        'error-rate-model.cc',
+        'interference-helper.cc',
+        'yans-wifi-phy.cc',
+        'yans-wifi-channel.cc',
         'wifi-mac-header.cc',
         'wifi-mac-trailer.cc',
         'mac-low.cc',
@@ -45,7 +49,6 @@
     headers.source = [
         'propagation-delay-model.h',
         'propagation-loss-model.h',
-        'composite-propagation-loss-model.h',
         'jakes-propagation-loss-model.h',
         'wifi-net-device.h',
         'wifi-channel.h',
@@ -53,7 +56,10 @@
         'ssid.h',
         'wifi-preamble.h',
 	'wifi-phy-standard.h',
+        'yans-wifi-phy.h',
+        'yans-wifi-channel.h',
         'wifi-phy.h',
+        'interference-helper.h',
         'wifi-remote-station-manager.h',
         'arf-wifi-manager.h',
         'aarf-wifi-manager.h',
@@ -68,4 +74,9 @@
         'nqap-wifi-mac.h',
         'wifi-phy.h',
         'supported-rates.h',
+        'error-rate-model.h',
         ]
+
+    obj = bld.create_ns3_program('wifi-phy-test',
+        ['core', 'simulator', 'mobility', 'node', 'wifi'])
+    obj.source = 'wifi-phy-test.cc'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/yans-wifi-channel.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -0,0 +1,121 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006,2007 INRIA
+ *
+ * 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>
+ */
+#include "ns3/packet.h"
+#include "ns3/simulator.h"
+#include "ns3/mobility-model.h"
+#include "ns3/net-device.h"
+#include "ns3/node.h"
+#include "ns3/log.h"
+#include "ns3/pointer.h"
+#include "ns3/object-factory.h"
+#include "yans-wifi-channel.h"
+#include "yans-wifi-phy.h"
+#include "propagation-loss-model.h"
+#include "propagation-delay-model.h"
+
+NS_LOG_COMPONENT_DEFINE ("YansWifiChannel");
+
+namespace ns3 {
+
+TypeId 
+YansWifiChannel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::YansWifiChannel")
+    .SetParent<WifiChannel> ()
+    .AddConstructor<YansWifiChannel> ()
+    .AddAttribute ("PropagationLossModel", "A pointer to the propagation loss model attached to this channel.",
+                   PointerValue (),
+                   MakePointerAccessor (&YansWifiChannel::m_loss),
+                   MakePointerChecker<PropagationLossModel> ())
+    .AddAttribute ("PropagationDelayModel", "A pointer to the propagation delay model attached to this channel.",
+                   PointerValue (),
+                   MakePointerAccessor (&YansWifiChannel::m_delay),
+                   MakePointerChecker<PropagationDelayModel> ())
+    ;
+  return tid;
+}
+
+YansWifiChannel::YansWifiChannel ()
+{}
+YansWifiChannel::~YansWifiChannel ()
+{
+  m_phyList.clear ();
+}
+
+void 
+YansWifiChannel::SetPropagationLossModel (Ptr<PropagationLossModel> loss)
+{
+  m_loss = loss;
+}
+void 
+YansWifiChannel::SetPropagationDelayModel (Ptr<PropagationDelayModel> delay)
+{
+  m_delay = delay;
+}
+
+void 
+YansWifiChannel::Send (Ptr<YansWifiPhy> sender, Ptr<const Packet> packet, double txPowerDbm,
+                       WifiMode wifiMode, WifiPreamble preamble) const
+{
+  Ptr<MobilityModel> senderMobility = sender->GetMobility ()->GetObject<MobilityModel> ();
+  NS_ASSERT (senderMobility != 0);
+  uint32_t j = 0;
+  for (PhyList::const_iterator i = m_phyList.begin (); i != m_phyList.end (); i++)
+    {
+      if (sender != (*i))
+        {
+          Ptr<MobilityModel> receiverMobility = (*i)->GetMobility ()->GetObject<MobilityModel> ();
+          Time delay = m_delay->GetDelay (senderMobility, receiverMobility);
+          double rxPowerDbm = txPowerDbm + m_loss->GetLoss (senderMobility, receiverMobility);
+          NS_LOG_DEBUG ("propagation: txPower="<<txPowerDbm<<"dbm, rxPower="<<rxPowerDbm<<"dbm, "<<
+                        "distance="<<senderMobility->GetDistanceFrom (receiverMobility)<<"m, delay="<<delay);
+          Ptr<Packet> copy = packet->Copy ();
+          Simulator::Schedule (delay, &YansWifiChannel::Receive, this, 
+                               j, copy, rxPowerDbm, wifiMode, preamble);
+        }
+      j++;
+    }
+}
+
+void
+YansWifiChannel::Receive (uint32_t i, Ptr<Packet> packet, double rxPowerDbm,
+                          WifiMode txMode, WifiPreamble preamble) const
+{
+  m_phyList[i]->StartReceivePacket (packet, rxPowerDbm, txMode, preamble);
+}
+
+uint32_t 
+YansWifiChannel::GetNDevices (void) const
+{
+  return m_phyList.size ();
+}
+Ptr<NetDevice> 
+YansWifiChannel::GetDevice (uint32_t i) const
+{
+  return m_phyList[i]->GetDevice ()->GetObject<NetDevice> ();
+}
+
+void 
+YansWifiChannel::Add (Ptr<YansWifiPhy> phy)
+{
+  m_phyList.push_back (phy);
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/yans-wifi-channel.h	Mon Nov 24 06:36:05 2008 +0100
@@ -0,0 +1,98 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006,2007 INRIA
+ *
+ * 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>
+ */
+#ifndef YANS_WIFI_CHANNEL_H
+#define YANS_WIFI_CHANNEL_H
+
+#include <vector>
+#include <stdint.h>
+#include "ns3/packet.h"
+#include "wifi-channel.h"
+#include "wifi-mode.h"
+#include "wifi-preamble.h"
+
+namespace ns3 {
+
+class NetDevice;
+class PropagationLossModel;
+class PropagationDelayModel;
+class YansWifiPhy;
+
+/**
+ * \brief A Yans wifi channel
+ *
+ * This wifi channel implements the propagation model described in
+ * "Yet Another Network Simulator", (http://cutebugs.net/files/wns2-yans.pdf).
+ *
+ * This class is expected to be used in tandem with the ns3::YansWifiPhy 
+ * class and contains a ns3::PropagationLossModel and a ns3::PropagationDelayModel.
+ * By default, no propagation models are set so, it is the caller's responsability
+ * to set them before using the channel.
+ */
+class YansWifiChannel : public WifiChannel
+{
+public:
+  static TypeId GetTypeId (void);
+
+  YansWifiChannel ();
+  virtual ~YansWifiChannel ();
+
+  // inherited from Channel.
+  virtual uint32_t GetNDevices (void) const;
+  virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
+
+  void Add (Ptr<YansWifiPhy> phy);
+
+  /**
+   * \param loss the new propagation loss model.
+   */
+  void SetPropagationLossModel (Ptr<PropagationLossModel> loss);
+  /**
+   * \param delay the new propagation delay model.
+   */
+  void SetPropagationDelayModel (Ptr<PropagationDelayModel> delay);
+
+  /**
+   * \param sender the device from which the packet is originating.
+   * \param packet the packet to send
+   * \param txPowerDbm the tx power associated to the packet
+   * \param wifiMode the tx mode associated to the packet
+   * \param preamble the preamble associated to the packet
+   *
+   * This method should not be invoked by normal users. It is 
+   * currently invoked only from WifiPhy::Send.
+   */
+  void Send (Ptr<YansWifiPhy> sender, Ptr<const Packet> packet, double txPowerDbm,
+             WifiMode wifiMode, WifiPreamble preamble) const;
+
+private:
+  typedef std::vector<Ptr<YansWifiPhy> > PhyList;
+  void Receive (uint32_t i, Ptr<Packet> packet, double rxPowerDbm,
+                WifiMode txMode, WifiPreamble preamble) const;
+
+
+  PhyList m_phyList;
+  Ptr<PropagationLossModel> m_loss;
+  Ptr<PropagationDelayModel> m_delay;
+};
+
+} // namespace ns3
+
+
+#endif /* YANS_WIFI_CHANNEL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/yans-wifi-phy.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -0,0 +1,565 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006 INRIA
+ *
+ * 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>
+ */
+
+#include "yans-wifi-phy.h"
+#include "yans-wifi-channel.h"
+#include "wifi-mode.h"
+#include "wifi-preamble.h"
+#include "wifi-phy-state-helper.h"
+#include "error-rate-model.h"
+#include "ns3/simulator.h"
+#include "ns3/packet.h"
+#include "ns3/random-variable.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/double.h"
+#include "ns3/uinteger.h"
+#include "ns3/enum.h"
+#include "ns3/pointer.h"
+#include "ns3/net-device.h"
+#include <math.h>
+
+NS_LOG_COMPONENT_DEFINE ("YansWifiPhy");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (YansWifiPhy);
+
+TypeId 
+YansWifiPhy::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::YansWifiPhy")
+    .SetParent<WifiPhy> ()
+    .AddConstructor<YansWifiPhy> ()
+    .AddAttribute ("EnergyDetectionThreshold",
+                   "The energy of a received signal should be higher than "
+                   "this threshold (dbm) to allow the PHY layer to detect the signal.",
+                   DoubleValue (-140.0),
+                   MakeDoubleAccessor (&YansWifiPhy::SetEdThreshold,
+                                       &YansWifiPhy::GetEdThreshold),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("CcaMode1Threshold",
+                   "The energy of a received signal should be higher than "
+                   "this threshold (dbm) to allow the PHY layer to declare CCA BUSY state",
+                   DoubleValue (-140.0),
+                   MakeDoubleAccessor (&YansWifiPhy::SetCcaMode1Threshold,
+                                       &YansWifiPhy::GetCcaMode1Threshold),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("TxGain",
+                   "Transmission gain (dB).",
+                   DoubleValue (1.0),
+                   MakeDoubleAccessor (&YansWifiPhy::SetTxGain,
+                                       &YansWifiPhy::GetTxGain),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("RxGain",
+                   "Reception gain (dB).",
+                   DoubleValue (1.0),
+                   MakeDoubleAccessor (&YansWifiPhy::SetRxGain,
+                                       &YansWifiPhy::GetRxGain),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("TxPowerLevels",
+                   "Number of transmission power levels available between "
+                   "TxPowerBase and TxPowerEnd included.",
+                   UintegerValue (1),
+                   MakeUintegerAccessor (&YansWifiPhy::m_nTxPower),
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("TxPowerEnd",
+                   "Maximum available transmission level (dbm).",
+                   DoubleValue (16.0206),
+                   MakeDoubleAccessor (&YansWifiPhy::SetTxPowerEnd, 
+                                       &YansWifiPhy::GetTxPowerEnd),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("TxPowerStart",
+                   "Minimum available transmission level (dbm).",
+                   DoubleValue (16.0206),
+                   MakeDoubleAccessor (&YansWifiPhy::SetTxPowerStart, 
+                                       &YansWifiPhy::GetTxPowerStart),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("RxNoise",
+                   "Ratio of energy lost by receiver (dB).",
+                   DoubleValue (7),
+                   MakeDoubleAccessor (&YansWifiPhy::SetRxNoise,
+                                       &YansWifiPhy::GetRxNoise),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Standard", "The standard chosen configures a set of transmission modes"
+                   " and some PHY-specific constants.",
+                   EnumValue (WIFI_PHY_STANDARD_80211a),
+                   MakeEnumAccessor (&YansWifiPhy::SetStandard),
+                   MakeEnumChecker (WIFI_PHY_STANDARD_80211a, "802.11a",
+                                    WIFI_PHY_STANDARD_holland, "holland"))
+    .AddAttribute ("State", "The state of the PHY layer",
+                   PointerValue (),
+                   MakePointerAccessor (&YansWifiPhy::m_state),
+                   MakePointerChecker<WifiPhyStateHelper> ())
+    ;
+  return tid;
+}
+
+YansWifiPhy::YansWifiPhy ()
+ : m_endSyncEvent (),
+   m_random (0.0, 1.0)
+{
+  NS_LOG_FUNCTION (this);
+  m_state = CreateObject<WifiPhyStateHelper> ();
+}
+
+YansWifiPhy::~YansWifiPhy ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+YansWifiPhy::DoDispose (void)
+{
+  NS_LOG_FUNCTION (this);
+  m_channel = 0;
+  m_modes.clear ();
+  m_device = 0;
+}
+
+void
+YansWifiPhy::SetStandard (enum WifiPhyStandard standard)
+{
+  NS_LOG_FUNCTION (this << standard);
+  m_standard = standard;
+  switch (standard) {
+  case WIFI_PHY_STANDARD_80211a:
+    Configure80211a ();
+    break;
+  case WIFI_PHY_STANDARD_holland:
+    ConfigureHolland ();
+    break;
+  default:
+    NS_ASSERT (false);
+    break;
+  }
+}
+
+
+void 
+YansWifiPhy::SetRxNoise (double db)
+{
+  NS_LOG_FUNCTION (this << db);
+  m_interference.SetNoiseFloorW (DbToRatio (db));
+}
+void 
+YansWifiPhy::SetTxPowerStart (double start)
+{
+  NS_LOG_FUNCTION (this << start);
+  m_txPowerBaseDbm = start;
+}
+void 
+YansWifiPhy::SetTxPowerEnd (double end)
+{
+  NS_LOG_FUNCTION (this << end);
+  m_txPowerEndDbm = end;
+}
+void 
+YansWifiPhy::SetNTxPower (uint32_t n)
+{
+  NS_LOG_FUNCTION (this << n);
+  m_nTxPower = n;
+}
+void 
+YansWifiPhy::SetTxGain (double gain)
+{
+  NS_LOG_FUNCTION (this << gain);
+  m_txGainDb = gain;
+}
+void 
+YansWifiPhy::SetRxGain (double gain)
+{
+  NS_LOG_FUNCTION (this << gain);
+  m_rxGainDb = gain;
+}
+void 
+YansWifiPhy::SetEdThreshold (double threshold)
+{
+  NS_LOG_FUNCTION (this << threshold);
+  m_edThresholdW = DbmToW (threshold);
+}
+void 
+YansWifiPhy::SetCcaMode1Threshold (double threshold)
+{
+  NS_LOG_FUNCTION (this << threshold);
+  m_ccaMode1ThresholdW = DbmToW (threshold);
+}
+void 
+YansWifiPhy::SetErrorRateModel (Ptr<ErrorRateModel> rate)
+{
+  m_interference.SetErrorRateModel (rate);
+}
+void 
+YansWifiPhy::SetDevice (Ptr<Object> device)
+{
+  m_device = device;
+}
+void 
+YansWifiPhy::SetMobility (Ptr<Object> mobility)
+{
+  m_mobility = mobility;
+}
+
+double 
+YansWifiPhy::GetRxNoise (void) const
+{
+  return RatioToDb (m_interference.GetNoiseFloorW ());
+}
+double 
+YansWifiPhy::GetTxPowerStart (void) const
+{
+  return m_txPowerBaseDbm;
+}
+double 
+YansWifiPhy::GetTxPowerEnd (void) const
+{
+  return m_txPowerEndDbm;
+}
+double 
+YansWifiPhy::GetTxGain (void) const
+{
+  return m_txGainDb;
+}
+double 
+YansWifiPhy::GetRxGain (void) const
+{
+  return m_rxGainDb;
+}
+
+double 
+YansWifiPhy::GetEdThreshold (void) const
+{
+  return WToDbm (m_edThresholdW);
+}
+
+double 
+YansWifiPhy::GetCcaMode1Threshold (void) const
+{
+  return WToDbm (m_ccaMode1ThresholdW);
+}
+
+Ptr<ErrorRateModel> 
+YansWifiPhy::GetErrorRateModel (void) const
+{
+  return m_interference.GetErrorRateModel ();
+}
+Ptr<Object> 
+YansWifiPhy::GetDevice (void) const
+{
+  return m_device;
+}
+Ptr<Object> 
+YansWifiPhy::GetMobility (void)
+{
+  return m_mobility;
+}
+
+double 
+YansWifiPhy::CalculateSnr (WifiMode txMode, double ber) const
+{
+  return m_interference.GetErrorRateModel ()->CalculateSnr (txMode, ber);
+}
+
+Ptr<WifiChannel> 
+YansWifiPhy::GetChannel (void) const
+{
+  return m_channel;
+}
+void 
+YansWifiPhy::SetChannel (Ptr<YansWifiChannel> channel)
+{
+  m_channel = channel;
+  m_channel->Add (this);
+}
+
+void 
+YansWifiPhy::SetReceiveOkCallback (SyncOkCallback callback)
+{
+  m_state->SetReceiveOkCallback (callback);
+}
+void 
+YansWifiPhy::SetReceiveErrorCallback (SyncErrorCallback callback)
+{
+  m_state->SetReceiveErrorCallback (callback);
+}
+void 
+YansWifiPhy::StartReceivePacket (Ptr<Packet> packet, 
+                                 double rxPowerDbm,
+                                 WifiMode txMode,
+                                 enum WifiPreamble preamble)
+{
+  NS_LOG_FUNCTION (this << packet << rxPowerDbm << txMode << preamble);
+  rxPowerDbm += m_rxGainDb;
+  double rxPowerW = DbmToW (rxPowerDbm);
+  Time rxDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble);
+  Time endRx = Simulator::Now () + rxDuration;
+
+  Ptr<InterferenceHelper::Event> event;
+  event = m_interference.Add (packet->GetSize (), 
+                              txMode,
+                              preamble,
+                              rxDuration,
+                              rxPowerW);
+
+  switch (m_state->GetState ()) {
+  case YansWifiPhy::SYNC:
+    NS_LOG_DEBUG ("drop packet because already in Sync (power="<<
+                  rxPowerW<<"W)");
+    if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ()) 
+      {
+        // that packet will be noise _after_ the reception of the
+        // currently-received packet.
+        goto maybeCcaBusy;
+      }
+    break;
+  case YansWifiPhy::TX:
+    NS_LOG_DEBUG ("drop packet because already in Tx (power="<<
+                  rxPowerW<<"W)");
+    if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ()) 
+      {
+        // that packet will be noise _after_ the transmission of the
+        // currently-transmitted packet.
+        goto maybeCcaBusy;
+      }
+    break;
+  case YansWifiPhy::CCA_BUSY:
+  case YansWifiPhy::IDLE:
+    if (rxPowerW > m_edThresholdW) 
+      {
+        NS_LOG_DEBUG ("sync (power="<<rxPowerW<<"W)");
+        // sync to signal
+        m_state->SwitchToSync (rxDuration);
+        NS_ASSERT (m_endSyncEvent.IsExpired ());
+        m_endSyncEvent = Simulator::Schedule (rxDuration, &YansWifiPhy::EndSync, this, 
+                                              packet,
+                                              event);
+      }
+    else 
+      {
+        NS_LOG_DEBUG ("drop packet because signal power too Small ("<<
+                      rxPowerW<<"<"<<m_edThresholdW<<")");
+        goto maybeCcaBusy;
+      }
+    break;
+  }
+
+  return;
+
+ maybeCcaBusy:
+  // We are here because we have received the first bit of a packet and we are
+  // not going to be able to synchronize on it
+  // In this model, CCA becomes busy when the aggregation of all signals as
+  // tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
+
+  Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaMode1ThresholdW);
+  if (!delayUntilCcaEnd.IsZero ())
+    {
+      m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
+    }
+}
+void 
+YansWifiPhy::SendPacket (Ptr<const Packet> packet, WifiMode txMode, WifiPreamble preamble, uint8_t txPower)
+{
+  NS_LOG_FUNCTION (this << packet << txMode << preamble << (uint32_t)txPower);
+  /* Transmission can happen if:
+   *  - we are syncing on a packet. It is the responsability of the
+   *    MAC layer to avoid doing this but the PHY does nothing to 
+   *    prevent it.
+   *  - we are idle
+   */
+  NS_ASSERT (!m_state->IsStateTx ());
+
+  Time txDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble);
+  if (m_state->IsStateSync ())
+    {
+      m_endSyncEvent.Cancel ();
+    }
+  m_state->SwitchToTx (txDuration, packet, txMode, preamble, txPower);
+  m_channel->Send (this, packet, GetPowerDbm (txPower) + m_txGainDb, txMode, preamble);
+}
+
+uint32_t 
+YansWifiPhy::GetNModes (void) const
+{
+  return m_modes.size ();
+}
+WifiMode 
+YansWifiPhy::GetMode (uint32_t mode) const
+{
+  return m_modes[mode];
+}
+uint32_t 
+YansWifiPhy::GetNTxPower (void) const
+{
+  return m_nTxPower;
+}
+
+void
+YansWifiPhy::Configure80211a (void)
+{
+  NS_LOG_FUNCTION (this);
+  m_interference.Configure80211aParameters ();
+  m_modes.push_back (g_6mba);
+  m_modes.push_back (g_9mba);
+  m_modes.push_back (g_12mba);
+  m_modes.push_back (g_18mba);
+  m_modes.push_back (g_24mba);
+  m_modes.push_back (g_36mba);
+  m_modes.push_back (g_48mba);
+  m_modes.push_back (g_54mba);
+}
+
+void
+YansWifiPhy::ConfigureHolland (void)
+{
+  NS_LOG_FUNCTION (this);
+  m_interference.Configure80211aParameters ();
+  m_modes.push_back (g_6mba);
+  m_modes.push_back (g_12mba);
+  m_modes.push_back (g_18mba);
+  m_modes.push_back (g_36mba);
+  m_modes.push_back (g_54mba);
+}
+
+void 
+YansWifiPhy::RegisterListener (WifiPhyListener *listener)
+{
+  m_state->RegisterListener (listener);
+}
+
+bool 
+YansWifiPhy::IsStateCcaBusy (void)
+{
+  return m_state->IsStateCcaBusy ();
+}
+
+bool 
+YansWifiPhy::IsStateIdle (void)
+{
+  return m_state->IsStateIdle ();
+}
+bool 
+YansWifiPhy::IsStateBusy (void)
+{
+  return m_state->IsStateBusy ();
+}
+bool 
+YansWifiPhy::IsStateSync (void)
+{
+  return m_state->IsStateSync ();
+}
+bool 
+YansWifiPhy::IsStateTx (void)
+{
+  return m_state->IsStateTx ();
+}
+
+Time
+YansWifiPhy::GetStateDuration (void)
+{
+  return m_state->GetStateDuration ();
+}
+Time
+YansWifiPhy::GetDelayUntilIdle (void)
+{
+  return m_state->GetDelayUntilIdle ();
+}
+
+Time 
+YansWifiPhy::GetLastRxStartTime (void) const
+{
+  return m_state->GetLastRxStartTime ();
+}
+
+Time 
+YansWifiPhy::CalculateTxDuration (uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble) const
+{
+  return m_interference.CalculateTxDuration (size, payloadMode, preamble);
+}
+
+double 
+YansWifiPhy::DbToRatio (double dB) const
+{
+  double ratio = pow(10.0,dB/10.0);
+  return ratio;
+}
+
+double 
+YansWifiPhy::DbmToW (double dBm) const
+{
+  double mW = pow(10.0,dBm/10.0);
+  return mW / 1000.0;
+}
+
+double
+YansWifiPhy::WToDbm (double w) const
+{
+  return 10.0 * log10(w * 1000.0);
+}
+
+double
+YansWifiPhy::RatioToDb (double ratio) const
+{
+  return 10.0 * log10(ratio);
+}
+
+double
+YansWifiPhy::GetEdThresholdW (void) const
+{
+  return m_edThresholdW;
+}
+
+double 
+YansWifiPhy::GetPowerDbm (uint8_t power) const
+{
+  NS_ASSERT (m_txPowerBaseDbm <= m_txPowerEndDbm);
+  NS_ASSERT (m_nTxPower > 0);
+  double dbm = m_txPowerBaseDbm + power * (m_txPowerEndDbm - m_txPowerBaseDbm) / m_nTxPower;
+  return dbm;
+}
+
+void
+YansWifiPhy::EndSync (Ptr<Packet> packet, Ptr<InterferenceHelper::Event> event)
+{
+  NS_LOG_FUNCTION (this << packet << event);
+  NS_ASSERT (IsStateSync ());
+  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
+
+  struct InterferenceHelper::SnrPer snrPer;
+  snrPer = m_interference.CalculateSnrPer (event);
+
+  NS_LOG_DEBUG ("mode="<<(event->GetPayloadMode ().GetDataRate ())<<
+                ", snr="<<snrPer.snr<<", per="<<snrPer.per<<", size="<<packet->GetSize ());
+  
+  if (m_random.GetValue () > snrPer.per) 
+    {
+      m_state->SwitchFromSyncEndOk (packet, snrPer.snr, event->GetPayloadMode (), event->GetPreambleType ());
+    } 
+  else 
+    {
+      /* failure. */
+      m_state->SwitchFromSyncEndError (packet, snrPer.snr);
+    }
+}
+
+
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/yans-wifi-phy.h	Mon Nov 24 06:36:05 2008 +0100
@@ -0,0 +1,159 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006 INRIA
+ *
+ * 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>
+ */
+
+#ifndef YANS_WIFI_PHY_H
+#define YANS_WIFI_PHY_H
+
+#include <stdint.h>
+#include "ns3/callback.h"
+#include "ns3/event-id.h"
+#include "ns3/packet.h"
+#include "ns3/object.h"
+#include "ns3/traced-callback.h"
+#include "ns3/nstime.h"
+#include "ns3/ptr.h"
+#include "ns3/random-variable.h"
+#include "wifi-phy.h"
+#include "wifi-mode.h"
+#include "wifi-preamble.h"
+#include "wifi-phy-standard.h"
+#include "interference-helper.h"
+
+
+namespace ns3 {
+
+class RandomUniform;
+class RxEvent;
+class YansWifiChannel;
+class WifiPhyStateHelper;
+
+
+/**
+ * \brief 802.11 PHY layer model
+ *
+ * This PHY implements a model of 802.11a. The model
+ * implemented here is based on the model described
+ * in "Yet Another Network Simulator", 
+ * (http://cutebugs.net/files/wns2-yans.pdf).
+ *
+ *
+ * This PHY model depends on a channel loss and delay
+ * model as provided by the ns3::PropagationLossModel
+ * and ns3::PropagationDelayModel classes, both of which are
+ * members of the ns3::YansWifiChannel class.
+ */
+class YansWifiPhy : public WifiPhy
+{
+public:
+
+  static TypeId GetTypeId (void);
+
+  YansWifiPhy ();
+  virtual ~YansWifiPhy ();
+
+  void SetChannel (Ptr<YansWifiChannel> channel);
+  void StartReceivePacket (Ptr<Packet> packet,
+                           double rxPowerDbm,
+                           WifiMode mode,
+                           WifiPreamble preamble);
+
+  void SetStandard (enum WifiPhyStandard standard);
+  void SetRxNoise (double ratio);
+  void SetTxPowerStart (double start);
+  void SetTxPowerEnd (double end);
+  void SetNTxPower (uint32_t n);
+  void SetTxGain (double gain);
+  void SetRxGain (double gain);
+  void SetEdThreshold (double threshold);
+  void SetCcaMode1Threshold (double threshold);
+  void SetErrorRateModel (Ptr<ErrorRateModel> rate);
+  void SetDevice (Ptr<Object> device);
+  void SetMobility (Ptr<Object> mobility);
+  double GetRxNoise (void) const;
+  double GetTxGain (void) const;
+  double GetRxGain (void) const;
+  double GetEdThreshold (void) const;
+  double GetCcaMode1Threshold (void) const;
+  Ptr<ErrorRateModel> GetErrorRateModel (void) const;
+  Ptr<Object> GetDevice (void) const;
+  Ptr<Object> GetMobility (void);
+
+
+  virtual double GetTxPowerStart (void) const;
+  virtual double GetTxPowerEnd (void) const;
+  virtual uint32_t GetNTxPower (void) const;
+  virtual void SetReceiveOkCallback (WifiPhy::SyncOkCallback callback);
+  virtual void SetReceiveErrorCallback (WifiPhy::SyncErrorCallback callback);
+  virtual void SendPacket (Ptr<const Packet> packet, WifiMode mode, enum WifiPreamble preamble, uint8_t txPowerLevel);
+  virtual void RegisterListener (WifiPhyListener *listener);
+  virtual bool IsStateCcaBusy (void);
+  virtual bool IsStateIdle (void);
+  virtual bool IsStateBusy (void);
+  virtual bool IsStateSync (void);
+  virtual bool IsStateTx (void);
+  virtual Time GetStateDuration (void);
+  virtual Time GetDelayUntilIdle (void);
+  virtual Time GetLastRxStartTime (void) const;
+  virtual Time CalculateTxDuration (uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble) const;
+  virtual uint32_t GetNModes (void) const;
+  virtual WifiMode GetMode (uint32_t mode) const;
+  virtual double CalculateSnr (WifiMode txMode, double ber) const;
+  virtual Ptr<WifiChannel> GetChannel (void) const;
+
+private:
+  typedef std::vector<WifiMode> Modes;
+
+private:
+  YansWifiPhy (const YansWifiPhy &o);
+  virtual void DoDispose (void);
+  void Configure80211a (void);
+  void ConfigureHolland (void);
+  double GetEdThresholdW (void) const;
+  double DbmToW (double dbm) const;
+  double DbToRatio (double db) const;
+  double WToDbm (double w) const;
+  double RatioToDb (double ratio) const;
+  double GetPowerDbm (uint8_t power) const;
+  void EndSync (Ptr<Packet> packet, Ptr<InterferenceHelper::Event> event);
+
+private:
+  double   m_edThresholdW;
+  double   m_ccaMode1ThresholdW;
+  double   m_txGainDb;
+  double   m_rxGainDb;
+  double   m_txPowerBaseDbm;
+  double   m_txPowerEndDbm;
+  uint32_t m_nTxPower;
+
+  Ptr<YansWifiChannel> m_channel;
+  Ptr<Object> m_device;
+  Ptr<Object> m_mobility;
+  Modes m_modes;
+  EventId m_endSyncEvent;
+  UniformVariable m_random;
+  WifiPhyStandard m_standard;
+  Ptr<WifiPhyStateHelper> m_state;
+  InterferenceHelper m_interference;
+};
+
+} // namespace ns3
+
+
+#endif /* YANS_WIFI_PHY_H */
--- a/src/helper/wifi-helper.cc	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/helper/wifi-helper.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -23,13 +23,12 @@
 #include "ns3/wifi-phy.h"
 #include "ns3/wifi-remote-station-manager.h"
 #include "ns3/wifi-channel.h"
+#include "ns3/yans-wifi-channel.h"
 #include "ns3/propagation-delay-model.h"
 #include "ns3/propagation-loss-model.h"
 #include "ns3/mobility-model.h"
 #include "ns3/log.h"
 #include "ns3/pcap-writer.h"
-#include "ns3/wifi-mode.h"
-#include "ns3/wifi-preamble.h"
 #include "ns3/config.h"
 #include "ns3/simulator.h"
 
@@ -39,41 +38,20 @@
 
 namespace ns3 {
 
-static void PcapPhyTxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet,
-                            WifiMode mode, WifiPreamble preamble, 
-                            uint8_t txLevel)
-{
-  writer->WritePacket (packet);
-}
-
-static void PcapPhyRxEvent (Ptr<PcapWriter> writer, 
-                            Ptr<const Packet> packet, double snr, WifiMode mode, 
-                            enum WifiPreamble preamble)
-{
-  writer->WritePacket (packet);
-}
-
-static void AsciiPhyTxEvent (std::ostream *os, std::string context, 
-                             Ptr<const Packet> packet,
-                             WifiMode mode, WifiPreamble preamble, 
-                             uint8_t txLevel)
-{
-  *os << "+ " << Simulator::Now () << " " << context << " " << *packet << std::endl;
-}
-
-static void AsciiPhyRxOkEvent (std::ostream *os, std::string context, 
-                               Ptr<const Packet> packet, double snr, WifiMode mode, 
-                               enum WifiPreamble preamble)
-{
-  *os << "r " << Simulator::Now () << " " << context << " " << *packet << std::endl;
-}
+WifiPhyHelper::~WifiPhyHelper ()
+{}
 
 
 WifiHelper::WifiHelper ()
+{}
+
+WifiHelper
+WifiHelper::Default (void)
 {
-  m_stationManager.SetTypeId ("ns3::ArfWifiManager");
-  m_phy.SetTypeId ("ns3::WifiPhy");
-  m_mac.SetTypeId ("ns3::AdhocWifiMac");
+  WifiHelper helper;
+  helper.SetRemoteStationManager ("ns3::ArfWifiManager");
+  helper.SetMac ("ns3::AdhocWifiMac");
+  return helper;
 }
 
 void 
@@ -122,175 +100,27 @@
   m_mac.Set (n7, v7);
 }
 
-void 
-WifiHelper::SetPhy (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_phy = ObjectFactory ();
-  m_phy.SetTypeId (type);
-  m_phy.Set (n0, v0);
-  m_phy.Set (n1, v1);
-  m_phy.Set (n2, v2);
-  m_phy.Set (n3, v3);
-  m_phy.Set (n4, v4);
-  m_phy.Set (n5, v5);
-  m_phy.Set (n6, v6);
-  m_phy.Set (n7, v7);
-}
-
-void 
-WifiHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid)
+NetDeviceContainer 
+WifiHelper::Install (const WifiPhyHelper &phyHelper, NodeContainer c) const
 {
-  std::ostringstream oss;
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/";
-  Config::MatchContainer matches = Config::LookupMatches (oss.str ());
-  if (matches.GetN () == 0)
-    {
-      return;
-    }
-  oss.str ("");
-  oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
-  Ptr<PcapWriter> pcap = Create<PcapWriter> ();
-  pcap->Open (oss.str ());
-  pcap->WriteWifiHeader ();
-  oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/Tx";
-  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapPhyTxEvent, pcap));
-  oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/RxOk";
-  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapPhyRxEvent, pcap));
-}
-void 
-WifiHelper::EnablePcap (std::string filename, NetDeviceContainer d)
-{
-  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
-    {
-      Ptr<NetDevice> dev = *i;
-      EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
-    }
-}
-void
-WifiHelper::EnablePcap (std::string filename, NodeContainer n)
-{
-  NetDeviceContainer devs;
-  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+  NetDeviceContainer devices;
+  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
     {
       Ptr<Node> node = *i;
-      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-        {
-          devs.Add (node->GetDevice (j));
-        }
+      Ptr<WifiNetDevice> device = CreateObject<WifiNetDevice> ();
+      Ptr<WifiRemoteStationManager> manager = m_stationManager.Create<WifiRemoteStationManager> ();
+      Ptr<WifiMac> mac = m_mac.Create<WifiMac> ();
+      Ptr<WifiPhy> phy = phyHelper.Create (node, device);
+      mac->SetAddress (Mac48Address::Allocate ());
+      device->SetMac (mac);
+      device->SetPhy (phy);
+      device->SetRemoteStationManager (manager);
+      node->AddDevice (device);
+      devices.Add (device);
+      NS_LOG_DEBUG ("node="<<node<<", mob="<<node->GetObject<MobilityModel> ());
     }
-  EnablePcap (filename, devs);
-}
-
-void
-WifiHelper::EnablePcapAll (std::string filename)
-{
-  EnablePcap (filename, NodeContainer::GetGlobal ());
+  return devices;
 }
 
-void 
-WifiHelper::EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid)
-{
-  Packet::EnablePrinting ();
-  std::ostringstream oss;
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/RxOk";
-  Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyRxOkEvent, &os));
-  oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/Tx";
-  Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyTxEvent, &os));
-}
-void 
-WifiHelper::EnableAscii (std::ostream &os, NetDeviceContainer d)
-{
-  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
-    {
-      Ptr<NetDevice> dev = *i;
-      EnableAscii (os, dev->GetNode ()->GetId (), dev->GetIfIndex ());
-    }
-}
-void
-WifiHelper::EnableAscii (std::ostream &os, NodeContainer n)
-{
-  NetDeviceContainer devs;
-  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
-    {
-      Ptr<Node> node = *i;
-      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-        {
-          devs.Add (node->GetDevice (j));
-        }
-    }
-  EnableAscii (os, devs);
-}
-
-void
-WifiHelper::EnableAsciiAll (std::ostream &os)
-{
-  EnableAscii (os, NodeContainer::GetGlobal ());
-}
-
-NetDeviceContainer
-WifiHelper::Install (Ptr<Node> node) const
-{
-  return Install (NodeContainer (node));
-}
-
-NetDeviceContainer
-WifiHelper::Install (Ptr<Node> node, Ptr<WifiChannel> channel) const
-{
-  return NetDeviceContainer (InstallPriv (node, channel));
-}
-
-NetDeviceContainer 
-WifiHelper::Install (const NodeContainer &c) const
-{
-  Ptr<WifiChannel> channel = CreateObject<WifiChannel> ();
-  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
-  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
-  log->SetReferenceModel (CreateObject<FriisPropagationLossModel> ());
-  channel->SetPropagationLossModel (log);
-
-  return Install (c, channel);
-}
-
-NetDeviceContainer 
-WifiHelper::Install (const NodeContainer &c, Ptr<WifiChannel> channel) const
-{
-  NetDeviceContainer devs;
-
-  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++)
-    {
-      devs.Add (InstallPriv (*i, channel));
-    }
-
-  return devs;
-}
-
-Ptr<NetDevice>
-WifiHelper::InstallPriv (Ptr<Node> node, Ptr<WifiChannel> channel) const
-{
-  Ptr<WifiNetDevice> device = CreateObject<WifiNetDevice> ();
-  Ptr<WifiRemoteStationManager> manager = m_stationManager.Create<WifiRemoteStationManager> ();
-  Ptr<WifiMac> mac = m_mac.Create<WifiMac> ();
-  Ptr<WifiPhy> phy = m_phy.Create<WifiPhy> ();
-  mac->SetAddress (Mac48Address::Allocate ());
-  device->SetMac (mac);
-  device->SetPhy (phy);
-  device->SetRemoteStationManager (manager);
-  device->SetChannel (channel);
-  node->AddDevice (device);
-  NS_LOG_DEBUG ("node="<<node<<", mob="<<node->GetObject<MobilityModel> ());
-
-  return device;
-}
 
 } // namespace ns3
--- a/src/helper/wifi-helper.h	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/helper/wifi-helper.h	Mon Nov 24 06:36:05 2008 +0100
@@ -28,7 +28,16 @@
 
 namespace ns3 {
 
-class WifiChannel;
+class WifiPhy;
+class WifiNetDevice;
+class Node;
+
+class WifiPhyHelper
+{
+public:
+  virtual ~WifiPhyHelper ();
+  virtual Ptr<WifiPhy> Create (Ptr<Node> node, Ptr<WifiNetDevice> device) const = 0;
+};
 
 /**
  * \brief helps to create WifiNetDevice objects
@@ -42,6 +51,8 @@
 public:
   WifiHelper ();
 
+  static WifiHelper Default (void);
+
   /**
    * \param type the type of ns3::WifiRemoteStationManager to create.
    * \param n0 the name of the attribute to set
@@ -106,180 +117,11 @@
                std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
                std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
 
-  /**
-   * \param phyType the type of ns3::WifiPhy 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 phy.
-   */
-  void SetPhy (std::string phyType,
-               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 filename filename prefix to use for pcap files.
-   * \param nodeid the id of the node to generate pcap output for.
-   * \param deviceid the id of the device to generate pcap output for.
-   *
-   * Generate a pcap file which contains the link-level data observed
-   * by the specified deviceid within the specified nodeid. The pcap
-   * data is stored in the file prefix-nodeid-deviceid.pcap.
-   *
-   * This method should be invoked after the network topology has 
-   * been fully constructed.
-   */
-  static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param d container of devices of type ns3::WifiNetDevice
-   *
-   * Enable pcap output on each input device which is of the
-   * ns3::WifiNetDevice type.
-   */
-  static void EnablePcap (std::string filename, NetDeviceContainer d);
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param n container of nodes.
-   *
-   * Enable pcap output on each device which is of the
-   * ns3::WifiNetDevice type and which is located in one of the 
-   * input nodes.
-   */
-  static void EnablePcap (std::string filename, NodeContainer n);
-  /**
-   * \param filename filename prefix to use for pcap files.
-   *
-   * Enable pcap output on each device which is of the
-   * ns3::WifiNetDevice type
-   */
-  static void EnablePcapAll (std::string filename);
-
-  /**
-   * \param os output stream
-   * \param nodeid the id of the node to generate ascii output for.
-   * \param deviceid the id of the device to generate ascii output for.
-   *
-   * Enable ascii output on the specified deviceid within the
-   * specified nodeid if it is of type ns3::WifiNetDevice and dump 
-   * that to the specified stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid);
-  /**
-   * \param os output stream
-   * \param d device container
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::WifiNetDevice type and which is located in the input
-   * device container and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, NetDeviceContainer d);
-  /**
-   * \param os output stream
-   * \param n node container
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::WifiNetDevice type and which is located in one
-   * of the input node and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, NodeContainer n);
-  /**
-   * \param os output stream
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::WifiNetDevice type and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAsciiAll (std::ostream &os);
-
-  /**
-   * This method creates a new ns3::WifiNetDevice that is configured with an 
-   * ns3::WifiRemoteStationManager, ns3::WifiMac and ns3::WifiPhy, all of which 
-   * are created based on the user-specified attributes in 
-   * WifiHelper::SetRemoteStationManager, WifiHelper::SetMac, and 
-   * WifiHelper::SetPhy.  It attaches this new device to the provided node.  It 
-   * also creates a simple ns3::WifiChannel (with a default ns3::PropagationLossModel
-   * and ns3::PropagationDelayModel) and attaches the new channel to the new device. 
-   *
-   * \param node The node to install the device in
-   * \returns A containter holding the added net device.
-   */
-  NetDeviceContainer Install (Ptr<Node> node) const;
-
-  /**
-   * This method creates a new ns3::WifiNetDevice that is configured with an 
-   * ns3::WifiRemoteStationManager, ns3::WifiMac and ns3::WifiPhy, all of which 
-   * are created based on the user-specified attributes in 
-   * WifiHelper::SetRemoteStationManager, WifiHelper::SetMac, and 
-   * WifiHelper::SetPhy.  It attaches this new device to the provided node and
-   * attaches the new device to the provided channel.
-   *
-   * \param node The node to install the device in
-   * \param channel The chanel to attach to the device.
-   * \returns A containter holding the added net device.
-   */
-  NetDeviceContainer Install (Ptr<Node> node, Ptr<WifiChannel> channel) const;
-
-  /**
-   * This method creates a simple ns3::WifiChannel (with a default 
-   * ns3::PropagationLossModel and ns3::PropagationDelayModel).  For each 
-   * Ptr<Node> in the provided NodeContainer, this method creates a new 
-   * ns3::WifiNetDevice that is configured with an ns3::WifiRemoteStationManager,
-   * ns3::WifiMac and ns3::WifiPhy, all of which are created based on the 
-   * user-specified attributes in WifiHelper::SetRemoteStationManager, 
-   * WifiHelper::SetMac, and WifiHelper::SetPhy.  It attaches these new devices to
-   * their corresponding nodes and attaches the new devices to the new channel.
-   *
-   * \param c The NodeContainer holding the nodes to be changed.
-   * \returns A containter holding the added net devices.
-   */
-  NetDeviceContainer Install (const NodeContainer &c) const;
-
-  /**
-   * For each Ptr<Node> in the provided NodeContainer, this method creates a new 
-   * ns3::WifiNetDevice that is configured with an ns3::WifiRemoteStationManager,
-   * ns3::WifiMac and ns3::WifiPhy, all of which are created based on the 
-   * user-specified attributes in WifiHelper::SetRemoteStationManager, 
-   * WifiHelper::SetMac, and WifiHelper::SetPhy.  It attaches these new devices to
-   * their corresponding nodes and attaches the new devices to the provided channel.
-   *
-   * \param c The NodeContainer holding the nodes to be changed.
-   * \param channel The channel to attach to the devices.
-   * \returns A containter holding the added net devices.
-   */
-  NetDeviceContainer Install (const NodeContainer &c, Ptr<WifiChannel> channel) const;
+  NetDeviceContainer Install (const WifiPhyHelper &phy, NodeContainer c) const;
 
 private:
-  Ptr<NetDevice> InstallPriv (Ptr<Node> node, Ptr<WifiChannel> channel) const;
-
   ObjectFactory m_stationManager;
   ObjectFactory m_mac;
-  ObjectFactory m_phy;
 };
 
 } // namespace ns3
--- a/src/helper/wscript	Wed Nov 19 16:41:17 2008 -0800
+++ b/src/helper/wscript	Mon Nov 24 06:36:05 2008 +0100
@@ -21,6 +21,7 @@
         'ipv4-interface-container.cc',
         'udp-echo-helper.cc',
         'bridge-helper.cc',
+        'yans-wifi-phy-helper.cc',
         'v4ping-helper.cc',
         ]
 
@@ -45,6 +46,7 @@
         'ipv4-interface-container.h',
         'udp-echo-helper.h',
         'bridge-helper.h',
+        'yans-wifi-phy-helper.h',
         'v4ping-helper.h',
         ]
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/yans-wifi-phy-helper.cc	Mon Nov 24 06:36:05 2008 +0100
@@ -0,0 +1,305 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * 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>
+ */
+#include "yans-wifi-phy-helper.h"
+#include "ns3/error-rate-model.h"
+#include "ns3/propagation-loss-model.h"
+#include "ns3/propagation-delay-model.h"
+#include "ns3/yans-wifi-channel.h"
+#include "ns3/yans-wifi-phy.h"
+#include "ns3/wifi-net-device.h"
+#include "ns3/pcap-writer.h"
+#include "ns3/simulator.h"
+#include "ns3/config.h"
+
+namespace ns3 {
+
+static void PcapPhyTxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet,
+                            WifiMode mode, WifiPreamble preamble, 
+                            uint8_t txLevel)
+{
+  writer->WritePacket (packet);
+}
+
+static void PcapPhyRxEvent (Ptr<PcapWriter> writer, 
+                            Ptr<const Packet> packet, double snr, WifiMode mode, 
+                            enum WifiPreamble preamble)
+{
+  writer->WritePacket (packet);
+}
+
+static void AsciiPhyTxEvent (std::ostream *os, std::string context, 
+                             Ptr<const Packet> packet,
+                             WifiMode mode, WifiPreamble preamble, 
+                             uint8_t txLevel)
+{
+  *os << "+ " << Simulator::Now () << " " << context << " " << *packet << std::endl;
+}
+
+static void AsciiPhyRxOkEvent (std::ostream *os, std::string context, 
+                               Ptr<const Packet> packet, double snr, WifiMode mode, 
+                               enum WifiPreamble preamble)
+{
+  *os << "r " << Simulator::Now () << " " << context << " " << *packet << std::endl;
+}
+
+
+YansWifiChannelHelper::YansWifiChannelHelper ()
+{}
+
+YansWifiChannelHelper 
+YansWifiChannelHelper::Default (void)
+{
+  YansWifiChannelHelper helper;
+  helper.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
+  helper.AddPropagationLoss ("ns3::LogDistancePropagationLossModel");
+  return helper;
+}
+
+void 
+YansWifiChannelHelper::AddPropagationLoss (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)
+{
+  ObjectFactory factory;
+  factory.SetTypeId (type);
+  factory.Set (n0, v0);
+  factory.Set (n1, v1);
+  factory.Set (n2, v2);
+  factory.Set (n3, v3);
+  factory.Set (n4, v4);
+  factory.Set (n5, v5);
+  factory.Set (n6, v6);
+  factory.Set (n7, v7);
+  m_propagationLoss.push_back (factory);
+}
+
+void 
+YansWifiChannelHelper::SetPropagationDelay (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)
+{
+  ObjectFactory factory;
+  factory.SetTypeId (type);
+  factory.Set (n0, v0);
+  factory.Set (n1, v1);
+  factory.Set (n2, v2);
+  factory.Set (n3, v3);
+  factory.Set (n4, v4);
+  factory.Set (n5, v5);
+  factory.Set (n6, v6);
+  factory.Set (n7, v7);
+  m_propagationDelay = factory;
+}
+
+Ptr<YansWifiChannel> 
+YansWifiChannelHelper::Create (void) const
+{
+  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
+  Ptr<PropagationLossModel> prev = 0;
+  for (std::vector<ObjectFactory>::const_iterator i = m_propagationLoss.begin (); i != m_propagationLoss.end (); ++i)
+    {
+      Ptr<PropagationLossModel> cur = (*i).Create<PropagationLossModel> ();
+      if (prev != 0)
+	{
+	  prev->SetNext (cur);
+	  prev = cur;
+	}
+      if (m_propagationLoss.begin () == i)
+	{
+	  channel->SetPropagationLossModel (cur);
+	}
+    }
+  Ptr<PropagationDelayModel> delay = m_propagationDelay.Create<PropagationDelayModel> ();
+  channel->SetPropagationDelayModel (delay);
+  return channel;
+}
+
+
+YansWifiPhyHelper::YansWifiPhyHelper ()
+  : m_channel (0)
+{
+  m_phy.SetTypeId ("ns3::YansWifiPhy");
+}
+
+YansWifiPhyHelper 
+YansWifiPhyHelper::Default (void)
+{
+  YansWifiPhyHelper helper;
+  helper.SetErrorRateModel ("ns3::ErrorRateModel");
+  return helper;
+}
+
+void 
+YansWifiPhyHelper::SetChannel (Ptr<YansWifiChannel> channel)
+{
+  m_channel = channel;
+}
+void 
+YansWifiPhyHelper::Set (std::string name, const AttributeValue &v)
+{
+  m_phy.Set (name, v);
+}
+
+void 
+YansWifiPhyHelper::SetErrorRateModel (std::string name,
+                                     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_errorRateModel = ObjectFactory ();
+  m_errorRateModel.SetTypeId (name);
+  m_errorRateModel.Set (n0, v0);
+  m_errorRateModel.Set (n1, v1);
+  m_errorRateModel.Set (n2, v2);
+  m_errorRateModel.Set (n3, v3);
+  m_errorRateModel.Set (n4, v4);
+  m_errorRateModel.Set (n5, v5);
+  m_errorRateModel.Set (n6, v6);
+  m_errorRateModel.Set (n7, v7);
+}
+
+
+Ptr<WifiPhy> 
+YansWifiPhyHelper::Create (Ptr<Node> node, Ptr<WifiNetDevice> device) const
+{
+  Ptr<YansWifiPhy> phy = m_phy.Create<YansWifiPhy> ();
+  Ptr<ErrorRateModel> error = m_errorRateModel.Create<ErrorRateModel> ();
+  phy->SetErrorRateModel (error);
+  phy->SetChannel (m_channel);
+  phy->SetMobility (node);
+  phy->SetDevice (device);
+  return phy;
+}
+
+void 
+YansWifiPhyHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid)
+{
+  std::ostringstream oss;
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/";
+  Config::MatchContainer matches = Config::LookupMatches (oss.str ());
+  if (matches.GetN () == 0)
+    {
+      return;
+    }
+  oss.str ("");
+  oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
+  // we must fully-qualify the call to Create below because it conflicts
+  // with the locally-defined WifiPhyHelper::Create method.
+  Ptr<PcapWriter> pcap = ::ns3::Create<PcapWriter> ();
+  pcap->Open (oss.str ());
+  pcap->WriteWifiHeader ();
+  oss.str ("");
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/Tx";
+  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapPhyTxEvent, pcap));
+  oss.str ("");
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/RxOk";
+  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapPhyRxEvent, pcap));
+}
+void 
+YansWifiPhyHelper::EnablePcap (std::string filename, NetDeviceContainer d)
+{
+  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
+    {
+      Ptr<NetDevice> dev = *i;
+      EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
+    }
+}
+void
+YansWifiPhyHelper::EnablePcap (std::string filename, NodeContainer n)
+{
+  NetDeviceContainer devs;
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
+        {
+          devs.Add (node->GetDevice (j));
+        }
+    }
+  EnablePcap (filename, devs);
+}
+
+void
+YansWifiPhyHelper::EnablePcapAll (std::string filename)
+{
+  EnablePcap (filename, NodeContainer::GetGlobal ());
+}
+
+void 
+YansWifiPhyHelper::EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid)
+{
+  Packet::EnablePrinting ();
+  std::ostringstream oss;
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/RxOk";
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyRxOkEvent, &os));
+  oss.str ("");
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/Tx";
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyTxEvent, &os));
+}
+void 
+YansWifiPhyHelper::EnableAscii (std::ostream &os, NetDeviceContainer d)
+{
+  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
+    {
+      Ptr<NetDevice> dev = *i;
+      EnableAscii (os, dev->GetNode ()->GetId (), dev->GetIfIndex ());
+    }
+}
+void
+YansWifiPhyHelper::EnableAscii (std::ostream &os, NodeContainer n)
+{
+  NetDeviceContainer devs;
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
+        {
+          devs.Add (node->GetDevice (j));
+        }
+    }
+  EnableAscii (os, devs);
+}
+
+void
+YansWifiPhyHelper::EnableAsciiAll (std::ostream &os)
+{
+  EnableAscii (os, NodeContainer::GetGlobal ());
+}
+
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/yans-wifi-phy-helper.h	Mon Nov 24 06:36:05 2008 +0100
@@ -0,0 +1,167 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * 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>
+ */
+#ifndef YANS_WIFI_PHY_HELPER_H
+#define YANS_WIFI_PHY_HELPER_H
+
+#include "wifi-helper.h"
+#include "ns3/yans-wifi-channel.h"
+
+namespace ns3 {
+
+class YansWifiChannelHelper
+{
+public:
+  YansWifiChannelHelper ();
+
+  static YansWifiChannelHelper Default (void);
+
+  void AddPropagationLoss (std::string name,
+			   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 ());
+  void SetPropagationDelay (std::string name,
+			    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 ());
+
+  Ptr<YansWifiChannel> Create (void) const;
+
+private:
+  std::vector<ObjectFactory> m_propagationLoss;
+  ObjectFactory m_propagationDelay;
+};
+
+class YansWifiPhyHelper : public WifiPhyHelper
+{
+public:
+  YansWifiPhyHelper ();
+
+  static YansWifiPhyHelper Default (void);
+
+  void SetChannel (Ptr<YansWifiChannel> channel);
+  void Set (std::string name, const AttributeValue &v);
+  void SetErrorRateModel (std::string name,
+                          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 ());
+
+  virtual Ptr<WifiPhy> Create (Ptr<Node> node, Ptr<WifiNetDevice> device) const;
+
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param nodeid the id of the node to generate pcap output for.
+   * \param deviceid the id of the device to generate pcap output for.
+   *
+   * Generate a pcap file which contains the link-level data observed
+   * by the specified deviceid within the specified nodeid. The pcap
+   * data is stored in the file prefix-nodeid-deviceid.pcap.
+   *
+   * This method should be invoked after the network topology has 
+   * been fully constructed.
+   */
+  static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param d container of devices of type ns3::WifiNetDevice
+   *
+   * Enable pcap output on each input device which is of the
+   * ns3::WifiNetDevice type.
+   */
+  static void EnablePcap (std::string filename, NetDeviceContainer d);
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param n container of nodes.
+   *
+   * Enable pcap output on each device which is of the
+   * ns3::WifiNetDevice type and which is located in one of the 
+   * input nodes.
+   */
+  static void EnablePcap (std::string filename, NodeContainer n);
+  /**
+   * \param filename filename prefix to use for pcap files.
+   *
+   * Enable pcap output on each device which is of the
+   * ns3::WifiNetDevice type
+   */
+  static void EnablePcapAll (std::string filename);
+
+  /**
+   * \param os output stream
+   * \param nodeid the id of the node to generate ascii output for.
+   * \param deviceid the id of the device to generate ascii output for.
+   *
+   * Enable ascii output on the specified deviceid within the
+   * specified nodeid if it is of type ns3::WifiNetDevice and dump 
+   * that to the specified stdc++ output stream.
+   */
+  static void EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid);
+  /**
+   * \param os output stream
+   * \param d device container
+   *
+   * Enable ascii output on each device which is of the
+   * ns3::WifiNetDevice type and which is located in the input
+   * device container and dump that to the specified
+   * stdc++ output stream.
+   */
+  static void EnableAscii (std::ostream &os, NetDeviceContainer d);
+  /**
+   * \param os output stream
+   * \param n node container
+   *
+   * Enable ascii output on each device which is of the
+   * ns3::WifiNetDevice type and which is located in one
+   * of the input node and dump that to the specified
+   * stdc++ output stream.
+   */
+  static void EnableAscii (std::ostream &os, NodeContainer n);
+  /**
+   * \param os output stream
+   *
+   * Enable ascii output on each device which is of the
+   * ns3::WifiNetDevice type and dump that to the specified
+   * stdc++ output stream.
+   */
+  static void EnableAsciiAll (std::ostream &os);
+
+private:
+  ObjectFactory m_phy;
+  ObjectFactory m_errorRateModel;
+  Ptr<YansWifiChannel> m_channel;
+};
+
+} // namespace ns3
+
+#endif /* YANS_WIFI_PHY_HELPER_H */