merge
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Fri, 09 Jan 2009 11:44:13 +0000
changeset 4071 a785ca39a10c
parent 4070 c2ad9c39fa06 (current diff)
parent 4063 803720fc9f31 (diff)
child 4072 5d226c752e85
merge
src/devices/wifi/wscript
src/simulator/wscript
--- a/bindings/python/ns3_module_contrib.py	Sat Jan 03 23:14:32 2009 +0000
+++ b/bindings/python/ns3_module_contrib.py	Fri Jan 09 11:44:13 2009 +0000
@@ -9,18 +9,28 @@
     module.add_class('EventGarbageCollector')
     ## gnuplot.h: ns3::Gnuplot [class]
     module.add_class('Gnuplot')
+    ## gnuplot.h: ns3::GnuplotCollection [class]
+    module.add_class('GnuplotCollection')
     ## gnuplot.h: ns3::GnuplotDataset [class]
     module.add_class('GnuplotDataset')
-    ## gnuplot.h: ns3::GnuplotDataset::Style [enumeration]
-    module.add_enum('Style', ['LINES', 'POINTS', 'LINES_POINTS', 'DOTS', 'IMPULSES', 'STEPS', 'FSTEPS', 'HISTEPS'], outer_class=root_module['ns3::GnuplotDataset'])
-    ## gnuplot.h: ns3::GnuplotDataset::ErrorBars [enumeration]
-    module.add_enum('ErrorBars', ['NONE', 'X', 'Y', 'XY'], outer_class=root_module['ns3::GnuplotDataset'])
     ## gtk-config-store.h: ns3::GtkConfigStore [class]
     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'])
+    ## gnuplot.h: ns3::Gnuplot2dDataset [class]
+    module.add_class('Gnuplot2dDataset', parent=root_module['ns3::GnuplotDataset'])
+    ## gnuplot.h: ns3::Gnuplot2dDataset::Style [enumeration]
+    module.add_enum('Style', ['LINES', 'POINTS', 'LINES_POINTS', 'DOTS', 'IMPULSES', 'STEPS', 'FSTEPS', 'HISTEPS'], outer_class=root_module['ns3::Gnuplot2dDataset'])
+    ## gnuplot.h: ns3::Gnuplot2dDataset::ErrorBars [enumeration]
+    module.add_enum('ErrorBars', ['NONE', 'X', 'Y', 'XY'], outer_class=root_module['ns3::Gnuplot2dDataset'])
+    ## gnuplot.h: ns3::Gnuplot2dFunction [class]
+    module.add_class('Gnuplot2dFunction', parent=root_module['ns3::GnuplotDataset'])
+    ## gnuplot.h: ns3::Gnuplot3dDataset [class]
+    module.add_class('Gnuplot3dDataset', parent=root_module['ns3::GnuplotDataset'])
+    ## gnuplot.h: ns3::Gnuplot3dFunction [class]
+    module.add_class('Gnuplot3dFunction', parent=root_module['ns3::GnuplotDataset'])
     
     ## Register a nested module for the namespace Config
     
@@ -66,10 +76,15 @@
     register_Ns3DelayJitterEstimation_methods(root_module, root_module['ns3::DelayJitterEstimation'])
     register_Ns3EventGarbageCollector_methods(root_module, root_module['ns3::EventGarbageCollector'])
     register_Ns3Gnuplot_methods(root_module, root_module['ns3::Gnuplot'])
+    register_Ns3GnuplotCollection_methods(root_module, root_module['ns3::GnuplotCollection'])
     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'])
+    register_Ns3Gnuplot2dDataset_methods(root_module, root_module['ns3::Gnuplot2dDataset'])
+    register_Ns3Gnuplot2dFunction_methods(root_module, root_module['ns3::Gnuplot2dFunction'])
+    register_Ns3Gnuplot3dDataset_methods(root_module, root_module['ns3::Gnuplot3dDataset'])
+    register_Ns3Gnuplot3dFunction_methods(root_module, root_module['ns3::Gnuplot3dFunction'])
     return
 
 def register_Ns3DelayJitterEstimation_methods(root_module, cls):
@@ -112,45 +127,87 @@
 def register_Ns3Gnuplot_methods(root_module, cls):
     ## gnuplot.h: ns3::Gnuplot::Gnuplot(ns3::Gnuplot const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Gnuplot const &', 'arg0')])
-    ## gnuplot.h: ns3::Gnuplot::Gnuplot(std::string pngFilename) [constructor]
-    cls.add_constructor([param('std::string', 'pngFilename')])
-    ## gnuplot.h: void ns3::Gnuplot::SetLegend(std::string xLegend, std::string yLegend) [member function]
+    ## gnuplot.h: ns3::Gnuplot::Gnuplot(std::string const & outputFilename="", std::string const & title="") [constructor]
+    cls.add_constructor([param('std::string const &', 'outputFilename', default_value='""'), param('std::string const &', 'title', default_value='""')])
+    ## gnuplot.h: static std::string ns3::Gnuplot::DetectTerminal(std::string const & filename) [member function]
+    cls.add_method('DetectTerminal', 
+                   'std::string', 
+                   [param('std::string const &', 'filename')], 
+                   is_static=True)
+    ## gnuplot.h: void ns3::Gnuplot::SetTerminal(std::string const & terminal) [member function]
+    cls.add_method('SetTerminal', 
+                   'void', 
+                   [param('std::string const &', 'terminal')])
+    ## gnuplot.h: void ns3::Gnuplot::SetTitle(std::string const & title) [member function]
+    cls.add_method('SetTitle', 
+                   'void', 
+                   [param('std::string const &', 'title')])
+    ## gnuplot.h: void ns3::Gnuplot::SetLegend(std::string const & xLegend, std::string const & yLegend) [member function]
     cls.add_method('SetLegend', 
                    'void', 
-                   [param('std::string', 'xLegend'), param('std::string', 'yLegend')])
+                   [param('std::string const &', 'xLegend'), param('std::string const &', 'yLegend')])
+    ## gnuplot.h: void ns3::Gnuplot::SetExtra(std::string const & extra) [member function]
+    cls.add_method('SetExtra', 
+                   'void', 
+                   [param('std::string const &', 'extra')])
+    ## gnuplot.h: void ns3::Gnuplot::AppendExtra(std::string const & extra) [member function]
+    cls.add_method('AppendExtra', 
+                   'void', 
+                   [param('std::string const &', 'extra')])
     ## gnuplot.h: void ns3::Gnuplot::AddDataset(ns3::GnuplotDataset const & dataset) [member function]
     cls.add_method('AddDataset', 
                    'void', 
                    [param('ns3::GnuplotDataset const &', 'dataset')])
-    ## gnuplot.h: void ns3::Gnuplot::GenerateOutput(std::ostream & os) [member function]
+    ## gnuplot.h: void ns3::Gnuplot::GenerateOutput(std::ostream & os) const [member function]
     cls.add_method('GenerateOutput', 
                    'void', 
-                   [param('std::ostream &', 'os')])
+                   [param('std::ostream &', 'os')], 
+                   is_const=True)
+    return
+
+def register_Ns3GnuplotCollection_methods(root_module, cls):
+    ## gnuplot.h: ns3::GnuplotCollection::GnuplotCollection(ns3::GnuplotCollection const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::GnuplotCollection const &', 'arg0')])
+    ## gnuplot.h: ns3::GnuplotCollection::GnuplotCollection(std::string const & outputFilename) [constructor]
+    cls.add_constructor([param('std::string const &', 'outputFilename')])
+    ## gnuplot.h: void ns3::GnuplotCollection::SetTerminal(std::string const & terminal) [member function]
+    cls.add_method('SetTerminal', 
+                   'void', 
+                   [param('std::string const &', 'terminal')])
+    ## gnuplot.h: void ns3::GnuplotCollection::AddPlot(ns3::Gnuplot const & plot) [member function]
+    cls.add_method('AddPlot', 
+                   'void', 
+                   [param('ns3::Gnuplot const &', 'plot')])
+    ## gnuplot.h: ns3::Gnuplot & ns3::GnuplotCollection::GetPlot(unsigned int id) [member function]
+    cls.add_method('GetPlot', 
+                   'ns3::Gnuplot &', 
+                   [param('unsigned int', 'id')])
+    ## gnuplot.h: void ns3::GnuplotCollection::GenerateOutput(std::ostream & os) const [member function]
+    cls.add_method('GenerateOutput', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True)
     return
 
 def register_Ns3GnuplotDataset_methods(root_module, cls):
-    ## gnuplot.h: ns3::GnuplotDataset::GnuplotDataset(ns3::GnuplotDataset const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::GnuplotDataset const &', 'arg0')])
-    ## gnuplot.h: ns3::GnuplotDataset::GnuplotDataset() [constructor]
-    cls.add_constructor([])
-    ## gnuplot.h: ns3::GnuplotDataset::GnuplotDataset(std::string title) [constructor]
-    cls.add_constructor([param('std::string', 'title')])
-    ## gnuplot.h: void ns3::GnuplotDataset::SetStyle(ns3::GnuplotDataset::Style style) [member function]
-    cls.add_method('SetStyle', 
+    ## gnuplot.h: ns3::GnuplotDataset::GnuplotDataset(ns3::GnuplotDataset const & original) [copy constructor]
+    cls.add_constructor([param('ns3::GnuplotDataset const &', 'original')])
+    ## gnuplot.h: void ns3::GnuplotDataset::SetTitle(std::string const & title) [member function]
+    cls.add_method('SetTitle', 
+                   'void', 
+                   [param('std::string const &', 'title')])
+    ## gnuplot.h: static void ns3::GnuplotDataset::SetDefaultExtra(std::string const & extra) [member function]
+    cls.add_method('SetDefaultExtra', 
                    'void', 
-                   [param('ns3::GnuplotDataset::Style', 'style')])
-    ## gnuplot.h: void ns3::GnuplotDataset::SetErrorBars(ns3::GnuplotDataset::ErrorBars errorBars) [member function]
-    cls.add_method('SetErrorBars', 
+                   [param('std::string const &', 'extra')], 
+                   is_static=True)
+    ## gnuplot.h: void ns3::GnuplotDataset::SetExtra(std::string const & extra) [member function]
+    cls.add_method('SetExtra', 
                    'void', 
-                   [param('ns3::GnuplotDataset::ErrorBars', 'errorBars')])
-    ## gnuplot.h: void ns3::GnuplotDataset::Add(double x, double y) [member function]
-    cls.add_method('Add', 
-                   'void', 
-                   [param('double', 'x'), param('double', 'y')])
-    ## gnuplot.h: void ns3::GnuplotDataset::Add(double x, double y, double errorDelta) [member function]
-    cls.add_method('Add', 
-                   'void', 
-                   [param('double', 'x'), param('double', 'y'), param('double', 'errorDelta')])
+                   [param('std::string const &', 'extra')])
+    ## gnuplot.h: ns3::GnuplotDataset::GnuplotDataset(ns3::GnuplotDataset::Data * data) [constructor]
+    cls.add_constructor([param('ns3::GnuplotDataset::Data *', 'data')], 
+                        visibility='protected')
     return
 
 def register_Ns3GtkConfigStore_methods(root_module, cls):
@@ -238,6 +295,93 @@
                    is_static=True)
     return
 
+def register_Ns3Gnuplot2dDataset_methods(root_module, cls):
+    ## gnuplot.h: ns3::Gnuplot2dDataset::Gnuplot2dDataset(ns3::Gnuplot2dDataset const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Gnuplot2dDataset const &', 'arg0')])
+    ## gnuplot.h: ns3::Gnuplot2dDataset::Gnuplot2dDataset(std::string const & title="Untitled") [constructor]
+    cls.add_constructor([param('std::string const &', 'title', default_value='"Untitled"')])
+    ## gnuplot.h: static void ns3::Gnuplot2dDataset::SetDefaultStyle(ns3::Gnuplot2dDataset::Style style) [member function]
+    cls.add_method('SetDefaultStyle', 
+                   'void', 
+                   [param('ns3::Gnuplot2dDataset::Style', 'style')], 
+                   is_static=True)
+    ## gnuplot.h: void ns3::Gnuplot2dDataset::SetStyle(ns3::Gnuplot2dDataset::Style style) [member function]
+    cls.add_method('SetStyle', 
+                   'void', 
+                   [param('ns3::Gnuplot2dDataset::Style', 'style')])
+    ## gnuplot.h: static void ns3::Gnuplot2dDataset::SetDefaultErrorBars(ns3::Gnuplot2dDataset::ErrorBars errorBars) [member function]
+    cls.add_method('SetDefaultErrorBars', 
+                   'void', 
+                   [param('ns3::Gnuplot2dDataset::ErrorBars', 'errorBars')], 
+                   is_static=True)
+    ## gnuplot.h: void ns3::Gnuplot2dDataset::SetErrorBars(ns3::Gnuplot2dDataset::ErrorBars errorBars) [member function]
+    cls.add_method('SetErrorBars', 
+                   'void', 
+                   [param('ns3::Gnuplot2dDataset::ErrorBars', 'errorBars')])
+    ## gnuplot.h: void ns3::Gnuplot2dDataset::Add(double x, double y) [member function]
+    cls.add_method('Add', 
+                   'void', 
+                   [param('double', 'x'), param('double', 'y')])
+    ## gnuplot.h: void ns3::Gnuplot2dDataset::Add(double x, double y, double errorDelta) [member function]
+    cls.add_method('Add', 
+                   'void', 
+                   [param('double', 'x'), param('double', 'y'), param('double', 'errorDelta')])
+    ## gnuplot.h: void ns3::Gnuplot2dDataset::Add(double x, double y, double minY, double maxY) [member function]
+    cls.add_method('Add', 
+                   'void', 
+                   [param('double', 'x'), param('double', 'y'), param('double', 'minY'), param('double', 'maxY')])
+    ## gnuplot.h: void ns3::Gnuplot2dDataset::AddEmptyLine() [member function]
+    cls.add_method('AddEmptyLine', 
+                   'void', 
+                   [])
+    return
+
+def register_Ns3Gnuplot2dFunction_methods(root_module, cls):
+    ## gnuplot.h: ns3::Gnuplot2dFunction::Gnuplot2dFunction(ns3::Gnuplot2dFunction const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Gnuplot2dFunction const &', 'arg0')])
+    ## gnuplot.h: ns3::Gnuplot2dFunction::Gnuplot2dFunction(std::string const & title="Untitled", std::string const & function="") [constructor]
+    cls.add_constructor([param('std::string const &', 'title', default_value='"Untitled"'), param('std::string const &', 'function', default_value='""')])
+    ## gnuplot.h: void ns3::Gnuplot2dFunction::SetFunction(std::string const & function) [member function]
+    cls.add_method('SetFunction', 
+                   'void', 
+                   [param('std::string const &', 'function')])
+    return
+
+def register_Ns3Gnuplot3dDataset_methods(root_module, cls):
+    ## gnuplot.h: ns3::Gnuplot3dDataset::Gnuplot3dDataset(ns3::Gnuplot3dDataset const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Gnuplot3dDataset const &', 'arg0')])
+    ## gnuplot.h: ns3::Gnuplot3dDataset::Gnuplot3dDataset(std::string const & title="Untitled") [constructor]
+    cls.add_constructor([param('std::string const &', 'title', default_value='"Untitled"')])
+    ## gnuplot.h: static void ns3::Gnuplot3dDataset::SetDefaultStyle(std::string const & style) [member function]
+    cls.add_method('SetDefaultStyle', 
+                   'void', 
+                   [param('std::string const &', 'style')], 
+                   is_static=True)
+    ## gnuplot.h: void ns3::Gnuplot3dDataset::SetStyle(std::string const & style) [member function]
+    cls.add_method('SetStyle', 
+                   'void', 
+                   [param('std::string const &', 'style')])
+    ## gnuplot.h: void ns3::Gnuplot3dDataset::Add(double x, double y, double z) [member function]
+    cls.add_method('Add', 
+                   'void', 
+                   [param('double', 'x'), param('double', 'y'), param('double', 'z')])
+    ## gnuplot.h: void ns3::Gnuplot3dDataset::AddEmptyLine() [member function]
+    cls.add_method('AddEmptyLine', 
+                   'void', 
+                   [])
+    return
+
+def register_Ns3Gnuplot3dFunction_methods(root_module, cls):
+    ## gnuplot.h: ns3::Gnuplot3dFunction::Gnuplot3dFunction(ns3::Gnuplot3dFunction const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Gnuplot3dFunction const &', 'arg0')])
+    ## gnuplot.h: ns3::Gnuplot3dFunction::Gnuplot3dFunction(std::string const & title="Untitled", std::string const & function="") [constructor]
+    cls.add_constructor([param('std::string const &', 'title', default_value='"Untitled"'), param('std::string const &', 'function', default_value='""')])
+    ## gnuplot.h: void ns3::Gnuplot3dFunction::SetFunction(std::string const & function) [member function]
+    cls.add_method('SetFunction', 
+                   'void', 
+                   [param('std::string const &', 'function')])
+    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	Sat Jan 03 23:14:32 2009 +0000
+++ b/bindings/python/ns3_module_core.py	Fri Jan 09 11:44:13 2009 +0000
@@ -1906,7 +1906,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')])
@@ -1914,7 +1914,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')])
@@ -2062,7 +2062,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', 
@@ -2082,7 +2082,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_simulator.py	Sat Jan 03 23:14:32 2009 +0000
+++ b/bindings/python/ns3_module_simulator.py	Fri Jan 09 11:44:13 2009 +0000
@@ -45,6 +45,8 @@
     module.add_class('TimeValue', parent=root_module['ns3::AttributeValue'])
     ## wall-clock-synchronizer.h: ns3::WallClockSynchronizer [class]
     module.add_class('WallClockSynchronizer', parent=root_module['ns3::Synchronizer'])
+    ## calendar-scheduler.h: ns3::CalendarScheduler [class]
+    module.add_class('CalendarScheduler', parent=root_module['ns3::Scheduler'])
     ## default-simulator-impl.h: ns3::DefaultSimulatorImpl [class]
     module.add_class('DefaultSimulatorImpl', parent=root_module['ns3::SimulatorImpl'])
     ## heap-scheduler.h: ns3::HeapScheduler [class]
@@ -120,6 +122,7 @@
     register_Ns3TimeChecker_methods(root_module, root_module['ns3::TimeChecker'])
     register_Ns3TimeValue_methods(root_module, root_module['ns3::TimeValue'])
     register_Ns3WallClockSynchronizer_methods(root_module, root_module['ns3::WallClockSynchronizer'])
+    register_Ns3CalendarScheduler_methods(root_module, root_module['ns3::CalendarScheduler'])
     register_Ns3DefaultSimulatorImpl_methods(root_module, root_module['ns3::DefaultSimulatorImpl'])
     register_Ns3HeapScheduler_methods(root_module, root_module['ns3::HeapScheduler'])
     register_Ns3ListScheduler_methods(root_module, root_module['ns3::ListScheduler'])
@@ -1066,6 +1069,43 @@
                    visibility='protected')
     return
 
+def register_Ns3CalendarScheduler_methods(root_module, cls):
+    ## calendar-scheduler.h: ns3::CalendarScheduler::CalendarScheduler(ns3::CalendarScheduler const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::CalendarScheduler const &', 'arg0')])
+    ## calendar-scheduler.h: static ns3::TypeId ns3::CalendarScheduler::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## calendar-scheduler.h: ns3::CalendarScheduler::CalendarScheduler() [constructor]
+    cls.add_constructor([])
+    ## calendar-scheduler.h: void ns3::CalendarScheduler::Insert(ns3::Scheduler::Event const & ev) [member function]
+    cls.add_method('Insert', 
+                   'void', 
+                   [param('ns3::Scheduler::Event const &', 'ev')], 
+                   is_virtual=True)
+    ## calendar-scheduler.h: bool ns3::CalendarScheduler::IsEmpty() const [member function]
+    cls.add_method('IsEmpty', 
+                   'bool', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## calendar-scheduler.h: ns3::Scheduler::Event ns3::CalendarScheduler::PeekNext() const [member function]
+    cls.add_method('PeekNext', 
+                   'ns3::Scheduler::Event', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## calendar-scheduler.h: ns3::Scheduler::Event ns3::CalendarScheduler::RemoveNext() [member function]
+    cls.add_method('RemoveNext', 
+                   'ns3::Scheduler::Event', 
+                   [], 
+                   is_virtual=True)
+    ## calendar-scheduler.h: void ns3::CalendarScheduler::Remove(ns3::Scheduler::Event const & ev) [member function]
+    cls.add_method('Remove', 
+                   'void', 
+                   [param('ns3::Scheduler::Event const &', 'ev')], 
+                   is_virtual=True)
+    return
+
 def register_Ns3DefaultSimulatorImpl_methods(root_module, cls):
     ## default-simulator-impl.h: ns3::DefaultSimulatorImpl::DefaultSimulatorImpl(ns3::DefaultSimulatorImpl const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::DefaultSimulatorImpl const &', 'arg0')])
@@ -1166,6 +1206,11 @@
 def register_Ns3HeapScheduler_methods(root_module, cls):
     ## heap-scheduler.h: ns3::HeapScheduler::HeapScheduler(ns3::HeapScheduler const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::HeapScheduler const &', 'arg0')])
+    ## heap-scheduler.h: static ns3::TypeId ns3::HeapScheduler::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
     ## heap-scheduler.h: ns3::HeapScheduler::HeapScheduler() [constructor]
     cls.add_constructor([])
     ## heap-scheduler.h: void ns3::HeapScheduler::Insert(ns3::Scheduler::Event const & ev) [member function]
@@ -1198,6 +1243,11 @@
 def register_Ns3ListScheduler_methods(root_module, cls):
     ## list-scheduler.h: ns3::ListScheduler::ListScheduler(ns3::ListScheduler const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::ListScheduler const &', 'arg0')])
+    ## list-scheduler.h: static ns3::TypeId ns3::ListScheduler::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
     ## list-scheduler.h: ns3::ListScheduler::ListScheduler() [constructor]
     cls.add_constructor([])
     ## list-scheduler.h: void ns3::ListScheduler::Insert(ns3::Scheduler::Event const & ev) [member function]
@@ -1230,6 +1280,11 @@
 def register_Ns3MapScheduler_methods(root_module, cls):
     ## map-scheduler.h: ns3::MapScheduler::MapScheduler(ns3::MapScheduler const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::MapScheduler const &', 'arg0')])
+    ## map-scheduler.h: static ns3::TypeId ns3::MapScheduler::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
     ## map-scheduler.h: ns3::MapScheduler::MapScheduler() [constructor]
     cls.add_constructor([])
     ## map-scheduler.h: void ns3::MapScheduler::Insert(ns3::Scheduler::Event const & ev) [member function]
--- a/bindings/python/ns3_module_wifi.py	Sat Jan 03 23:14:32 2009 +0000
+++ b/bindings/python/ns3_module_wifi.py	Fri Jan 09 11:44:13 2009 +0000
@@ -51,6 +51,8 @@
     module.add_class('SsidChecker', parent=root_module['ns3::AttributeChecker'])
     ## ssid.h: ns3::SsidValue [class]
     module.add_class('SsidValue', parent=root_module['ns3::AttributeValue'])
+    ## propagation-loss-model.h: ns3::ThreeLogDistancePropagationLossModel [class]
+    module.add_class('ThreeLogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## wifi-mac.h: ns3::WifiMac [class]
     module.add_class('WifiMac', parent=root_module['ns3::Object'])
     ## wifi-mode.h: ns3::WifiModeChecker [class]
@@ -99,6 +101,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-error-rate-model.h: ns3::YansErrorRateModel [class]
+    module.add_class('YansErrorRateModel', parent=root_module['ns3::ErrorRateModel'])
     ## yans-wifi-channel.h: ns3::YansWifiChannel [class]
     module.add_class('YansWifiChannel', parent=root_module['ns3::WifiChannel'])
     ## aarf-wifi-manager.h: ns3::AarfWifiManager [class]
@@ -166,6 +170,7 @@
     register_Ns3RraaWifiRemoteStation_methods(root_module, root_module['ns3::RraaWifiRemoteStation'])
     register_Ns3SsidChecker_methods(root_module, root_module['ns3::SsidChecker'])
     register_Ns3SsidValue_methods(root_module, root_module['ns3::SsidValue'])
+    register_Ns3ThreeLogDistancePropagationLossModel_methods(root_module, root_module['ns3::ThreeLogDistancePropagationLossModel'])
     register_Ns3WifiMac_methods(root_module, root_module['ns3::WifiMac'])
     register_Ns3WifiModeChecker_methods(root_module, root_module['ns3::WifiModeChecker'])
     register_Ns3WifiModeValue_methods(root_module, root_module['ns3::WifiModeValue'])
@@ -189,6 +194,7 @@
     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_Ns3YansErrorRateModel_methods(root_module, root_module['ns3::YansErrorRateModel'])
     register_Ns3YansWifiChannel_methods(root_module, root_module['ns3::YansWifiChannel'])
     register_Ns3AarfWifiManager_methods(root_module, root_module['ns3::AarfWifiManager'])
     return
@@ -1015,15 +1021,15 @@
     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', 
+    ## propagation-loss-model.h: double ns3::PropagationLossModel::CalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('CalcRxPower', 
                    'double', 
-                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
                    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', 
+    ## propagation-loss-model.h: double ns3::PropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
                    'double', 
-                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   [param('double', 'txPowerDbm'), 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
 
@@ -1052,10 +1058,10 @@
                    is_static=True)
     ## propagation-loss-model.h: ns3::RandomPropagationLossModel::RandomPropagationLossModel() [constructor]
     cls.add_constructor([])
-    ## 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', 
+    ## propagation-loss-model.h: double ns3::RandomPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
                    'double', 
-                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
                    is_const=True, visibility='private', is_virtual=True)
     return
 
@@ -1161,6 +1167,21 @@
                    is_virtual=True)
     return
 
+def register_Ns3ThreeLogDistancePropagationLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::ThreeLogDistancePropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-loss-model.h: ns3::ThreeLogDistancePropagationLossModel::ThreeLogDistancePropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: double ns3::ThreeLogDistancePropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
 def register_Ns3WifiMac_methods(root_module, cls):
     ## wifi-mac.h: ns3::WifiMac::WifiMac(ns3::WifiMac const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::WifiMac const &', 'arg0')])
@@ -1358,22 +1379,6 @@
     return
 
 def register_Ns3WifiPhy_methods(root_module, cls):
-    ## 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]
@@ -1483,6 +1488,46 @@
                    'ns3::Ptr< ns3::WifiChannel >', 
                    [], 
                    is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get6mba() [member function]
+    cls.add_method('Get6mba', 
+                   'ns3::WifiMode', 
+                   [], 
+                   is_static=True)
+    ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get9mba() [member function]
+    cls.add_method('Get9mba', 
+                   'ns3::WifiMode', 
+                   [], 
+                   is_static=True)
+    ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get12mba() [member function]
+    cls.add_method('Get12mba', 
+                   'ns3::WifiMode', 
+                   [], 
+                   is_static=True)
+    ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get18mba() [member function]
+    cls.add_method('Get18mba', 
+                   'ns3::WifiMode', 
+                   [], 
+                   is_static=True)
+    ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get24mba() [member function]
+    cls.add_method('Get24mba', 
+                   'ns3::WifiMode', 
+                   [], 
+                   is_static=True)
+    ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get36mba() [member function]
+    cls.add_method('Get36mba', 
+                   'ns3::WifiMode', 
+                   [], 
+                   is_static=True)
+    ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get48mba() [member function]
+    cls.add_method('Get48mba', 
+                   'ns3::WifiMode', 
+                   [], 
+                   is_static=True)
+    ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get54mba() [member function]
+    cls.add_method('Get54mba', 
+                   'ns3::WifiMode', 
+                   [], 
+                   is_static=True)
     return
 
 def register_Ns3WifiRemoteStationManager_methods(root_module, cls):
@@ -2051,13 +2096,13 @@
 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: ns3::ErrorRateModel::ErrorRateModel() [constructor]
+    cls.add_constructor([])
     ## 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', 
@@ -2067,7 +2112,7 @@
     cls.add_method('GetChunkSuccessRate', 
                    'double', 
                    [param('ns3::WifiMode', 'mode'), param('double', 'snr'), param('uint32_t', 'nbits')], 
-                   is_const=True)
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
     return
 
 def register_Ns3FriisPropagationLossModel_methods(root_module, cls):
@@ -2109,10 +2154,10 @@
                    'double', 
                    [], 
                    is_const=True)
-    ## 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', 
+    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
                    'double', 
-                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
                    is_const=True, visibility='private', is_virtual=True)
     return
 
@@ -2163,10 +2208,10 @@
     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', 
+    ## jakes-propagation-loss-model.h: double ns3::JakesPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
                    'double', 
-                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
                    is_const=True, visibility='private', is_virtual=True)
     return
 
@@ -2191,10 +2236,10 @@
     cls.add_method('SetReference', 
                    'void', 
                    [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', 
+    ## propagation-loss-model.h: double ns3::LogDistancePropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
                    'double', 
-                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
                    is_const=True, visibility='private', is_virtual=True)
     return
 
@@ -2736,6 +2781,23 @@
                    visibility='private', is_virtual=True)
     return
 
+def register_Ns3YansErrorRateModel_methods(root_module, cls):
+    ## yans-error-rate-model.h: ns3::YansErrorRateModel::YansErrorRateModel(ns3::YansErrorRateModel const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::YansErrorRateModel const &', 'arg0')])
+    ## yans-error-rate-model.h: static ns3::TypeId ns3::YansErrorRateModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## yans-error-rate-model.h: ns3::YansErrorRateModel::YansErrorRateModel() [constructor]
+    cls.add_constructor([])
+    ## yans-error-rate-model.h: double ns3::YansErrorRateModel::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, 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')])
--- a/doc/doxygen.conf	Sat Jan 03 23:14:32 2009 +0000
+++ b/doc/doxygen.conf	Fri Jan 09 11:44:13 2009 +0000
@@ -846,7 +846,7 @@
 # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
 # packages that should be included in the LaTeX output.
 
-EXTRA_PACKAGES         = 
+EXTRA_PACKAGES         = amsmath
 
 # The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
 # the generated latex document. The header should contain everything until 
--- a/examples/mixed-wireless.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/examples/mixed-wireless.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -47,12 +47,19 @@
 //                   |                                        |
 //          +----------------+                       +----------------+
 //          |     802.11     |                       |     802.11     |
-//          |      net       |                       |       net      |
+//          |   infra net    |                       |   infra net    |
 //          |   K-1 hosts    |                       |   K-1 hosts    |
 //          +----------------+                       +----------------+
 //
+// We'll send data from the first wired LAN node on the first wired LAN
+// to the last wireless STA on the last infrastructure net, thereby
+// causing packets to traverse CSMA to adhoc to infrastructure links
+// 
+// Note that certain mobility patterns may cause packet forwarding
+// to fail (if nodes become disconnected) 
 
 #include <fstream>
+#include <string>
 #include "ns3/core-module.h"
 #include "ns3/common-module.h"
 #include "ns3/node-module.h"
@@ -60,6 +67,7 @@
 #include "ns3/mobility-module.h"
 #include "ns3/contrib-module.h"
 #include "ns3/wifi-module.h"
+#include "ns3/global-route-manager.h"
 
 using namespace ns3;
 
@@ -69,16 +77,15 @@
 NS_LOG_COMPONENT_DEFINE ("MixedWireless");
 
 //
-// This function will be used below as a trace sink
+// This function will be used below as a trace sink, if the command-line
+// argument or default value "useCourseChangeCallback" is set to true
 // 
-#ifdef ENABLE_FOR_TRACING_EXAMPLE
 static void
 CourseChangeCallback (std::string path, Ptr<const MobilityModel> model)
 {
   Vector position = model->GetPosition ();
   std::cout << "CourseChange " << path << " x=" << position.x << ", y=" << position.y << ", z=" << position.z << std::endl;
 }
-#endif
 
 int 
 main (int argc, char *argv[])
@@ -91,13 +98,15 @@
   uint32_t infraNodes = 5;
   uint32_t lanNodes = 5;
   uint32_t stopTime = 10;
+  bool useCourseChangeCallback = false;
+  bool enableTracing = false;
 
   //
   // Simulation defaults are typically set next, before command line
   // arguments are parsed.
   //
   Config::SetDefault ("ns3::OnOffApplication::PacketSize", StringValue ("210"));
-  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("448kb/s"));
+  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("10kb/s"));
 
   //
   // For convenience, we add the local variables to the command line argument
@@ -109,6 +118,8 @@
   cmd.AddValue ("infraNodes", "number of leaf nodes", infraNodes);
   cmd.AddValue("lanNodes", "number of LAN nodes", lanNodes);
   cmd.AddValue("stopTime", "simulation stop time (seconds)", stopTime);
+  cmd.AddValue("useCourseChangeCallback", "whether to enable course change tracing", useCourseChangeCallback);
+  cmd.AddValue("enableTracing", "enable tracing", enableTracing);
 
   //
   // The system global variables and the local values added to the argument
@@ -132,11 +143,13 @@
   // Create the backbone wifi net devices and install them into the nodes in 
   // our container
   //
+  WifiHelper wifi;
+  wifi.SetMac ("ns3::AdhocWifiMac");
+  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
+                                "DataMode", StringValue ("wifia-54mbs"));
   YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
   YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
   wifiPhy.SetChannel (wifiChannel.Create ());
-  WifiHelper wifi;
-  wifi.SetMac ("ns3::AdhocWifiMac");
   NetDeviceContainer backboneDevices = wifi.Install (wifiPhy, backbone);
   //
   // Add the IPv4 protocol stack to the nodes in our container
@@ -166,8 +179,8 @@
     }
   mobility.SetPositionAllocator (positionAlloc);
   mobility.SetMobilityModel ("ns3::RandomDirection2dMobilityModel",
-                             "Bounds", RectangleValue (Rectangle (0, 1000, 0, 1000)),
-                             "Speed", RandomVariableValue (ConstantVariable (2000)),
+                             "Bounds", RectangleValue (Rectangle (0, 20, 0, 20)),
+                             "Speed", RandomVariableValue (ConstantVariable (2)),
                              "Pause", RandomVariableValue (ConstantVariable (0.2)));
   mobility.Install (backbone);
 
@@ -237,21 +250,38 @@
       // two containers here; one with all of the new nodes, and one
       // with all of the nodes including new and existing nodes
       //
-      NodeContainer newInfraNodes;
-      newInfraNodes.Create (infraNodes - 1);
+      NodeContainer stas;
+      stas.Create (infraNodes - 1);
       // Now, create the container with all nodes on this link
-      NodeContainer infra (backbone.Get (i), newInfraNodes);
+      NodeContainer infra (backbone.Get (i), stas);
+      //
+      // Create an infrastructure network
       //
-      // Create another ad hoc network and devices
-      //
-      WifiHelper wifiInfra;
-      wifiInfra.SetMac ("ns3::AdhocWifiMac");
+      WifiHelper wifiInfra = WifiHelper::Default ();
       wifiPhy.SetChannel (wifiChannel.Create ());
-      NetDeviceContainer infraDevices = wifiInfra.Install (wifiPhy, infra);
+      // Create unique ssids for these networks
+      std::string ssidString("wifi-infra");
+      std::stringstream ss;
+      ss << i;
+      ssidString += ss.str();
+      Ssid ssid = Ssid (ssidString);
+      wifiInfra.SetRemoteStationManager ("ns3::ArfWifiManager");
+      // setup stas
+      wifiInfra.SetMac ("ns3::NqstaWifiMac",
+               "Ssid", SsidValue (ssid),
+               "ActiveProbing", BooleanValue (false));
+      NetDeviceContainer staDevices = wifiInfra.Install (wifiPhy, stas);
+      // setup ap.
+      wifiInfra.SetMac ("ns3::NqapWifiMac", "Ssid", SsidValue (ssid),
+               "BeaconGeneration", BooleanValue (true),
+               "BeaconInterval", TimeValue (Seconds (2.5)));
+      NetDeviceContainer apDevices = wifiInfra.Install (wifiPhy, backbone.Get (i));
+      // Collect all of these new devices
+      NetDeviceContainer infraDevices (apDevices, staDevices);
 
       // Add the IPv4 protocol stack to the nodes in our container
       //
-      internet.Install (newInfraNodes);
+      internet.Install (stas);
       //
       // Assign IPv4 addresses to the device drivers (actually to the associated
       // IPv4 interfaces) we just created.
@@ -275,8 +305,8 @@
       mobility.PushReferenceMobilityModel (backbone.Get (i));
       mobility.SetPositionAllocator (subnetAlloc);
       mobility.SetMobilityModel ("ns3::RandomDirection2dMobilityModel",
-                                 "Bounds", RectangleValue (Rectangle (-25, 25, -25, 25)),
-                                 "Speed", RandomVariableValue (ConstantVariable (30)),
+                                 "Bounds", RectangleValue (Rectangle (-10, 10, -10, 10)),
+                                 "Speed", RandomVariableValue (ConstantVariable (3)),
                                  "Pause", RandomVariableValue (ConstantVariable (0.4)));
       mobility.Install (infra);
     }
@@ -286,6 +316,14 @@
   //                                                                       //
   /////////////////////////////////////////////////////////////////////////// 
 
+  // The below global routing does not take into account wireless effects.
+  // However, it is useful for setting default routes for all of the nodes
+  // such as the LAN nodes.  
+  NS_LOG_INFO ("Enabling global routing on all nodes");
+  GlobalRouteManager::PopulateRoutingTables ();
+
+  // We enable OLSR (which will be consulted at a higher priority than
+  // the global routing above) on the backbone ad hoc nodes
   NS_LOG_INFO ("Enabling OLSR routing on all backbone nodes");
   OlsrHelper olsr;
   olsr.Install (backbone);
@@ -297,16 +335,25 @@
   /////////////////////////////////////////////////////////////////////////// 
 
   // Create the OnOff application to send UDP datagrams of size
-  // 210 bytes at a rate of 448 Kb/s, between two nodes
+  // 210 bytes at a rate of 10 Kb/s, between two nodes
+  // We'll send data from the first wired LAN node on the first wired LAN
+  // to the last wireless STA on the last infrastructure net, thereby
+  // causing packets to traverse CSMA to adhoc to infrastructure links
+
   NS_LOG_INFO ("Create Applications.");
   uint16_t port = 9;   // Discard port (RFC 863)
 
-  // Let's make sure that the user does not define too few LAN nodes
-  // to make this example work.  We need lanNodes >= 5
-  NS_ASSERT (lanNodes >= 5);
-  Ptr<Node> appSource = NodeList::GetNode (11);  
-  Ptr<Node> appSink = NodeList::GetNode (13);  
-  Ipv4Address remoteAddr = Ipv4Address ("172.16.0.5");
+  // Let's make sure that the user does not define too few nodes
+  // to make this example work.  We need lanNodes > 1  and infraNodes > 1
+  NS_ASSERT (lanNodes > 1 && infraNodes > 1);
+  // We want the source to be the first node created outside of the backbone
+  // Conveniently, the variable "backboneNodes" holds this node index value
+  Ptr<Node> appSource = NodeList::GetNode (backboneNodes);  
+  // We want the sink to be the last node created in the topology.  
+  uint32_t lastNodeIndex = backboneNodes + backboneNodes*(lanNodes - 1) + backboneNodes*(infraNodes - 1) - 1;
+  Ptr<Node> appSink = NodeList::GetNode (lastNodeIndex);  
+  // Let's fetch the IP address of the last node, which is on Ipv4Interface 1
+  Ipv4Address remoteAddr = appSink->GetObject<Ipv4> ()->GetAddress(1);
 
   OnOffHelper onoff ("ns3::UdpSocketFactory", 
                      Address (InetSocketAddress (remoteAddr, port)));
@@ -329,27 +376,28 @@
   /////////////////////////////////////////////////////////////////////////// 
 
   NS_LOG_INFO ("Configure Tracing.");
-  //
-  // Let's set up some ns-2-like ascii traces, using another helper class
-  //
   std::ofstream ascii;
-  ascii.open ("mixed-wireless.tr");
-  YansWifiPhyHelper::EnableAsciiAll (ascii);
-  CsmaHelper::EnableAsciiAll (ascii);
-  // Look at nodes 11, 13 only
-  //WifiHelper::EnableAscii (ascii, 11, 0); 
-  //WifiHelper::EnableAscii (ascii, 13, 0); 
+  if (enableTracing == true)
+   {
+      //
+      // Let's set up some ns-2-like ascii traces, using another helper class
+      //
+      ascii.open ("mixed-wireless.tr");
+      YansWifiPhyHelper::EnableAsciiAll (ascii);
+      CsmaHelper::EnableAsciiAll (ascii);
+      InternetStackHelper::EnableAsciiAll (ascii);
 
-  // Let's do a pcap trace on the backbone devices
-  YansWifiPhyHelper::EnablePcap ("mixed-wireless", backboneDevices); 
-  // Let's additionally trace the application Sink, ifIndex 0
-  CsmaHelper::EnablePcap ("mixed-wireless", appSink->GetId (), 0);
+      // Let's do a pcap trace on the application source and sink, ifIndex 0
+      CsmaHelper::EnablePcap ("mixed-wireless", appSource->GetId (), 0);
+      YansWifiPhyHelper::EnablePcap ("mixed-wireless", appSink->GetId (), 0);
+      YansWifiPhyHelper::EnablePcap ("mixed-wireless", 9, 2);
+      YansWifiPhyHelper::EnablePcap ("mixed-wireless", 9, 0);
+    }
 
-#ifdef ENABLE_FOR_TRACING_EXAMPLE
-  Config::Connect ("/NodeList/*/$MobilityModel/CourseChange",
-    MakeCallback (&CourseChangeCallback));
-#endif
-
+  if (useCourseChangeCallback == true)
+    {
+      Config::Connect ("/NodeList/*/$ns3::MobilityModel/CourseChange", MakeCallback (&CourseChangeCallback));
+    }
 
   /////////////////////////////////////////////////////////////////////////// 
   //                                                                       //
--- a/examples/wifi-adhoc.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/examples/wifi-adhoc.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -36,7 +36,7 @@
 public:
   Experiment ();
   Experiment (std::string name);
-  GnuplotDataset Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy, const YansWifiChannelHelper &wifiChannel);
+  Gnuplot2dDataset Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy, const YansWifiChannelHelper &wifiChannel);
 private:
   void ReceivePacket (Ptr<Socket> socket);
   void SetPosition (Ptr<Node> node, Vector position);
@@ -45,17 +45,16 @@
   Ptr<Socket> SetupPacketReceive (Ptr<Node> node);
 
   uint32_t m_bytesTotal;
-  GnuplotDataset m_output;
+  Gnuplot2dDataset m_output;
 };
 
 Experiment::Experiment ()
-  : m_output ()
 {}
 
 Experiment::Experiment (std::string name)
   : m_output (name)
 {
-  m_output.SetStyle (GnuplotDataset::LINES);
+  m_output.SetStyle (Gnuplot2dDataset::LINES);
 }
 
 void
@@ -109,7 +108,7 @@
   return sink;
 }
 
-GnuplotDataset
+Gnuplot2dDataset
 Experiment::Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy, const YansWifiChannelHelper &wifiChannel)
 {
   m_bytesTotal = 0;
@@ -173,7 +172,7 @@
   WifiHelper wifi = WifiHelper::Default ();
   YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
   YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
-  GnuplotDataset dataset;
+  Gnuplot2dDataset dataset;
 
   wifi.SetMac ("ns3::AdhocWifiMac");
 
--- a/samples/main-propagation-loss.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/samples/main-propagation-loss.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -40,7 +40,7 @@
       std::cout << x << " ";
       for (double txpower = minTxpower; txpower < maxTxpower; txpower += stepTxpower)
         {
-          double rxPowerDbm = txpower + model->GetLoss (a, b);
+          double rxPowerDbm = model->CalcRxPower (txpower, a, b);
           std::cout << rxPowerDbm << " ";
         }
       std::cout << std::endl;
--- a/src/contrib/gnuplot.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/contrib/gnuplot.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2007 INRIA
+ * Copyright (c) 2007 INRIA, 2008 Timo Bingmann
  *
  * 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
@@ -15,178 +15,719 @@
  * 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>
+ * Original Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Enhancements: Timo Bingmann <timo.bingmann@student.kit.edu>
  */
 #include "gnuplot.h"
 #include "ns3/assert.h"
 #include <ostream>
+#include <stdexcept>
 
 namespace ns3 {
 
-GnuplotDataset::GnuplotDataset ()
-  : m_title ("untitled"),
-    m_style (LINES),
-    m_errorBars (NONE)
-{}
+// --- GnuplotDataset::Data ------------------------------------------------ //
+
+struct GnuplotDataset::Data
+{
+  // *** Data Variables ***
+
+  unsigned int m_references;
+
+  std::string m_title;
+  std::string m_extra;
+
+  /**
+   * Initializes the reference counter to 1 and sets m_title and m_extra.
+   */
+  Data(const std::string& title);
+
+  /// Required.
+  virtual ~Data();
+
+  /**
+   * Returns "plot" or "splot".
+   */
+  virtual std::string GetCommand() const = 0;
+
+  /**
+   * Prints the plot description used as argument to (s)plot. Either the
+   * function expression or a datafile description. Should include m_title and
+   * m_extra in the output.
+   */
+  virtual void PrintExpression(std::ostream &os) const = 0;
+    
+  /**
+   * Print the inline data file contents trailing the plot command. Empty for
+   * functions.
+   */
+  virtual void PrintDatafile(std::ostream &os) const = 0;
+};
+
+GnuplotDataset::Data::Data(const std::string& title)
+  : m_references(1),
+    m_title(title),
+    m_extra(m_defaultExtra)
+{
+}
+
+GnuplotDataset::Data::~Data()
+{
+}
+
+// --- GnuplotDataset ------------------------------------------------------ //
+
+std::string GnuplotDataset::m_defaultExtra = "";
+
+GnuplotDataset::GnuplotDataset (struct Data* data)
+  : m_data(data)
+{
+}
+
+GnuplotDataset::GnuplotDataset (const GnuplotDataset& original)
+  : m_data(original.m_data)
+{
+  ++m_data->m_references;
+}
+
+GnuplotDataset::~GnuplotDataset()
+{
+  if (--m_data->m_references == 0)
+    delete m_data;
+}
+
+GnuplotDataset& GnuplotDataset::operator= (const GnuplotDataset& original)
+{
+  if (this != &original)
+    {
+      if (--m_data->m_references == 0)
+        delete m_data;
+
+      m_data = original.m_data;
+      ++m_data->m_references;
+    }
+  return *this;
+}
+
+void
+GnuplotDataset::SetTitle (const std::string& title)
+{
+  m_data->m_title = title;
+}
+
+void
+GnuplotDataset::SetDefaultExtra (const std::string& extra)
+{
+  m_defaultExtra = extra;
+}
+void
+GnuplotDataset::SetExtra (const std::string& extra)
+{
+  m_data->m_extra = extra;
+}
+
+// --- Gnuplot2dDataset::Data2d -------------------------------------------- //
+
+struct Gnuplot2dDataset::Data2d : public GnuplotDataset::Data
+{
+  // *** Data Variables ***
+    
+  enum Style  m_style;
+  enum ErrorBars m_errorBars;
+
+  PointSet    m_pointset;
+
+  /**
+   * Initializes with the values from m_defaultStyle and m_defaultErrorBars.
+   */
+  Data2d(const std::string& title);
+
+  virtual std::string GetCommand() const;
+  virtual void PrintExpression(std::ostream &os) const;
+  virtual void PrintDatafile(std::ostream &os) const;
+};
+
+Gnuplot2dDataset::Data2d::Data2d(const std::string& title)
+  : Data(title),
+    m_style(m_defaultStyle),
+    m_errorBars(m_defaultErrorBars)
+{
+}
 
-GnuplotDataset::GnuplotDataset (std::string title)
-  : m_title (title),
-    m_style (LINES),
-    m_errorBars (NONE)
-{}
+std::string
+Gnuplot2dDataset::Data2d::GetCommand() const
+{
+  return "plot";
+}
+
+void
+Gnuplot2dDataset::Data2d::PrintExpression(std::ostream &os) const
+{
+  os << "'-' ";
+
+  if (m_title.size())
+    os << " title '" << m_title << "'";
+
+  switch (m_style) {
+  case LINES:
+    os << " with lines";
+    break;
+  case POINTS:
+    switch (m_errorBars)
+      {
+      case NONE:
+        os << " with points";
+        break;
+      case X:
+        os << " with xerrorbars";
+        break;
+      case Y:
+        os << " with yerrorbars";
+        break;
+      case XY:
+        os << " with xyerrorbars";
+        break;
+      }
+    break;
+  case LINES_POINTS:
+    switch (m_errorBars)
+      {
+      case NONE:
+        os << " with linespoints";
+        break;
+      case X:
+        os << " with errorlines";
+        break;
+      case Y:
+        os << " with yerrorlines";
+        break;
+      case XY:
+        os << " with xyerrorlines";
+        break;
+      }
+    break;
+  case DOTS:
+    os << " with dots";
+    break;
+  case IMPULSES:
+    os << " with impulses";
+    break;
+  case STEPS:
+    os << " with steps";
+    break;
+  case FSTEPS:
+    os << " with fsteps";
+    break;
+  case HISTEPS:
+    os << " with histeps";
+    break;
+  }
+
+  if (m_extra.size())
+    os << " " << m_extra;
+}
+
+void
+Gnuplot2dDataset::Data2d::PrintDatafile(std::ostream &os) const
+{
+  for (PointSet::const_iterator i = m_pointset.begin ();
+       i != m_pointset.end (); ++i)
+    {
+      if (i->empty) {
+        os << std::endl;
+        continue;
+      }
+
+      switch (m_errorBars) {
+      case NONE:
+        os << i->x << " " << i->y << std::endl;
+        break;
+      case X:
+        os << i->x << " " << i->y << " " << i->dx << std::endl;
+        break;
+      case Y:
+        os << i->x << " " << i->y << " " << i->dy << std::endl;
+        break;
+      case XY:
+        os << i->x << " " << i->y << " " << i->dx << " " << i->dy << std::endl;
+        break;
+      }
+    }
+  os << "e" << std::endl;
+}
+
+// --- Gnuplot2dDataset ---------------------------------------------------- //
+
+enum Gnuplot2dDataset::Style Gnuplot2dDataset::m_defaultStyle = LINES;
+enum Gnuplot2dDataset::ErrorBars Gnuplot2dDataset::m_defaultErrorBars = NONE;
+
+Gnuplot2dDataset::Gnuplot2dDataset (const std::string& title)
+  : GnuplotDataset( new Data2d(title) )
+{
+}
+
+void
+Gnuplot2dDataset::SetDefaultStyle (enum Style style)
+{
+  m_defaultStyle = style;
+}
+void
+Gnuplot2dDataset::SetStyle (enum Style style)
+{
+  reinterpret_cast<Data2d*>(m_data)->m_style = style;
+}
+
+void
+Gnuplot2dDataset::SetDefaultErrorBars (enum ErrorBars errorBars)
+{
+  m_defaultErrorBars = errorBars;
+}
+void
+Gnuplot2dDataset::SetErrorBars (enum ErrorBars errorBars)
+{
+  reinterpret_cast<Data2d*>(m_data)->m_errorBars = errorBars;
+}
+
 void 
-GnuplotDataset::SetStyle (enum Style style)
-{
-  m_style = style;
-}
-void 
-GnuplotDataset::SetErrorBars (enum ErrorBars errorBars)
+Gnuplot2dDataset::Add (double x, double y)
 {
-  m_errorBars = errorBars;
-}
-void 
-GnuplotDataset::Add (double x, double y)
-{
-  NS_ASSERT (m_errorBars == NONE);
-  struct Data data;
+  NS_ASSERT (reinterpret_cast<Data2d*>(m_data)->m_errorBars == NONE);
+
+  struct Point data;
+  data.empty = false;
   data.x = x;
   data.y = y;
   data.dx = 0.0;
   data.dy = 0.0;
-  m_dataset.push_back (data);
+  reinterpret_cast<Data2d*>(m_data)->m_pointset.push_back (data);
 }
+
 void 
-GnuplotDataset::Add (double x, double y, double errorDelta)
+Gnuplot2dDataset::Add (double x, double y, double errorDelta)
 {
-  NS_ASSERT (m_errorBars == X || m_errorBars == Y);
-  struct Data data;
+  NS_ASSERT ( reinterpret_cast<Data2d*>(m_data)->m_errorBars == X ||
+              reinterpret_cast<Data2d*>(m_data)->m_errorBars == Y );
+
+  struct Point data;
+  data.empty = false;
   data.x = x;
   data.y = y;
   data.dx = errorDelta;
   data.dy = errorDelta;
-  m_dataset.push_back (data);
-}
-
-Gnuplot::Gnuplot (std::string pngFilename)
-  : m_pngFilename (pngFilename)
-{}
-
-Gnuplot::~Gnuplot ()
-{
-  for (Datasets::const_iterator i = m_datasets.begin (); i != m_datasets.end (); i++)
-    {
-      delete *i;
-    }
-  m_datasets.clear ();
+  reinterpret_cast<Data2d*>(m_data)->m_pointset.push_back (data);
 }
 
 void 
-Gnuplot::SetLegend (std::string xLegend, std::string yLegend)
+Gnuplot2dDataset::Add (double x, double y, double minY, double maxY)
+{
+  NS_ASSERT ( reinterpret_cast<Data2d*>(m_data)->m_errorBars == X ||
+              reinterpret_cast<Data2d*>(m_data)->m_errorBars == Y );
+
+  struct Point data;
+  data.empty = false;
+  data.x = x;
+  data.y = y;
+  data.dx = minY;
+  data.dy = maxY;
+  reinterpret_cast<Data2d*>(m_data)->m_pointset.push_back (data);
+}
+
+void
+Gnuplot2dDataset::AddEmptyLine()
+{
+  struct Point data;
+  data.empty = true;
+  reinterpret_cast<Data2d*>(m_data)->m_pointset.push_back (data);
+}
+
+// --- Gnuplot2dFunction::Function2d --------------------------------------- //
+
+struct Gnuplot2dFunction::Function2d : public GnuplotDataset::Data
+{
+  // *** Data Variables ***
+
+  std::string m_function;
+
+  /**
+   * Initializes with the function and title.
+   */
+  Function2d(const std::string& title, const std::string& function);
+
+  virtual std::string GetCommand() const;
+  virtual void PrintExpression(std::ostream &os) const;
+  virtual void PrintDatafile(std::ostream &os) const;
+};
+
+Gnuplot2dFunction::Function2d::Function2d(const std::string& title, const std::string& function)
+  : Data(title),
+    m_function(function)
+{
+}
+
+std::string
+Gnuplot2dFunction::Function2d::GetCommand() const
+{
+  return "plot";
+}
+
+void
+Gnuplot2dFunction::Function2d::PrintExpression(std::ostream &os) const
+{
+  os << m_function;
+
+  if (m_title.size())
+    os << " title '" << m_title << "'";
+
+  if (m_extra.size())
+    os << " " << m_extra;
+}
+
+void
+Gnuplot2dFunction::Function2d::PrintDatafile(std::ostream &os) const
+{
+}
+
+// --- Gnuplot2dFunction --------------------------------------------------- //
+
+Gnuplot2dFunction::Gnuplot2dFunction (const std::string& title, const std::string& function)
+  : GnuplotDataset( new Function2d(title, function) )
+{
+}
+
+void
+Gnuplot2dFunction::SetFunction (const std::string& function)
+{
+  reinterpret_cast<Function2d*>(m_data)->m_function = function;
+}
+
+// --- Gnuplot3dDataset::Data3d -------------------------------------------- //
+
+struct Gnuplot3dDataset::Data3d : public GnuplotDataset::Data
+{
+  // *** Data Variables ***
+    
+  std::string   m_style;
+
+  PointSet      m_pointset;
+
+  /**
+   * Initializes with value from m_defaultStyle.
+   */
+  Data3d(const std::string& title);
+
+  virtual std::string GetCommand() const;
+  virtual void PrintExpression(std::ostream &os) const;
+  virtual void PrintDatafile(std::ostream &os) const;
+};
+
+Gnuplot3dDataset::Data3d::Data3d(const std::string& title)
+  : Data(title),
+    m_style(m_defaultStyle)
+{
+}
+
+std::string
+Gnuplot3dDataset::Data3d::GetCommand() const
+{
+  return "splot";
+}
+
+void
+Gnuplot3dDataset::Data3d::PrintExpression(std::ostream &os) const
+{
+  os << "'-' ";
+
+  if (m_style.size())
+    os << " " << m_style;
+
+  if (m_title.size())
+    os << " title '" << m_title << "'";
+
+  if (m_extra.size())
+    os << " " << m_extra;
+}
+
+void
+Gnuplot3dDataset::Data3d::PrintDatafile(std::ostream &os) const
+{
+  for (PointSet::const_iterator i = m_pointset.begin ();
+       i != m_pointset.end (); ++i)
+    {
+      if (i->empty) {
+        os << std::endl;
+        continue;
+      }
+
+      os << i->x << " " << i->y << " " << i->z << std::endl;
+    }
+  os << "e" << std::endl;
+}
+
+// --- Gnuplot3dDataset ---------------------------------------------------- //
+
+std::string Gnuplot3dDataset::m_defaultStyle = "";
+
+Gnuplot3dDataset::Gnuplot3dDataset (const std::string& title)
+  : GnuplotDataset( new Data3d(title) )
+{
+}
+
+void
+Gnuplot3dDataset::SetDefaultStyle (const std::string& style)
+{
+  m_defaultStyle = style;
+}
+void
+Gnuplot3dDataset::SetStyle (const std::string& style)
+{
+  reinterpret_cast<Data3d*>(m_data)->m_style = style;
+}
+
+void 
+Gnuplot3dDataset::Add (double x, double y, double z)
+{
+  struct Point data;
+  data.empty = false;
+  data.x = x;
+  data.y = y;
+  data.z = z;
+  reinterpret_cast<Data3d*>(m_data)->m_pointset.push_back (data);
+}
+
+void
+Gnuplot3dDataset::AddEmptyLine()
+{
+  struct Point data;
+  data.empty = true;
+  reinterpret_cast<Data3d*>(m_data)->m_pointset.push_back (data);
+}
+
+// --- Gnuplot3dFunction::Function3d --------------------------------------- //
+
+struct Gnuplot3dFunction::Function3d : public GnuplotDataset::Data
+{
+  // *** Data Variables ***
+
+  std::string m_function;
+
+  /**
+   * Initializes with the function and title.
+   */
+  Function3d(const std::string& title, const std::string& function);
+
+  virtual std::string GetCommand() const;
+  virtual void PrintExpression(std::ostream &os) const;
+  virtual void PrintDatafile(std::ostream &os) const;
+};
+
+Gnuplot3dFunction::Function3d::Function3d(const std::string& title, const std::string& function)
+  : Data(title),
+    m_function(function)
+{
+}
+
+std::string
+Gnuplot3dFunction::Function3d::GetCommand() const
+{
+  return "splot";
+}
+
+void
+Gnuplot3dFunction::Function3d::PrintExpression(std::ostream &os) const
+{
+  os << m_function;
+
+  if (m_title.size())
+    os << " title '" << m_title << "'";
+
+  if (m_extra.size())
+    os << " " << m_extra;
+}
+
+void
+Gnuplot3dFunction::Function3d::PrintDatafile(std::ostream &os) const
+{
+}
+
+// --- Gnuplot3dFunction --------------------------------------------------- //
+
+Gnuplot3dFunction::Gnuplot3dFunction (const std::string& title, const std::string& function)
+  : GnuplotDataset( new Function3d(title, function) )
+{
+}
+
+void
+Gnuplot3dFunction::SetFunction (const std::string& function)
+{
+  reinterpret_cast<Function3d*>(m_data)->m_function = function;
+}
+
+// ------------------------------------------------------------------------- //
+
+Gnuplot::Gnuplot (const std::string& outputFilename, const std::string& title)
+  : m_outputFilename(outputFilename),
+    m_terminal( DetectTerminal(outputFilename) ),
+    m_title(title)
+{
+}
+
+std::string Gnuplot::DetectTerminal (const std::string& filename)
+{
+  std::string::size_type dotpos = filename.rfind('.');
+  if (dotpos == std::string::npos) return "";
+
+  if (filename.substr(dotpos) == ".png") {
+    return "png";
+  }
+  else if (filename.substr(dotpos) == ".pdf") {
+    return "pdf";
+  }
+
+  return "";
+}
+
+void
+Gnuplot::SetTerminal (const std::string& terminal)
+{
+  m_terminal = terminal;
+}
+
+void
+Gnuplot::SetTitle (const std::string& title)
+{
+  m_title = title;
+}
+
+void 
+Gnuplot::SetLegend (const std::string& xLegend, const std::string& yLegend)
 {
   m_xLegend = xLegend;
   m_yLegend = yLegend;
 }
 
-void 
-Gnuplot::AddDataset (const GnuplotDataset &dataset)
+void
+Gnuplot::SetExtra (const std::string& extra)
 {
-  m_datasets.push_back (new GnuplotDataset (dataset));
+  m_extra = extra;
+}
+
+void
+Gnuplot::AppendExtra (const std::string& extra)
+{
+  m_extra += "\n";
+  m_extra += extra;
 }
 
 void 
-Gnuplot::GenerateOutput (std::ostream &os)
+Gnuplot::AddDataset (const GnuplotDataset& dataset)
+{
+  m_datasets.push_back (dataset);
+}
+
+void
+Gnuplot::GenerateOutput (std::ostream &os) const
 {
-  os << "set terminal png" << std::endl;
-  os << "set output '" << m_pngFilename << "'" << std::endl;
-  os << "set xlabel '" << m_xLegend << "'" << std::endl;
-  os << "set ylabel '" << m_yLegend << "'" << std::endl;
-  os << "plot ";
+  if (m_terminal.size())
+    os << "set terminal " << m_terminal << std::endl;
+
+  if (m_outputFilename.size())
+    os << "set output '" << m_outputFilename << "'" << std::endl;
+
+  if (m_title.size())
+    os << "set title '" << m_title << "'" << std::endl;
+  
+  if (m_xLegend.size())
+    os << "set xlabel '" << m_xLegend << "'" << std::endl;
+
+  if (m_yLegend.size())
+    os << "set ylabel '" << m_yLegend << "'" << std::endl;
+
+  if (m_extra.size())
+    os << m_extra << std::endl;
+
+  if (m_datasets.empty())
+    return;
+
+  // Determine the GetCommand() values of all datasets included. Check that all
+  // are equal and print the command.
+
+  std::string command = m_datasets.begin()->m_data->GetCommand();
+
+  for (Datasets::const_iterator i = m_datasets.begin () + 1;
+       i != m_datasets.end (); ++i)
+    {
+      NS_ASSERT_MSG(command == i->m_data->GetCommand(),
+                    "Cannot mix 'plot' and 'splot' GnuplotDatasets.");
+    }
+
+  os << command << " ";
+
+  // Print all dataset expressions
+
   for (Datasets::const_iterator i = m_datasets.begin (); i != m_datasets.end ();)
     {
-      os << "'-' title '" << (*i)->m_title << "'";
-      switch ((*i)->m_style) {
-      case GnuplotDataset::LINES:
-        os << " with lines";
-	break;
-      case GnuplotDataset::POINTS:
-        switch ((*i)->m_errorBars)
-          {
-          case GnuplotDataset::NONE:
-            os << " with points";
-            break;
-          case GnuplotDataset::X:
-            os << " with xerrorbars";
-            break;
-          case GnuplotDataset::Y:
-            os << " with yerrorbars";
-            break;
-          case GnuplotDataset::XY:
-            os << " with xyerrorbars";
-            break;
-          }
-	break;
-      case GnuplotDataset::LINES_POINTS:
-        switch ((*i)->m_errorBars)
-          {
-          case GnuplotDataset::NONE:
-            os << " with linespoints";
-            break;
-          case GnuplotDataset::X:
-            os << " with xerrorlines";
-            break;
-          case GnuplotDataset::Y:
-            os << " with yerrorlines";
-            break;
-          case GnuplotDataset::XY:
-            os << " with xyerrorlines";
-            break;
-          }
-	break;
-      case GnuplotDataset::DOTS:
-	os << " with dots";
-	break;
-      case GnuplotDataset::IMPULSES:
-	os << " with impulses";
-	break;
-      case GnuplotDataset::STEPS:
-	os << " with steps";
-	break;
-      case GnuplotDataset::FSTEPS:
-	os << " with fsteps";
-	break;
-      case GnuplotDataset::HISTEPS:
-	os << " with histeps";
-	break;
-      }
+      i->m_data->PrintExpression(os);
+
       i++;
+
       if (i != m_datasets.end ())
 	{
 	  os << ", ";
 	}
     }
   os << std::endl;
+
+  // followed by the inline datafile.
+
   for (Datasets::const_iterator i = m_datasets.begin (); i != m_datasets.end (); i++)
     {
-      for (GnuplotDataset::Dataset::const_iterator j = (*i)->m_dataset.begin ();
-	   j != (*i)->m_dataset.end (); j++)
-	{
-          switch ((*i)->m_errorBars) {
-          case GnuplotDataset::NONE:
-            os << j->x << " " << j->y << std::endl;
-            break;
-          case GnuplotDataset::X:
-            os << j->x << " " << j->y << " " << j->dx << std::endl;
-            break;
-          case GnuplotDataset::Y:
-            os << j->x << " " << j->y << " " << j->dy << std::endl;
-            break;
-          case GnuplotDataset::XY:
-            os << j->x << " " << j->y << " " << j->dx << " " << j->dy << std::endl;
-            break;
-          }
-	}
-      os << "e" << std::endl;
+      i->m_data->PrintDatafile(os);
     }
 }
 
+// ------------------------------------------------------------------------- //
+
+GnuplotCollection::GnuplotCollection (const std::string& outputFilename)
+  : m_outputFilename(outputFilename),
+    m_terminal( Gnuplot::DetectTerminal(outputFilename) )
+{
+}
+
+void
+GnuplotCollection::SetTerminal (const std::string& terminal)
+{
+  m_terminal = terminal;
+}
+
+void
+GnuplotCollection::AddPlot (const Gnuplot& plot)
+{
+  m_plots.push_back (plot);
+}
+
+Gnuplot&
+GnuplotCollection::GetPlot(unsigned int id)
+{
+  if (id >= m_plots.size())
+    throw(std::range_error("Gnuplot id is out of range"));
+  else
+    return m_plots[id];
+}
+
+void
+GnuplotCollection::GenerateOutput (std::ostream &os) const
+{
+  if (m_terminal.size())
+    os << "set terminal " << m_terminal << std::endl;
+
+  if (m_outputFilename.size())
+    os << "set output '" << m_outputFilename << "'" << std::endl;
+
+  for (Plots::const_iterator i = m_plots.begin (); i != m_plots.end (); ++i)
+    {
+      i->GenerateOutput (os);
+    }
+}
+
+// ------------------------------------------------------------------------- //
+
 } // namespace ns3
--- a/src/contrib/gnuplot.h	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/contrib/gnuplot.h	Fri Jan 09 11:44:13 2009 +0000
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2007 INRIA
+ * Copyright (c) 2007 INRIA, 2008 Timo Bingmann
  *
  * 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
@@ -15,7 +15,8 @@
  * 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>
+ * Original Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Enhancements: Timo Bingmann <timo.bingmann@student.kit.edu>
  */
 #ifndef GNUPLOT_H
 #define GNUPLOT_H
@@ -27,11 +28,83 @@
 namespace ns3 {
 
 /**
- * \brief store a dataset to be used by ns3::Gnuplot
+ * \brief Abstract class to store a plot line to be used by ns3::Gnuplot.
+ *
+ * This class contains a reference counted data object in m_data. The data
+ * object contains different structs derived from struct Data by subclasses.
  */
 class GnuplotDataset
 {
 public:
+
+  /**
+   * Reference-counting copy constructor.
+   */
+  GnuplotDataset (const GnuplotDataset& original);
+
+  /**
+   * Reference-counting destructor.
+   */
+  ~GnuplotDataset();
+
+  /**
+   * Reference-counting assignment operator.
+   */
+  GnuplotDataset& operator= (const GnuplotDataset& original);
+
+  /**
+   * \brief Change line title.
+   * \param title the new title string to use for this dataset.
+   */
+  void SetTitle (const std::string& title);
+
+  /**
+   * \brief Change extra formatting style parameters for newly created objects.
+   * \param extra       extra formatting
+   */
+  static void SetDefaultExtra (const std::string& extra);
+
+  /**
+   * \brief Add extra formatting parameters to this dataset.
+   * \param extra       extra formatting
+   */
+  void SetExtra (const std::string& extra);
+
+protected:
+
+  /// Friend because it accesses m_data and it's virtual functions directly in
+  /// GenerateOutput().
+  friend class Gnuplot;
+
+  /**
+   * \brief Extra gnuplot parameters set on every newly created dataset.
+   */
+  static std::string m_defaultExtra;
+
+  /**
+   * \brief Derived classes subclass this struct and add their own data fields.
+   */
+  struct Data;
+
+  /**
+   * Called by constructors of derived classes.
+   * \param data the reference counted data object representing this dataset.
+   */
+  GnuplotDataset (struct Data* data);
+
+  /**
+   * Reference counted data object.
+   */
+  struct Data*  m_data;
+};
+
+/**
+ * \brief Class to represent a 2D points plot. Set the line or points style
+ * using SetStyle() and set points using Add().
+ */
+class Gnuplot2dDataset : public GnuplotDataset
+{
+public:
   /**
    * The plotting style to use for this dataset.
    */
@@ -45,6 +118,7 @@
     FSTEPS,
     HISTEPS,
   };
+
   /**
    * Whether errorbars should be used for this dataset.
    */
@@ -56,20 +130,30 @@
   };
 
   /**
-   * Create an empty dataset without any title.
-   */
-  GnuplotDataset ();
-  /**
    * \param title the title to be associated to this dataset.
    *
    * Create an empty dataset. Usually, the dataset's title is 
    * displayed in the legend box.
    */
-  GnuplotDataset (std::string title);
+  Gnuplot2dDataset (const std::string& title = "Untitled");
+
+  /**
+   * Change default style for all newly created objects.
+   * \param style the style of plotting to use for newly created datasets.
+   */
+  static void SetDefaultStyle (enum Style style);
+
   /**
    * \param style the style of plotting to use for this dataset.
    */
   void SetStyle (enum Style style);
+
+  /**
+   * Change default errorbars style for all newly created objects.
+   * \param errorBars the style of errorbars to use for newly created datasets.
+   */
+  static void SetDefaultErrorBars (enum ErrorBars errorBars);
+
   /**
    * \param errorBars the style of errorbars to display.
    *
@@ -79,6 +163,7 @@
    * method.
    */
   void SetErrorBars (enum ErrorBars errorBars);
+
   /**
    * \param x x coord to new data point
    * \param y y coord to new data point
@@ -86,27 +171,164 @@
    * Use this method with error bar style NONE.
    */
   void Add (double x, double y);
+
   /**
    * \param x x coord to new data point
    * \param y y coord to new data point
-   * \param errorDelta
+   * \param errorDelta data point error range.
    *
    * Use this method with error bar style X or Y.
    */
   void Add (double x, double y, double errorDelta);
+
+  /**
+   * \param x x coord to new data point
+   * \param y y coord to new data point
+   * \param minY minimum error data point
+   * \param maxY maximum error data point
+   *
+   * Use this method with error bar style X or Y.
+   */
+  void Add (double x, double y, double minY, double maxY);
+
+  /**
+   * Add an empty line in the data output sequence. Empty lines in the plot
+   * data break continuous lines and do other things in the output.
+   */
+  void AddEmptyLine();
+
 private:
-  friend class Gnuplot;
-  struct Data {
+
+  struct Point {
+    bool empty;
     double x;
     double y;
     double dx;
     double dy;
   };
-  typedef std::vector<struct Data> Dataset;
-  Dataset m_dataset;
-  std::string m_title;
-  enum Style m_style;
-  enum ErrorBars m_errorBars;
+
+  typedef std::vector<struct Point> PointSet;
+
+  static enum Style m_defaultStyle;
+  static enum ErrorBars m_defaultErrorBars;
+
+  /// Forward declaration of the internal data class.
+  struct Data2d;
+};
+
+/**
+ * \brief Class to represent a 2D function expression plot.
+ *
+ * Since the function expression is not escaped, styles and extras could just
+ * as well be included in the expression string.
+ */
+class Gnuplot2dFunction : public GnuplotDataset
+{
+public:
+  /**
+   * \param title the title to be associated to this dataset.
+   * \param function function to plot
+   *
+   * Create an function dataset. Usually, the dataset's title is displayed in
+   * the legend box.
+   */
+  Gnuplot2dFunction (const std::string& title = "Untitled", const std::string& function = "");
+
+  /**
+   * \param function new function string to set
+   */
+  void SetFunction (const std::string& function);
+
+private:
+
+  /// Forward declaration of the internal data class.
+  struct Function2d;
+};
+
+/**
+ * \brief Class to represent a 3D points plot. Set the line or points style
+ * using SetStyle() and set points using Add().
+ */
+class Gnuplot3dDataset : public GnuplotDataset
+{
+public:
+  /**
+   * \param title the title to be associated to this dataset.
+   *
+   * Create an empty dataset. Usually, the dataset's title is 
+   * displayed in the legend box.
+   */
+  Gnuplot3dDataset (const std::string& title = "Untitled");
+
+  /**
+   * Change default style for all newly created objects.
+   * \param style the style of plotting to use for newly created datasets.
+   */
+  static void SetDefaultStyle (const std::string& style);
+
+  /**
+   * \param style the style of plotting to use for this dataset.
+   */
+  void SetStyle (const std::string& style);
+
+  /**
+   * \param x x coord to new data point
+   * \param y y coord to new data point
+   * \param z z coord to new data point
+   *
+   * Use this method to add a new 3D point
+   */
+  void Add (double x, double y, double z);
+
+  /**
+   * Add an empty line in the data output sequence. Empty lines in the plot
+   * data break continuous lines and do other things in the output.
+   */
+  void AddEmptyLine();
+
+private:
+
+  struct Point {
+    bool empty;
+    double x, y, z;
+  };
+
+  typedef std::vector<struct Point> PointSet;
+
+  static std::string m_defaultStyle;
+
+  /// Forward declaration of the internal data class.
+  struct Data3d;
+};
+
+/**
+ * \brief Class to represent a 3D function expression plot.
+ *
+ * Since the function expression is not escaped, styles and extras could just as
+ * well be included in the expression string. The only difference to
+ * Gnuplot2dFunction is the splot command string.
+ */
+class Gnuplot3dFunction : public GnuplotDataset
+{
+public:
+  /**
+   * \param title the title to be associated to this dataset.
+   * \param function function to plot
+   *
+   * Create an function dataset. Usually, the dataset's title is displayed in
+   * the legend box.
+   */
+  Gnuplot3dFunction (const std::string& title = "Untitled", const std::string& function = "");
+
+  /**
+   * \param function new function string to set
+   */
+  void SetFunction (const std::string& function);
+
+private:
+
+  /// Forward declaration of the internal data class.
+  struct Function3d;
 };
 
 /**
@@ -120,35 +342,117 @@
 {
 public:
   /**
-   * \param pngFilename the name of the file where the png rendering of the
+   * \param outputFilename the name of the file where the rendering of the
    *        graph will be generated if you feed the command stream output by
    *        Gnuplot::GenerateOutput to the gnuplot program.
+   * \param title title line of the plot page 
    */
-  Gnuplot (std::string pngFilename);
-  ~Gnuplot ();
+  Gnuplot (const std::string& outputFilename="", const std::string& title = "");
+
+  /**
+   * Crude attempt to auto-detect the correct terminal setting by inspecting
+   * the filename's extension.
+   * \param filename output file name
+   */
+  static std::string DetectTerminal(const std::string& filename);
+
+  /**
+   * \param terminal terminal setting string for output. The default terminal
+   * string is "png"
+   */
+  void SetTerminal (const std::string& terminal);
+
+  /**
+   * \param title set new plot title string to use for this plot.
+   */
+  void SetTitle (const std::string& title);
 
   /**
    * \param xLegend the legend for the x horizontal axis
    * \param yLegend the legend for the y vertical axis
    */
-  void SetLegend (std::string xLegend, std::string yLegend);
+  void SetLegend (const std::string& xLegend, const std::string& yLegend);
+
+  /**
+   * \param extra set extra gnuplot directive for output.
+   */
+  void SetExtra (const std::string& extra);
+
+  /**
+   * \param extra append extra gnuplot directive for output.
+   */
+  void AppendExtra (const std::string& extra);
 
   /**
    * \param dataset add a dataset to the graph to be plotted.
    */
-  void AddDataset (const GnuplotDataset &dataset);
+  void AddDataset (const GnuplotDataset& dataset);
 
   /**
-   * \param os the output stream on which the relevant gnuplot
-   *        commands should be generated.
+   * \param os the output stream on which the relevant gnuplot commands should
+   * be generated. Including output file and terminal headers.
    */
-  void GenerateOutput (std::ostream &os);
+  void GenerateOutput (std::ostream &os) const;
+
 private:
-  typedef std::vector<GnuplotDataset *> Datasets;
+  typedef std::vector<GnuplotDataset> Datasets;
+
+  std::string m_outputFilename;
+  std::string m_terminal;
+
   Datasets m_datasets;
+
+  std::string m_title;
   std::string m_xLegend;
   std::string m_yLegend;
-  std::string m_pngFilename;
+  std::string m_extra;
+};
+
+/**
+ * \brief a simple class to group together multiple gnuplots into one file,
+ * e.g. for PDF multi-page output terminals.
+ */
+class GnuplotCollection
+{
+public:
+  /**
+   * \param outputFilename the name of the file where the rendering of the
+   *        graph will be generated if you feed the command stream output by
+   *        GnuplotCollection::GenerateOutput to the gnuplot program.
+   */
+  GnuplotCollection (const std::string& outputFilename);
+
+  /**
+   * \param terminal terminal setting string for output. The default terminal
+   * string is guessed from the output filename's extension.
+   */
+  void SetTerminal (const std::string& terminal);
+
+  /**
+   * \param plot add a plot to the collection to be plotted.
+   */
+  void AddPlot (const Gnuplot& plot);
+
+  /**
+   * Return a pointer to one of the added plots.
+   * \param id  index of plot to return
+   * \return    reference to plot, throws std::range_error if it does not exist.
+   */
+  Gnuplot& GetPlot(unsigned int id);
+
+  /**
+   * \param os the output stream on which the relevant gnuplot commands should
+   * be generated.
+   */
+  void GenerateOutput (std::ostream &os) const;
+ 
+private:
+  typedef std::vector<Gnuplot> Plots;
+
+  std::string m_outputFilename;
+  std::string m_terminal;
+
+  Plots       m_plots;
 };
 
 } // namespace ns3
--- a/src/devices/wifi/error-rate-model.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/devices/wifi/error-rate-model.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -18,28 +18,17 @@
  * 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)
+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
 {
@@ -64,231 +53,4 @@
   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
--- a/src/devices/wifi/error-rate-model.h	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/devices/wifi/error-rate-model.h	Fri Jan 09 11:44:13 2009 +0000
@@ -31,8 +31,6 @@
 public:
   static TypeId GetTypeId (void);
 
-  ErrorRateModel ();
-
   /**
    * \param txMode a specific transmission mode
    * \param ber a target ber
@@ -41,28 +39,9 @@
    */
   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;
+  virtual double GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const = 0;
 };
 
-
 } // namespace ns3
 
 #endif /* ERROR_RATE_MODEL_H */
--- a/src/devices/wifi/interference-helper.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/devices/wifi/interference-helper.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -224,11 +224,11 @@
   m_80211a = true;
   m_plcpLongPreambleDelayUs = 16;
   m_plcpShortPreambleDelayUs = 16;
-  m_longPlcpHeaderMode = WifiPhy::g_6mba;
-  m_shortPlcpHeaderMode = WifiPhy::g_6mba;
+  m_longPlcpHeaderMode = WifiPhy::Get6mba ();
+  m_shortPlcpHeaderMode = WifiPhy::Get6mba ();
   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);
+  m_maxPacketDuration = CalculateTxDuration (4095, WifiPhy::Get6mba (), WIFI_PREAMBLE_LONG);
 }
 
 void 
--- a/src/devices/wifi/jakes-propagation-loss-model.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/devices/wifi/jakes-propagation-loss-model.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -31,8 +31,6 @@
 
 namespace ns3 {
 
-
-
 class JakesPropagationLossModel::PathCoefficients 
 {
 public:
@@ -68,9 +66,10 @@
 
 JakesPropagationLossModel::PathCoefficients::~PathCoefficients ()
 {
-  for (uint8_t i = 0; i < m_nRays; i++) {
-    delete [] m_phases[i];
-  }
+  for (uint8_t i = 0; i < m_nRays; i++) 
+    {
+      delete [] m_phases[i];
+    }
   delete [] m_phases;
 }
 
@@ -78,12 +77,14 @@
 JakesPropagationLossModel::PathCoefficients::DoConstruct ()
 {
   m_phases = new double*[m_nRays];
-  for (uint8_t i = 0; i < m_nRays; i++) {
-    m_phases[i] = new double[m_nOscillators + 1];
-    for (uint8_t j = 0; j <= m_nOscillators; j++) {
-      m_phases[i][j] = 2.0 * JakesPropagationLossModel::PI * m_jakes->m_variable.GetValue ();
+  for (uint8_t i = 0; i < m_nRays; i++) 
+    {
+      m_phases[i] = new double[m_nOscillators + 1];
+      for (uint8_t j = 0; j <= m_nOscillators; j++) 
+        {
+          m_phases[i][j] = 2.0 * JakesPropagationLossModel::PI * m_jakes->m_variable.GetValue ();
+        }
     }
-  }
   m_lastUpdate = Simulator::Now ();
 }
 
@@ -101,19 +102,23 @@
   ComplexNumber coef= {0.0, 0.0};
   ComplexNumber fading;
   double norm = 0.0;
-  for (uint8_t i = 0; i < m_nRays; i++) {
-    fading.real = 0.0;
-    fading.imag = 0.0;
-    for (uint8_t j = 0; j <= m_nOscillators; j++) {
-      m_phases[i][j] += 2.0 * JakesPropagationLossModel::PI * cos (2.0 * JakesPropagationLossModel::PI * j / N) * m_jakes->m_fd * interval.GetSeconds ();
-      m_phases[i][j] -= 2.0 * JakesPropagationLossModel::PI * floor (m_phases[i][j] / 2.0 / JakesPropagationLossModel::PI);
-      fading.real += m_jakes->m_amp[j].real * cos (m_phases[i][j]);
-      fading.imag += m_jakes->m_amp[j].imag * cos (m_phases[i][j]);
-      norm += sqrt(pow (m_jakes->m_amp[j].real, 2) + pow(m_jakes->m_amp[j].imag, 2));
-    }
+  for (uint8_t i = 0; i < m_nRays; i++) 
+    {
+      fading.real = 0.0;
+      fading.imag = 0.0;
+      for (uint8_t j = 0; j <= m_nOscillators; j++) 
+        {
+          m_phases[i][j] += 2.0 * JakesPropagationLossModel::PI * 
+            cos (2.0 * JakesPropagationLossModel::PI * j / N) * m_jakes->m_fd * interval.GetSeconds ();
+          m_phases[i][j] -= 2.0 * JakesPropagationLossModel::PI * 
+            floor (m_phases[i][j] / 2.0 / JakesPropagationLossModel::PI);
+          fading.real += m_jakes->m_amp[j].real * cos (m_phases[i][j]);
+          fading.imag += m_jakes->m_amp[j].imag * cos (m_phases[i][j]);
+          norm += sqrt(pow (m_jakes->m_amp[j].real, 2) + pow(m_jakes->m_amp[j].imag, 2));
+        }
     coef.real += fading.real;
     coef.imag += fading.imag;
-  }
+    }
   m_lastUpdate = Simulator::Now ();
   double k = sqrt (pow (coef.real, 2) + pow (coef.imag, 2)) / norm;
   NS_LOG_DEBUG ("Jakes coef "<< k << " (" << 10 * log10 (k) << "dB)");
@@ -136,12 +141,13 @@
 		   MakeUintegerAccessor (&JakesPropagationLossModel::m_nRays),
 		   MakeUintegerChecker<uint8_t> ())
     .AddAttribute ("NumberOfOscillatorsPerRay",
-                   "The number of oscillators to use by default for compute the coeficent for a given ray of a given path (default is 4)",
+                   "The number of oscillators to use by default for compute the coeficent for a given ray of a given "
+                   "path (default is 4)",
                    UintegerValue (4),
 		   MakeUintegerAccessor (&JakesPropagationLossModel::m_nOscillators),
 		   MakeUintegerChecker<uint8_t> ())
     .AddAttribute ("DopplerFreq",
-                   "The doppler frequency in Hz (f_d = v / lambda = v * f / c, the defualt is 0)",
+                   "The doppler frequency in Hz (f_d = v / lambda = v * f / c), the default is 0)",
                    DoubleValue (0.0),
 		   MakeDoubleAccessor (&JakesPropagationLossModel::m_fd),
 		   MakeDoubleChecker<double> ())
@@ -162,14 +168,16 @@
 JakesPropagationLossModel::~JakesPropagationLossModel ()
 {
   delete [] m_amp;
-  for (PathsList::iterator i = m_paths.end (); i != m_paths.begin (); i--) {
-    PathsSet *ps = *i;
-    for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++) {
-      PathCoefficients *pc = *r;
-      delete pc;
+  for (PathsList::iterator i = m_paths.end (); i != m_paths.begin (); i--) 
+    {
+      PathsSet *ps = *i;
+      for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++) 
+        {
+          PathCoefficients *pc = *r;
+          delete pc;
+        }
+      delete ps;
     }
-    delete ps;
-  }
 }
 
 void
@@ -179,11 +187,12 @@
   m_amp = new ComplexNumber[m_nOscillators + 1];
   m_amp[0].real = 2.0 * sqrt(2.0 / N) * cos (PI / 4.0);
   m_amp[0].imag = 2.0 * sqrt(2.0 / N) * sin (PI / 4.0);
-  for (uint8_t i = 1; i <= m_nOscillators; i++) {
-    double beta = PI * (double)i / m_nOscillators;
-    m_amp[i].real = 4.0 * cos (beta) / sqrt(N);
-    m_amp[i].imag = 4.0 * sin (beta) / sqrt(N);
-  }
+  for (uint8_t i = 1; i <= m_nOscillators; i++) 
+    {
+      double beta = PI * (double)i / m_nOscillators;
+      m_amp[i].real = 4.0 * cos (beta) / sqrt(N);
+      m_amp[i].imag = 4.0 * sin (beta) / sqrt(N);
+    }
 }
 
 void
@@ -198,38 +207,42 @@
   m_nOscillators = nOscillators;
 }
 
-double
-JakesPropagationLossModel::DoGetLoss (Ptr<MobilityModel> a,
-				    Ptr<MobilityModel> b) const
+double 
+JakesPropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                          Ptr<MobilityModel> a,
+                                          Ptr<MobilityModel> b) const
 {
   PathsList::iterator i = m_paths.end ();
-  while (i != m_paths.begin ()) {
-    i--;
-    PathsSet *ps = *i;
-    if (PeekPointer (ps->sender) == PeekPointer(a)) {
-      m_paths.erase (i);
-      m_paths.push_back (ps);
-      for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++) {
-        PathCoefficients *pc = *r;
-      	if (PeekPointer (pc->GetReceiver ()) == PeekPointer (b)) {
-          ps->receivers.erase (r);
-	  ps->receivers.push_back (pc);
-	  return pc->GetLoss ();
-	}
-      }
-      PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators);
-      ps->receivers.push_back (pc);
-      return pc->GetLoss ();
+  while (i != m_paths.begin ()) 
+    {
+      i--;
+      PathsSet *ps = *i;
+      if (ps->sender == a) 
+        {
+          m_paths.erase (i);
+          m_paths.push_back (ps);
+          for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++) 
+            {
+              PathCoefficients *pc = *r;
+              if (pc->GetReceiver () == b) 
+                {
+                  ps->receivers.erase (r);
+                  ps->receivers.push_back (pc);
+                  return txPowerDbm + pc->GetLoss ();
+                }
+            }
+          PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators);
+          ps->receivers.push_back (pc);
+          return txPowerDbm + pc->GetLoss ();
+        }
     }
-  }
   PathsSet *ps = new PathsSet;
   ps->sender = a;
   PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators);
   ps->receivers.push_back (pc);
   m_paths.push_back (ps);
-  return pc->GetLoss ();
+  return txPowerDbm + pc->GetLoss ();
 }
 
-
 } // namespace ns3
 
--- a/src/devices/wifi/jakes-propagation-loss-model.h	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/devices/wifi/jakes-propagation-loss-model.h	Fri Jan 09 11:44:13 2009 +0000
@@ -100,9 +100,9 @@
   JakesPropagationLossModel (const JakesPropagationLossModel &o);
   JakesPropagationLossModel & operator = (const JakesPropagationLossModel &o);
   void DoConstruct (void);
-  virtual double DoGetLoss (Ptr<MobilityModel> a,
-			  Ptr<MobilityModel> b) const;
-
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
 
   class PathCoefficients;
   struct ComplexNumber {
--- a/src/devices/wifi/propagation-loss-model.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/devices/wifi/propagation-loss-model.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -16,21 +16,22 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Contributions: Timo Bingmann <timo.bingmann@student.kit.edu>
  */
+
 #include "propagation-loss-model.h"
 #include "ns3/log.h"
 #include "ns3/mobility-model.h"
 #include "ns3/static-mobility-model.h"
+#include "ns3/boolean.h"
 #include "ns3/double.h"
-#include "ns3/pointer.h"
 #include <math.h>
 
 NS_LOG_COMPONENT_DEFINE ("PropagationLossModel");
 
 namespace ns3 {
 
-
-const double FriisPropagationLossModel::PI = 3.1415;
+// ------------------------------------------------------------------------- //
 
 NS_OBJECT_ENSURE_REGISTERED (PropagationLossModel);
 
@@ -57,17 +58,19 @@
 }
 
 double 
-PropagationLossModel::GetLoss (Ptr<MobilityModel> a,
-                               Ptr<MobilityModel> b) const
+PropagationLossModel::CalcRxPower (double txPowerDbm,
+                                   Ptr<MobilityModel> a,
+                                   Ptr<MobilityModel> b) const
 {
-  double self = DoGetLoss (a, b);
+  double self = DoCalcRxPower (txPowerDbm, a, b);
   if (m_next != 0)
     {
-      self += m_next->GetLoss (a, b);
+      self = m_next->CalcRxPower (self, a, b);
     }
   return self;
 }
 
+// ------------------------------------------------------------------------- //
 
 NS_OBJECT_ENSURE_REGISTERED (RandomPropagationLossModel);
 
@@ -77,7 +80,7 @@
   static TypeId tid = TypeId ("ns3::RandomPropagationLossModel")
     .SetParent<PropagationLossModel> ()
     .AddConstructor<RandomPropagationLossModel> ()
-    .AddAttribute ("Variable", "The random variable used to pick a loss everytime GetLoss is invoked.",
+    .AddAttribute ("Variable", "The random variable used to pick a loss everytime CalcRxPower is invoked.",
                    RandomVariableValue (ConstantVariable (1.0)),
                    MakeRandomVariableAccessor (&RandomPropagationLossModel::m_variable),
                    MakeRandomVariableChecker ())
@@ -92,16 +95,21 @@
 {}
 
 double 
-RandomPropagationLossModel::DoGetLoss (Ptr<MobilityModel> a,
-                                       Ptr<MobilityModel> b) const
+RandomPropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                           Ptr<MobilityModel> a,
+                                           Ptr<MobilityModel> b) const
 {
   double rxc = -m_variable.GetValue ();
   NS_LOG_DEBUG ("attenuation coefficent="<<rxc<<"Db");
-  return rxc;
+  return txPowerDbm + rxc;
 }
 
+// ------------------------------------------------------------------------- //
+
 NS_OBJECT_ENSURE_REGISTERED (FriisPropagationLossModel);
 
+const double FriisPropagationLossModel::PI = 3.1415;
+
 TypeId 
 FriisPropagationLossModel::GetTypeId (void)
 {
@@ -179,10 +187,10 @@
   return dbm;
 }
 
-
 double 
-FriisPropagationLossModel::DoGetLoss (Ptr<MobilityModel> a,
-				    Ptr<MobilityModel> b) const
+FriisPropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                          Ptr<MobilityModel> a,
+                                          Ptr<MobilityModel> b) const
 {
   /*
    * Friis free space equation:
@@ -201,30 +209,32 @@
    * lambda: wavelength (m)
    *
    * Here, we ignore tx and rx gain and the input and output values 
-   * are in dbm:
+   * are in dB or dBm:
    *
    *                           lambda^2
    * rx = tx +  10 log10 (-------------------)
    *                       (4 * pi * d)^2 * L
    *
-   * rx: rx power (dbm)
-   * tx: tx power (dbm)
+   * rx: rx power (dB)
+   * tx: tx power (dB)
    * d: distance (m)
-   * L: system loss
+   * L: system loss (unit-less)
    * lambda: wavelength (m)
    */
   double distance = a->GetDistanceFrom (b);
   if (distance <= m_minDistance)
     {
-      return 0.0;
+      return txPowerDbm;
     }
   double numerator = m_lambda * m_lambda;
   double denominator = 16 * PI * PI * distance * distance * m_systemLoss;
   double pr = 10 * log10 (numerator / denominator);
   NS_LOG_DEBUG ("distance="<<distance<<"m, attenuation coefficient="<<pr<<"dB");
-  return pr;
+  return txPowerDbm + pr;
 }
 
+// ------------------------------------------------------------------------- //
+
 NS_OBJECT_ENSURE_REGISTERED (LogDistancePropagationLossModel);
 
 TypeId
@@ -244,7 +254,7 @@
                    MakeDoubleAccessor (&LogDistancePropagationLossModel::m_referenceDistance),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("ReferenceLoss",
-                   "The reference loss at reference distance",
+                   "The reference loss at reference distance (dB). (Default is Friis at 1m with 5.15 GHz)",
                    DoubleValue (46.6777),
                    MakeDoubleAccessor (&LogDistancePropagationLossModel::m_referenceLoss),
                    MakeDoubleChecker<double> ())
@@ -274,13 +284,14 @@
 }
   
 double 
-LogDistancePropagationLossModel::DoGetLoss (Ptr<MobilityModel> a,
-                                          Ptr<MobilityModel> b) const
+LogDistancePropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                                Ptr<MobilityModel> a,
+                                                Ptr<MobilityModel> b) const
 {
   double distance = a->GetDistanceFrom (b);
   if (distance <= m_referenceDistance)
     {
-      return 0.0;
+      return txPowerDbm;
     }
   /**
    * The formula is:
@@ -289,18 +300,114 @@
    * Pr0: rx power at reference distance d0 (W)
    * d0: reference distance: 1.0 (m)
    * d: distance (m)
-   * tx: tx power (db)
-   * rx: db
+   * tx: tx power (dB)
+   * rx: dB
    *
    * Which, in our case is:
-   *      
+   *
    * rx = rx0(tx) - 10 * n * log (d/d0)
    */
   double pathLossDb = 10 * m_exponent * log10 (distance / m_referenceDistance);
   double rxc = -m_referenceLoss - pathLossDb;
   NS_LOG_DEBUG ("distance="<<distance<<"m, reference-attenuation="<<-m_referenceLoss<<"dB, "<<
 		"attenuation coefficient="<<rxc<<"db");
-  return rxc;
+  return txPowerDbm + rxc;
 }
 
+// ------------------------------------------------------------------------- //
+
+NS_OBJECT_ENSURE_REGISTERED (ThreeLogDistancePropagationLossModel);
+
+TypeId
+ThreeLogDistancePropagationLossModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::ThreeLogDistancePropagationLossModel")
+    .SetParent<PropagationLossModel> ()
+    .AddConstructor<ThreeLogDistancePropagationLossModel> ()
+    .AddAttribute ("Distance0",
+                   "Beginning of the first (near) distance field",
+                   DoubleValue (1.0),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance0),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Distance1",
+                   "Beginning of the second (middle) distance field.",
+                   DoubleValue (200.0),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance1),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Distance2",
+                   "Beginning of the third (far) distance field.",
+                   DoubleValue (500.0),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance2),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Exponent0",
+                   "The exponent for the first field.",
+                   DoubleValue (1.9),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent0),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Exponent1",
+                   "The exponent for the second field.",
+                   DoubleValue (3.8),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent1),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Exponent2",
+                   "The exponent for the third field.",
+                   DoubleValue (3.8),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent2),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("ReferenceLoss",
+                   "The reference loss at distance d0 (dB). (Default is Friis at 1m with 5.15 GHz)",
+                   DoubleValue (46.6777),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_referenceLoss),
+                   MakeDoubleChecker<double> ())
+    ;
+  return tid;
+                   
+}
+
+ThreeLogDistancePropagationLossModel::ThreeLogDistancePropagationLossModel ()
+{
+}
+
+double 
+ThreeLogDistancePropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                                     Ptr<MobilityModel> a,
+                                                     Ptr<MobilityModel> b) const
+{
+  double distance = a->GetDistanceFrom (b);
+  NS_ASSERT(distance >= 0);
+
+  // See doxygen comments for the formula and explanation
+
+  double pathLossDb;
+
+  if (distance < m_distance0)
+    {
+      pathLossDb = 0;
+    }
+  else if (distance < m_distance1)
+    {
+      pathLossDb = m_referenceLoss
+        + 10 * m_exponent0 * log10(distance / m_distance0);
+    }
+  else if (distance < m_distance2)
+    {
+      pathLossDb = m_referenceLoss
+        + 10 * m_exponent0 * log10(m_distance1 / m_distance0)
+        + 10 * m_exponent1 * log10(distance / m_distance1);
+    }
+  else
+    {
+      pathLossDb = m_referenceLoss
+        + 10 * m_exponent0 * log10(m_distance1 / m_distance0)
+        + 10 * m_exponent1 * log10(m_distance2 / m_distance1)
+        + 10 * m_exponent2 * log10(distance / m_distance2);
+    }
+
+  NS_LOG_DEBUG ("ThreeLogDistance distance=" << distance << "m, " <<
+                "attenuation=" << pathLossDb << "dB");
+
+  return txPowerDbm - pathLossDb;
+}
+
+
 } // namespace ns3
--- a/src/devices/wifi/propagation-loss-model.h	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/devices/wifi/propagation-loss-model.h	Fri Jan 09 11:44:13 2009 +0000
@@ -16,7 +16,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Contributions: Timo Bingmann <timo.bingmann@student.kit.edu>
  */
+
 #ifndef PROPAGATION_LOSS_MODEL_H
 #define PROPAGATION_LOSS_MODEL_H
 
@@ -30,8 +32,8 @@
 /**
  * \brief Modelize the propagation loss through a transmission medium
  *
- * Calculate the receive power (dbm) from a transmit power (dbm),
- * and, a mobility model for the source and destination positions.
+ * Calculate the receive power (dbm) from a transmit power (dbm)
+ * and a mobility model for the source and destination positions.
  */
 class PropagationLossModel : public Object
 {
@@ -44,23 +46,26 @@
   void SetNext (Ptr<PropagationLossModel> next);
 
   /**
+   * \param txPowerDbm current transmission power (in dBm)
    * \param a the mobility model of the source
    * \param b the mobility model of the destination
-   * \returns the attenuation coefficient (dB)
+   * \returns the reception power after adding/multiplying propagation loss (in dBm)
    */
-  double GetLoss (Ptr<MobilityModel> a,
-                  Ptr<MobilityModel> b) const;
+  double CalcRxPower (double txPowerDbm,
+                      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;
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const = 0;
 
   Ptr<PropagationLossModel> m_next;
 };
 
 /**
- * \brief The propagation loss is random
+ * \brief The propagation loss follows a random distribution.
  */ 
 class RandomPropagationLossModel : public PropagationLossModel
 {
@@ -73,8 +78,9 @@
 private:
   RandomPropagationLossModel (const RandomPropagationLossModel &o);
   RandomPropagationLossModel & operator = (const RandomPropagationLossModel &o);
-  virtual double DoGetLoss (Ptr<MobilityModel> a,
-                            Ptr<MobilityModel> b) const;
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
   RandomVariable m_variable;
 };
 
@@ -163,8 +169,9 @@
 private:
   FriisPropagationLossModel (const FriisPropagationLossModel &o);
   FriisPropagationLossModel & operator = (const FriisPropagationLossModel &o);
-  virtual double DoGetLoss (Ptr<MobilityModel> a,
-                            Ptr<MobilityModel> b) const;
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
   double DbmToW (double dbm) const;
   double DbmFromW (double w) const;
 
@@ -213,8 +220,9 @@
 private:
   LogDistancePropagationLossModel (const LogDistancePropagationLossModel &o);
   LogDistancePropagationLossModel & operator = (const LogDistancePropagationLossModel &o);
-  virtual double DoGetLoss (Ptr<MobilityModel> a,
-                            Ptr<MobilityModel> b) const;
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
   static Ptr<PropagationLossModel> CreateDefaultReference (void);
 
   double m_exponent;
@@ -222,6 +230,72 @@
   double m_referenceLoss;
 };
 
+/**
+ * \brief A log distance path loss propagation model with three distance
+ * fields. This model is the same as ns3::LogDistancePropagationLossModel
+ * except that it has three distance fields: near, middle and far with
+ * different exponents.
+ *
+ * Within each field the reception power is calculated using the log-distance
+ * propagation equation:
+ * \f[ L = L_0 + 10 \cdot n_0 log_{10}(\frac{d}{d_0})\f]
+ * Each field begins where the previous ends and all together form a continuous function.
+ *
+ * There are three valid distance fields: near, middle, far. Actually four: the
+ * first from 0 to the reference distance is invalid and returns txPowerDbm.
+ *
+ * \f[ \underbrace{0 \cdots\cdots}_{=0} \underbrace{d_0 \cdots\cdots}_{n_0} \underbrace{d_1 \cdots\cdots}_{n_1} \underbrace{d_2 \cdots\cdots}_{n_2} \infty \f]
+ *
+ * Complete formula for the path loss in dB:
+ *
+ * \f[\displaystyle L =
+\begin{cases}
+0 & d < d_0 \\
+L_0 + 10 \cdot n_0 \log_{10}(\frac{d}{d_0}) & d_0 \leq d < d_1 \\
+L_0 + 10 \cdot n_0 \log_{10}(\frac{d_1}{d_0}) + 10 \cdot n_1 \log_{10}(\frac{d}{d_1}) & d_1 \leq d < d_2 \\
+L_0 + 10 \cdot n_0 \log_{10}(\frac{d_1}{d_0}) + 10 \cdot n_1 \log_{10}(\frac{d_2}{d_1}) + 10 \cdot n_2 \log_{10}(\frac{d}{d_2})& d_2 \leq d
+\end{cases}\f]
+ *
+ * where:
+ *  - \f$ L \f$ : resulting path loss (dB)
+ *  - \f$ d \f$ : distance (m)
+ *  - \f$ d_0, d_1, d_2 \f$ : three distance fields (m)
+ *  - \f$ n_0, n_1, n_2 \f$ : path loss distance exponent for each field (unitless)
+ *  - \f$ L_0 \f$ : path loss at reference distance (dB)
+ *
+ * When the path loss is requested at a distance smaller than the reference
+ * distance \f$ d_0 \f$, the tx power (with no path loss) is returned. The
+ * reference distance defaults to 1m and reference loss defaults to
+ * ns3::FriisPropagationLossModel with 5.15 GHz and is thus \f$ L_0 \f$ = 46.67 dB.
+ */
+
+class ThreeLogDistancePropagationLossModel : public PropagationLossModel
+{
+public:
+  static TypeId GetTypeId (void);
+  ThreeLogDistancePropagationLossModel ();
+
+  // Parameters are all accessible via attributes.
+
+private:
+  ThreeLogDistancePropagationLossModel (const ThreeLogDistancePropagationLossModel& o);
+  ThreeLogDistancePropagationLossModel& operator= (const ThreeLogDistancePropagationLossModel& o);
+
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
+
+  double m_distance0;
+  double m_distance1;
+  double m_distance2;
+
+  double m_exponent0;
+  double m_exponent1;
+  double m_exponent2;
+
+  double m_referenceLoss;
+};
+
 } // namespace ns3
 
 #endif /* PROPAGATION_LOSS_MODEL_H */
--- a/src/devices/wifi/wifi-phy-test.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/devices/wifi/wifi-phy-test.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -4,6 +4,7 @@
 #include "propagation-loss-model.h"
 #include "propagation-delay-model.h"
 #include "error-rate-model.h"
+#include "yans-error-rate-model.h"
 #include "ns3/ptr.h"
 #include "ns3/mobility-model.h"
 #include "ns3/static-mobility-model.h"
@@ -86,7 +87,7 @@
 
   Ptr<YansWifiPhy> tx = CreateObject<YansWifiPhy> ();
   Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
-  Ptr<ErrorRateModel> error = CreateObject<ErrorRateModel> ();
+  Ptr<ErrorRateModel> error = CreateObject<YansErrorRateModel> ();
   tx->SetErrorRateModel (error);
   rx->SetErrorRateModel (error);
   tx->SetChannel (channel);
@@ -217,7 +218,7 @@
   Ptr<YansWifiPhy> txB = CreateObject<YansWifiPhy> ();
   Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
 
-  Ptr<ErrorRateModel> error = CreateObject<ErrorRateModel> ();
+  Ptr<ErrorRateModel> error = CreateObject<YansErrorRateModel> ();
   txA->SetErrorRateModel (error);
   txB->SetErrorRateModel (error);
   rx->SetErrorRateModel (error);
--- a/src/devices/wifi/wifi-phy.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/devices/wifi/wifi-phy.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -37,34 +37,6 @@
 
 namespace ns3 {
 
-// 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
-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);
-
-
 /****************************************************************
  *       This destructor is needed.
  ****************************************************************/
@@ -97,4 +69,89 @@
   NS_LOG_FUNCTION (this);
 }
 
+WifiMode 
+WifiPhy::Get6mba (void)
+{
+  static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-6mbs",
+                                                      true,
+                                                      20000000, 6000000, 12000000);
+  return mode;
+}
+WifiMode 
+WifiPhy::Get9mba (void)
+{
+  static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-9mbs",
+                                                      false,
+                                                      20000000, 9000000, 12000000);
+  return mode;
+}
+WifiMode 
+WifiPhy::Get12mba (void)
+{
+  static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-12mbs",
+                                                      true,
+                                                      20000000, 12000000, 24000000);
+  return mode;
+}
+WifiMode 
+WifiPhy::Get18mba (void)
+{
+  static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-18mbs",
+                                                      false,
+                                                      20000000, 18000000, 24000000);
+  return mode;
+}
+WifiMode 
+WifiPhy::Get24mba (void)
+{
+  static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-24mbs",
+                                                      true,
+                                                      20000000, 24000000, 48000000);
+  return mode;
+}
+WifiMode 
+WifiPhy::Get36mba (void)
+{
+  static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-36mbs",
+                                                      false,
+                                                      20000000, 36000000, 48000000);
+  return mode;
+}
+
+WifiMode 
+WifiPhy::Get48mba (void)
+{
+  static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-48mbs",
+                                                      false,
+                                                      20000000, 48000000, 72000000);
+  return mode;
+}
+
+WifiMode 
+WifiPhy::Get54mba (void)
+{
+  static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-54mbs",
+                                                      false,
+                                                      20000000, 54000000, 72000000);
+  return mode;
+}
+
 } // namespace ns3
+
+namespace {
+
+static class Constructor
+{
+public:
+  Constructor () {
+    ns3::WifiPhy::Get6mba ();
+    ns3::WifiPhy::Get9mba ();
+    ns3::WifiPhy::Get12mba ();
+    ns3::WifiPhy::Get18mba ();
+    ns3::WifiPhy::Get24mba ();
+    ns3::WifiPhy::Get36mba ();
+    ns3::WifiPhy::Get48mba ();
+    ns3::WifiPhy::Get54mba ();
+  }
+} g_constructor;
+}
--- a/src/devices/wifi/wifi-phy.h	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/devices/wifi/wifi-phy.h	Fri Jan 09 11:44:13 2009 +0000
@@ -242,14 +242,14 @@
 
   virtual Ptr<WifiChannel> GetChannel (void) const = 0;
 
-  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;
+  static WifiMode Get6mba (void);
+  static WifiMode Get9mba (void);
+  static WifiMode Get12mba (void);
+  static WifiMode Get18mba (void);
+  static WifiMode Get24mba (void);
+  static WifiMode Get36mba (void);
+  static WifiMode Get48mba (void);
+  static WifiMode Get54mba (void);
 };
 
 } // namespace ns3
--- a/src/devices/wifi/wifi-test.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/devices/wifi/wifi-test.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -8,6 +8,7 @@
 #include "propagation-delay-model.h"
 #include "propagation-loss-model.h"
 #include "error-rate-model.h"
+#include "yans-error-rate-model.h"
 #include "ns3/static-mobility-model.h"
 #include "ns3/node.h"
 #include "ns3/simulator.h"
@@ -52,7 +53,7 @@
   Ptr<WifiMac> mac = m_mac.Create<WifiMac> ();
   Ptr<StaticMobilityModel> mobility = CreateObject<StaticMobilityModel> ();
   Ptr<YansWifiPhy> phy = CreateObject<YansWifiPhy> ();
-  Ptr<ErrorRateModel> error = CreateObject<ErrorRateModel> ();
+  Ptr<ErrorRateModel> error = CreateObject<YansErrorRateModel> ();
   phy->SetErrorRateModel (error);
   phy->SetChannel (channel);
   phy->SetDevice (dev);
--- a/src/devices/wifi/wscript	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/devices/wifi/wscript	Fri Jan 09 11:44:13 2009 +0000
@@ -12,6 +12,7 @@
         'wifi-phy.cc',
         'wifi-phy-state-helper.cc',
         'error-rate-model.cc',
+        'yans-error-rate-model.cc',
         'interference-helper.cc',
         'yans-wifi-phy.cc',
         'yans-wifi-channel.cc',
@@ -75,6 +76,7 @@
         'wifi-phy.h',
         'supported-rates.h',
         'error-rate-model.h',
+        'yans-error-rate-model.h',
         ]
 
     obj = bld.create_ns3_program('wifi-phy-test',
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/yans-error-rate-model.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -0,0 +1,269 @@
+/* -*-  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-error-rate-model.h"
+#include "wifi-phy.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("YansErrorRateModel");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (YansErrorRateModel);
+
+TypeId 
+YansErrorRateModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::YansErrorRateModel")
+    .SetParent<ErrorRateModel> ()
+    .AddConstructor<YansErrorRateModel> ()
+    ;
+  return tid;
+}
+
+YansErrorRateModel::YansErrorRateModel ()
+{}
+
+double 
+YansErrorRateModel::Log2 (double val) const
+{
+  return log(val) / log(2.0);
+}
+double 
+YansErrorRateModel::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 
+YansErrorRateModel::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
+YansErrorRateModel::Factorial (uint32_t k) const
+{
+  uint32_t fact = 1;
+  while (k > 0) 
+    {
+      fact *= k;
+      k--;
+    }
+  return fact;
+}
+double 
+YansErrorRateModel::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 
+YansErrorRateModel::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 
+YansErrorRateModel::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 
+YansErrorRateModel::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
+YansErrorRateModel::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
+YansErrorRateModel::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 
+YansErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const
+{
+  if (mode == WifiPhy::Get6mba ())
+    {
+      return GetFecBpskBer (snr, 
+                            nbits,
+                            mode.GetBandwidth (), // signal spread
+                            mode.GetPhyRate (), // phy rate
+                            10, // dFree
+                            11 // adFree
+                            );      
+    }
+  else if (mode == WifiPhy::Get9mba ())
+    {
+      return GetFecBpskBer (snr, 
+                            nbits,
+                            mode.GetBandwidth (), // signal spread
+                            mode.GetPhyRate (), // phy rate
+                            5, // dFree
+                            8 // adFree
+                            );
+    }
+  else if (mode == WifiPhy::Get12mba ())
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           4,  // m 
+                           10, // dFree
+                           11, // adFree
+                           0   // adFreePlusOne
+                           );
+    }
+  else if (mode == WifiPhy::Get18mba ())
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           4, // m
+                           5, // dFree
+                           8, // adFree
+                           31 // adFreePlusOne
+                           );
+    }
+  else if (mode == WifiPhy::Get24mba ())
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           16, // m
+                           10, // dFree
+                           11, // adFree
+                           0   // adFreePlusOne
+                           );
+    }
+  else if (mode == WifiPhy::Get36mba ())
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           16, // m
+                           5,  // dFree
+                           8,  // adFree
+                           31  // adFreePlusOne
+                           );
+    }
+  else if (mode == WifiPhy::Get48mba ())
+    {
+      return GetFecQamBer (snr, 
+                           nbits,
+                           mode.GetBandwidth (), // signal spread
+                           mode.GetPhyRate (), // phy rate
+                           64, // m
+                           6,  // dFree
+                           1,  // adFree
+                           16  // adFreePlusOne
+                           );
+    }
+  else if (mode == WifiPhy::Get54mba ())
+    {
+      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/yans-error-rate-model.h	Fri Jan 09 11:44:13 2009 +0000
@@ -0,0 +1,60 @@
+/* -*-  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_ERROR_RATE_MODEL_H
+#define YANS_ERROR_RATE_MODEL_H
+
+#include <stdint.h>
+#include "wifi-mode.h"
+#include "error-rate-model.h"
+
+namespace ns3 {
+
+class YansErrorRateModel : public ErrorRateModel
+{
+public:
+  static TypeId GetTypeId (void);
+
+  YansErrorRateModel ();
+
+  virtual 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 /* YANS_ERROR_RATE_MODEL_H */
--- a/src/devices/wifi/yans-wifi-channel.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/devices/wifi/yans-wifi-channel.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -83,7 +83,7 @@
         {
           Ptr<MobilityModel> receiverMobility = (*i)->GetMobility ()->GetObject<MobilityModel> ();
           Time delay = m_delay->GetDelay (senderMobility, receiverMobility);
-          double rxPowerDbm = txPowerDbm + m_loss->GetLoss (senderMobility, receiverMobility);
+          double rxPowerDbm = m_loss->CalcRxPower (txPowerDbm, senderMobility, receiverMobility);
           NS_LOG_DEBUG ("propagation: txPower="<<txPowerDbm<<"dbm, rxPower="<<rxPowerDbm<<"dbm, "<<
                         "distance="<<senderMobility->GetDistanceFrom (receiverMobility)<<"m, delay="<<delay);
           Ptr<Packet> copy = packet->Copy ();
--- a/src/devices/wifi/yans-wifi-phy.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/devices/wifi/yans-wifi-phy.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -416,14 +416,14 @@
 {
   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);
+  m_modes.push_back (WifiPhy::Get6mba ());
+  m_modes.push_back (WifiPhy::Get9mba ());
+  m_modes.push_back (WifiPhy::Get12mba ());
+  m_modes.push_back (WifiPhy::Get18mba ());
+  m_modes.push_back (WifiPhy::Get24mba ());
+  m_modes.push_back (WifiPhy::Get36mba ());
+  m_modes.push_back (WifiPhy::Get48mba ());
+  m_modes.push_back (WifiPhy::Get54mba ());
 }
 
 void
@@ -431,11 +431,11 @@
 {
   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);
+  m_modes.push_back (WifiPhy::Get6mba ());
+  m_modes.push_back (WifiPhy::Get12mba ());
+  m_modes.push_back (WifiPhy::Get18mba ());
+  m_modes.push_back (WifiPhy::Get36mba ());
+  m_modes.push_back (WifiPhy::Get54mba ());
 }
 
 void 
--- a/src/helper/yans-wifi-helper.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/helper/yans-wifi-helper.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -131,12 +131,12 @@
       if (prev != 0)
 	{
 	  prev->SetNext (cur);
-	  prev = cur;
 	}
       if (m_propagationLoss.begin () == i)
 	{
 	  channel->SetPropagationLossModel (cur);
 	}
+      prev = cur;
     }
   Ptr<PropagationDelayModel> delay = m_propagationDelay.Create<PropagationDelayModel> ();
   channel->SetPropagationDelayModel (delay);
@@ -154,7 +154,7 @@
 YansWifiPhyHelper::Default (void)
 {
   YansWifiPhyHelper helper;
-  helper.SetErrorRateModel ("ns3::ErrorRateModel");
+  helper.SetErrorRateModel ("ns3::YansErrorRateModel");
   return helper;
 }
 
--- a/src/mobility/position-allocator.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/mobility/position-allocator.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -70,6 +70,10 @@
 {
   Vector v = *m_current;
   m_current++;
+  if (m_current == m_positions.end()) 
+    {
+      m_current = m_positions.begin ();
+    }
   return v;
 }
 
--- a/src/mobility/random-waypoint-mobility-model.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/mobility/random-waypoint-mobility-model.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -56,7 +56,7 @@
 
 RandomWaypointMobilityModel::RandomWaypointMobilityModel ()
 {
-  Simulator::ScheduleNow (&RandomWaypointMobilityModel::Start, this);
+  m_event = Simulator::ScheduleNow (&RandomWaypointMobilityModel::Start, this);
 }
 
 void
@@ -72,6 +72,7 @@
   double k = speed / std::sqrt (dx*dx + dy*dy + dz*dz);
 
   m_helper.SetVelocity (Vector (k*dx, k*dy, k*dz));
+  m_helper.Unpause ();
   Time travelDelay = Seconds (CalculateDistance (destination, m_current) / speed);
   m_event = Simulator::Schedule (travelDelay,
 				 &RandomWaypointMobilityModel::Start, this);
@@ -99,7 +100,7 @@
 {
   m_helper.SetPosition (position);
   Simulator::Remove (m_event);
-  Simulator::ScheduleNow (&RandomWaypointMobilityModel::Start, this);
+  m_event = Simulator::ScheduleNow (&RandomWaypointMobilityModel::Start, this);
 }
 Vector
 RandomWaypointMobilityModel::DoGetVelocity (void) const
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/calendar-scheduler.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -0,0 +1,345 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 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 "calendar-scheduler.h"
+#include "event-impl.h"
+#include <utility>
+#include <string>
+#include <list>
+#include "ns3/assert.h"
+#include "ns3/log.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("CalendarScheduler");
+
+NS_OBJECT_ENSURE_REGISTERED (CalendarScheduler);
+
+TypeId 
+CalendarScheduler::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::CalendarScheduler")
+    .SetParent<Scheduler> ()
+    .AddConstructor<CalendarScheduler> ()
+    ;
+  return tid;
+}
+
+CalendarScheduler::CalendarScheduler ()
+{
+  NS_LOG_FUNCTION (this);
+  Init (2, 1, 0);
+  m_qSize = 0;
+}
+CalendarScheduler::~CalendarScheduler ()
+{
+  NS_LOG_FUNCTION (this);
+  delete [] m_buckets;
+  m_buckets = 0;
+}
+void
+CalendarScheduler::Init (uint32_t nBuckets, 
+                         uint64_t width,
+                         uint64_t startPrio)
+{
+  NS_LOG_FUNCTION (this << nBuckets << width << startPrio);
+  m_buckets = new Bucket [nBuckets];
+  m_nBuckets = nBuckets;
+  m_width = width;
+  m_lastPrio = startPrio;
+  m_lastBucket = Hash (startPrio);
+  m_bucketTop = (startPrio / width + 1) * width;
+}
+void
+CalendarScheduler::PrintInfo (void)
+{
+  std::cout << "nBuckets=" << m_nBuckets << ", width=" << m_width<< std::endl;
+  std::cout << "Bucket Distribution ";
+  for (uint32_t i = 0; i < m_nBuckets; i++)
+    {
+      std::cout << m_buckets[i].size () << " ";
+    }
+  std::cout << std::endl;
+}
+uint32_t
+CalendarScheduler::Hash (uint64_t ts) const
+{
+  uint32_t bucket = (ts / m_width) % m_nBuckets;
+  return bucket;
+}
+
+void
+CalendarScheduler::DoInsert (const Event &ev)
+{
+  NS_LOG_FUNCTION (this << ev.key.m_ts << ev.key.m_uid);
+  // calculate bucket index.
+  uint32_t bucket = Hash (ev.key.m_ts);
+  NS_LOG_LOGIC ("insert in bucket=" << bucket);
+
+  // insert in bucket list.
+  Bucket::iterator end = m_buckets[bucket].end ();
+  for (Bucket::iterator i = m_buckets[bucket].begin (); i != end; ++i) 
+    {
+      if (ev.key < i->key)
+        {
+          m_buckets[bucket].insert (i, ev);
+          return;
+        }
+    }
+  m_buckets[bucket].push_back (ev);
+}
+
+void
+CalendarScheduler::Insert (const Event &ev)
+{
+  DoInsert (ev);
+  m_qSize++;
+  ResizeUp ();
+}
+bool 
+CalendarScheduler::IsEmpty (void) const
+{
+  return m_qSize == 0;
+}
+Scheduler::Event
+CalendarScheduler::PeekNext (void) const
+{
+  NS_LOG_FUNCTION (this << m_lastBucket << m_bucketTop);
+  NS_ASSERT (!IsEmpty ());
+  uint32_t i = m_lastBucket;
+  uint64_t bucketTop = m_bucketTop;
+  Scheduler::Event minEvent = {0, {~0, ~0}};
+  do {
+    if (!m_buckets[i].empty ())
+      {
+        Scheduler::Event next = m_buckets[i].front ();
+        if (next.key.m_ts < bucketTop)
+          {
+            return next;
+          }
+        if (next.key < minEvent.key)
+          {
+            minEvent = next;
+          }
+      }
+    i++;
+    i %= m_nBuckets;
+    bucketTop += m_width;
+  } while (i != m_lastBucket);
+
+  return minEvent;
+}
+
+Scheduler::Event
+CalendarScheduler::DoRemoveNext (void)
+{
+  uint32_t i = m_lastBucket;
+  uint64_t bucketTop = m_bucketTop;
+  Scheduler::Event minEvent = {0, {~0, ~0}};
+  do {
+    if (!m_buckets[i].empty ())
+      {
+        Scheduler::Event next = m_buckets[i].front ();
+        if (next.key.m_ts < bucketTop)
+          {
+            m_lastBucket = i;
+            m_lastPrio = next.key.m_ts;
+            m_bucketTop = bucketTop;
+            m_buckets[i].pop_front ();
+            return next;
+          }
+        if (next.key < minEvent.key)
+          {
+            minEvent = next;
+          }
+      }
+    i++;
+    i %= m_nBuckets;
+    bucketTop += m_width;
+  } while (i != m_lastBucket);
+
+  m_lastPrio = minEvent.key.m_ts;
+  m_lastBucket = Hash (minEvent.key.m_ts);
+  m_bucketTop = (minEvent.key.m_ts / m_width + 1) * m_width;
+  m_buckets[m_lastBucket].pop_front ();
+
+  return minEvent;
+}
+
+Scheduler::Event
+CalendarScheduler::RemoveNext (void)
+{
+  NS_LOG_FUNCTION (this << m_lastBucket << m_bucketTop);
+  NS_ASSERT (!IsEmpty ());
+
+  Scheduler::Event ev = DoRemoveNext ();
+  NS_LOG_LOGIC ("remove ts=" << ev.key.m_ts << 
+                ", key=" << ev.key.m_uid << 
+                ", from bucket=" << m_lastBucket);
+  m_qSize--;
+  ResizeDown ();
+  return ev;
+}
+
+void
+CalendarScheduler::Remove (const Event &ev)
+{
+  NS_ASSERT (!IsEmpty ());
+  // bucket index of event
+  uint32_t bucket = Hash (ev.key.m_ts);
+
+  Bucket::iterator end = m_buckets[bucket].end ();
+  for (Bucket::iterator i = m_buckets[bucket].begin (); i != end; ++i)
+    {
+      if (i->key.m_uid == ev.key.m_uid)
+        {
+          NS_ASSERT (ev.impl == i->impl);
+          m_buckets[bucket].erase (i);
+
+          m_qSize--;
+          ResizeDown ();
+          return;
+        }
+    }
+  NS_ASSERT (false);
+}
+
+void 
+CalendarScheduler::ResizeUp (void)
+{
+  if (m_qSize > m_nBuckets * 2 && 
+      m_nBuckets < 32768)
+    {
+      Resize (m_nBuckets * 2);
+    }
+}
+void 
+CalendarScheduler::ResizeDown (void)
+{
+  if (m_qSize < m_nBuckets / 2)
+    {
+      Resize (m_nBuckets / 2);
+    }
+}
+
+uint32_t
+CalendarScheduler::CalculateNewWidth (void)
+{
+  if (m_qSize < 2) 
+    {
+      return 1;
+    }
+  uint32_t nSamples;
+  if (m_qSize <= 5)
+    {
+      nSamples = m_qSize;
+    }
+  else
+    {
+      nSamples = 5 + m_qSize / 10;
+    }
+  if (nSamples > 25)
+    {
+      nSamples = 25;
+    }
+
+  // we gather the first nSamples from the queue
+  std::list<Scheduler::Event> samples;
+  // save state
+  uint32_t lastBucket = m_lastBucket;
+  uint64_t bucketTop = m_bucketTop;
+  uint64_t lastPrio = m_lastPrio;
+ 
+  // gather requested events
+  for (uint32_t i = 0; i < nSamples; i++)
+    {
+      samples.push_back (DoRemoveNext ());
+    }
+  // put them back
+  for (std::list<Scheduler::Event>::const_iterator i = samples.begin (); 
+       i != samples.end (); ++i)
+    {
+      DoInsert (*i);
+    }
+
+  // restore state.
+  m_lastBucket = lastBucket;
+  m_bucketTop = bucketTop;
+  m_lastPrio = lastPrio;
+
+  // finally calculate inter-time average over samples.
+  uint64_t totalSeparation = 0;
+  std::list<Scheduler::Event>::const_iterator end = samples.end ();
+  std::list<Scheduler::Event>::const_iterator cur = samples.begin ();
+  std::list<Scheduler::Event>::const_iterator next = cur;
+  next++;
+  while (next != end)
+    {
+      totalSeparation += next->key.m_ts - cur->key.m_ts;
+      cur++;
+      next++;
+    }
+  uint64_t twiceAvg = totalSeparation / (nSamples - 1) * 2;
+  totalSeparation = 0;
+  cur = samples.begin ();
+  next = cur;
+  next++;
+  while (next != end)
+    {
+      uint64_t diff = next->key.m_ts - cur->key.m_ts;
+      if (diff <= twiceAvg)
+        {
+          totalSeparation += diff;
+        }
+      cur++;
+      next++;
+    }
+
+  totalSeparation *= 3;
+  totalSeparation = std::max (totalSeparation, (uint64_t)1);
+  return totalSeparation;
+}
+void
+CalendarScheduler::DoResize (uint32_t newSize, uint32_t newWidth)
+{
+  Bucket *oldBuckets = m_buckets;
+  uint32_t oldNBuckets = m_nBuckets;
+  Init (newSize, newWidth, m_lastPrio);
+
+  for (uint32_t i = 0; i < oldNBuckets; i++)
+    {
+      Bucket::iterator end = oldBuckets[i].end ();
+      for (Bucket::iterator j = oldBuckets[i].begin (); j != end; ++j) 
+        {
+          DoInsert (*j);
+        }
+    }
+}
+void 
+CalendarScheduler::Resize (uint32_t newSize)
+{
+  NS_LOG_FUNCTION (this << newSize);
+
+  //PrintInfo ();
+  uint32_t newWidth = CalculateNewWidth ();  
+  DoResize (newSize, newWidth);
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/calendar-scheduler.h	Fri Jan 09 11:44:13 2009 +0000
@@ -0,0 +1,93 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 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 CALENDAR_SCHEDULER_H
+#define CALENDAR_SCHEDULER_H
+
+#include "scheduler.h"
+#include <stdint.h>
+#include <list>
+
+namespace ns3 {
+
+class EventImpl;
+
+/**
+ * \ingroup scheduler
+ * \brief a calendar queue event scheduler
+ *
+ * This event scheduler is a direct implementation of the algorithm known as a calendar queue.
+ * first published in 1988 in "Calendar Queues: A Fast O(1) Priority Queue Implementation for
+ * the Simulation Event Set Problem" by Randy Brown. There are many refinements published
+ * later but this class implements the original algorithm (to the best of my knowledge).
+ *
+ * Note: This queue is much slower than I expected (much slower than the std::map queue)
+ * and this seems to be because the original resizing policy is horribly bad. This is
+ * most likely the reason why there have been so many variations published which all
+ * slightly tweak the resizing heuristics to obtain a better distribution of events
+ * across buckets.
+ */
+class CalendarScheduler : public Scheduler 
+{
+public:
+  static TypeId GetTypeId (void);
+
+  CalendarScheduler ();
+  virtual ~CalendarScheduler ();
+
+  virtual void Insert (const Event &ev);
+  virtual bool IsEmpty (void) const;
+  virtual Event PeekNext (void) const;
+  virtual Event RemoveNext (void);
+  virtual void Remove (const Event &ev);
+
+private:
+  void ResizeUp (void);
+  void ResizeDown (void);
+  void Resize (uint32_t newSize);
+  uint32_t CalculateNewWidth (void);
+  void Init (uint32_t nBuckets, 
+             uint64_t width,
+             uint64_t startPrio);
+  inline uint32_t Hash (uint64_t key) const;
+  void PrintInfo (void);
+  void DoResize (uint32_t newSize, uint32_t newWidth);
+  Scheduler::Event DoRemoveNext (void);
+  void DoInsert (const Event &ev);
+
+  typedef std::list<Scheduler::Event> Bucket;
+  Bucket *m_buckets;
+  // number of buckets in array
+  uint32_t m_nBuckets;
+  // duration of a bucket
+  uint64_t m_width;
+  // bucket index from which the last event was dequeued
+  uint32_t m_lastBucket;
+  // priority at the top of the bucket from which last event was dequeued
+  uint64_t m_bucketTop;
+  // the priority of the last event removed
+  uint64_t m_lastPrio;
+  // number of events in queue
+  uint32_t m_qSize;
+};
+
+} // namespace ns3
+
+#endif /* CALENDAR_SCHEDULER_H */
--- a/src/simulator/default-simulator-impl.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/simulator/default-simulator-impl.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -144,7 +144,7 @@
 void
 DefaultSimulatorImpl::Run (void)
 {
-
+  m_stop = false;
   while (!m_events->IsEmpty () && !m_stop) 
     {
       ProcessOneEvent ();
--- a/src/simulator/heap-scheduler.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/simulator/heap-scheduler.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -29,6 +29,17 @@
 
 namespace ns3 {
 
+NS_OBJECT_ENSURE_REGISTERED (HeapScheduler);
+
+TypeId 
+HeapScheduler::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::HeapScheduler")
+    .SetParent<Scheduler> ()
+    .AddConstructor<HeapScheduler> ()
+    ;
+  return tid;
+}
 
 HeapScheduler::HeapScheduler ()
 {
--- a/src/simulator/heap-scheduler.h	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/simulator/heap-scheduler.h	Fri Jan 09 11:44:13 2009 +0000
@@ -47,6 +47,8 @@
 class HeapScheduler : public Scheduler 
 {
 public:
+  static TypeId GetTypeId (void);
+
   HeapScheduler ();
   virtual ~HeapScheduler ();
 
--- a/src/simulator/high-precision-128.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/simulator/high-precision-128.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -18,6 +18,7 @@
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
 #include "high-precision-128.h"
+#include "ns3/test.h"
 #include <math.h>
 #include <iostream>
 
@@ -160,10 +161,24 @@
   HP128INC (m_ndivs++);
   EnsureSlow ();
   const_cast<HighPrecision &> (o).EnsureSlow ();
-  cairo_int128_t div = _cairo_int128_rsa (o.m_slowValue, 64);
   cairo_quorem128_t qr;
-  qr = _cairo_int128_divrem (m_slowValue, div);
-  m_slowValue = qr.quo;
+  qr = _cairo_int128_divrem (m_slowValue, o.m_slowValue);
+  m_slowValue = _cairo_int128_lsl (qr.quo, 64);
+  // Now, manage the remainder
+  cairo_int128_t div = o.m_slowValue;
+  cairo_int128_t tmp;
+  tmp = _cairo_int128_rsa (qr.rem, 64);
+  cairo_int128_t zero = _cairo_int64_to_int128 (0);
+  if (_cairo_int128_eq (tmp, zero))
+    {
+      qr.rem = _cairo_int128_lsl (qr.rem, 64);
+    }
+  else
+    {
+      div = _cairo_int128_rsa (div, 64);
+    }
+  qr = _cairo_int128_divrem (qr.rem, div);
+  m_slowValue = _cairo_int128_add (m_slowValue, qr.quo);
   return false;
 }
 int 
@@ -207,14 +222,15 @@
 HighPrecision128Tests::~HighPrecision128Tests ()
 {}
 
-#define CHECK_EXPECTED(v,expected) \
-{ \
-  if (v.GetInteger () != expected) \
-    { \
-      Failure () << "file="<<__FILE__<<", line="<<__LINE__<<", expected: "<<expected<<", got: "<< v.GetInteger ()<<std::endl; \
-      ok = false; \
-    } \
-}
+#define CHECK_EXPECTED(v,expected)                                      \
+  {                                                                     \
+    if (v.GetInteger () != expected)                                    \
+      {                                                                 \
+        Failure () << "file="<<__FILE__<<", line="<<__LINE__<<          \
+          ", expected: "<<expected<<", got: "<< v.GetInteger ()<<std::endl; \
+        result = false;                                                 \
+      }                                                                 \
+  }
 
 #define V(v) \
   HighPrecision (v, false)
@@ -222,7 +238,7 @@
 bool
 HighPrecision128Tests::RunTests (void)
 {
-  bool ok = true;
+  bool result = true;
 
   HighPrecision a, b;
   a = HighPrecision (1, false);
@@ -331,15 +347,17 @@
   a.Mul (V(3));
   CHECK_EXPECTED (a, 1999999999);
   
+  // Bug 455
+  a = HighPrecision (0.1);
+  a.Div (HighPrecision (1.25));
+  NS_TEST_ASSERT_EQUAL (a.GetDouble (), 0.08);
 
 
-
-  return ok;
+  return result;
 }
 
 static HighPrecision128Tests g_int128Tests;
 
-
-}; // namespace ns3
+} // namespace ns3
 
 #endif /* RUN_SELF_TESTS */
--- a/src/simulator/list-scheduler.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/simulator/list-scheduler.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -27,6 +27,18 @@
 namespace ns3 {
 
 
+NS_OBJECT_ENSURE_REGISTERED (ListScheduler);
+
+TypeId 
+ListScheduler::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::ListScheduler")
+    .SetParent<Scheduler> ()
+    .AddConstructor<ListScheduler> ()
+    ;
+  return tid;
+}
+
 ListScheduler::ListScheduler ()
 {}
 ListScheduler::~ListScheduler ()
--- a/src/simulator/list-scheduler.h	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/simulator/list-scheduler.h	Fri Jan 09 11:44:13 2009 +0000
@@ -40,6 +40,8 @@
 class ListScheduler : public Scheduler 
 {
  public:
+  static TypeId GetTypeId (void);
+
   ListScheduler ();
   virtual ~ListScheduler ();
 
--- a/src/simulator/map-scheduler.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/simulator/map-scheduler.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -29,6 +29,18 @@
 
 namespace ns3 {
 
+NS_OBJECT_ENSURE_REGISTERED (MapScheduler);
+
+TypeId 
+MapScheduler::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::MapScheduler")
+    .SetParent<Scheduler> ()
+    .AddConstructor<MapScheduler> ()
+    ;
+  return tid;
+}
+
 MapScheduler::MapScheduler ()
 {}
 MapScheduler::~MapScheduler ()
--- a/src/simulator/map-scheduler.h	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/simulator/map-scheduler.h	Fri Jan 09 11:44:13 2009 +0000
@@ -38,6 +38,8 @@
 class MapScheduler : public Scheduler 
 {
 public:
+  static TypeId GetTypeId (void);
+
   MapScheduler ();
   virtual ~MapScheduler ();
 
--- a/src/simulator/realtime-simulator-impl.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/simulator/realtime-simulator-impl.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -421,6 +421,7 @@
   NS_ASSERT_MSG (m_running == false, 
                  "RealtimeSimulatorImpl::Run(): Simulator already running");
 
+  m_stop = false;
   m_running = true;
   m_synchronizer->SetOrigin (m_currentTs);
 
--- a/src/simulator/simulator.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/simulator/simulator.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -23,7 +23,6 @@
 #include "default-simulator-impl.h"
 #include "realtime-simulator-impl.h"
 #include "scheduler.h"
-#include "map-scheduler.h"
 #include "event-impl.h"
 
 #include "ns3/ptr.h"
@@ -48,6 +47,12 @@
   StringValue ("ns3::DefaultSimulatorImpl"),
   MakeStringChecker ());
 
+GlobalValue g_schedTypeImpl = GlobalValue ("SchedulerType", 
+  "The object class to use as the scheduler implementation",
+  StringValue ("ns3::MapScheduler"),
+  MakeStringChecker ());
+
+
 #ifdef NS3_LOG_ENABLE
 
 //
@@ -77,15 +82,21 @@
    */
   if (impl == 0) 
     {
-      ObjectFactory factory;
-      StringValue s;
-
-      g_simTypeImpl.GetValue (s);
-      factory.SetTypeId (s.Get ());
-      impl = factory.Create<SimulatorImpl> ();
-
-      Ptr<Scheduler> scheduler = CreateObject<MapScheduler> ();
-      impl->SetScheduler (scheduler);
+      {
+        ObjectFactory factory;
+        StringValue s;
+        
+        g_simTypeImpl.GetValue (s);
+        factory.SetTypeId (s.Get ());
+        impl = factory.Create<SimulatorImpl> ();
+      }
+      {
+        ObjectFactory factory;
+        StringValue s;
+        g_schedTypeImpl.GetValue (s);
+        factory.SetTypeId (s.Get ());
+        impl->SetScheduler (factory.Create<Scheduler> ());
+      }
 
 //
 // Note: we call LogSetTimePrinter _after_ creating the implementation
@@ -302,6 +313,7 @@
 #include "ns3/ptr.h"
 #include "list-scheduler.h"
 #include "heap-scheduler.h"
+#include "map-scheduler.h"
 
 namespace ns3 {
 
--- a/src/simulator/time.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/simulator/time.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -698,11 +698,14 @@
   itu3 = tu3.GetHighPrecision().GetInteger()/(1e27);
 }
 
-void TimeTests::CheckConversions(uint64_t tval, bool *ok, bool verbose) {
+void TimeTests::CheckConversions(uint64_t tval, bool *ok, bool verbose) 
+{
   Time t_sec, t_ms, t_us, t_ns, t_ps, t_fs;
 
   if (verbose) 
-    std::cout << std::endl << "Check conversions: " << tval << std::endl;
+    {
+      std::cout << std::endl << "Check conversions: " << tval << std::endl;
+    }
 
   // First check the seconds
   t_sec = Seconds((double)tval);
@@ -764,15 +767,18 @@
 }
 
 void TimeTests::CheckPrecision(TimeStepPrecision::precision_t prec, uint64_t val, bool *ok, 
-                               bool verbose) {
-  if (verbose) {
-    std::cout << "check precision 10^-" << prec << std::endl;
-  }
+                               bool verbose) 
+{
+  if (verbose) 
+    {
+      std::cout << "check precision 10^-" << prec << std::endl;
+    }
 
   TimeStepPrecision::Set (prec);
-  if (TimeStepPrecision::Get () != prec) {
-    ok = false;
-  }
+  if (TimeStepPrecision::Get () != prec) 
+    {
+      ok = false;
+    }
 
   /* These still need to be fixed.
   // The smallest value that can be stored is 1x10^(-prec)
@@ -802,20 +808,24 @@
                               bool verbose)
 {
   double prec = pow(10,-((double)(ns3::TimeStepPrecision::Get ()))) * precMultFactor;
-  if ((actual < (expected-prec)) || (actual > (expected+prec))) {
-    std::cout << "FAIL " << test_id 
-              << " Expected:" << expected 
-              << " Actual: " << actual
-              << " Precision: " << prec << std::endl;
-    *flag = false;
-  } else {
-    if (verbose) {
-      std::cout << "PASS " << test_id 
+  if ((actual < (expected-prec)) || (actual > (expected+prec))) 
+    {
+      std::cout << "FAIL " << test_id 
                 << " Expected:" << expected 
                 << " Actual: " << actual
                 << " Precision: " << prec << std::endl;
+      *flag = false;
+    } 
+  else 
+    {
+      if (verbose) 
+        {
+          std::cout << "PASS " << test_id 
+                    << " Expected:" << expected 
+                    << " Actual: " << actual
+                    << " Precision: " << prec << std::endl;
+        }
     }
-  }
 }
 
 void TimeTests::CheckTime (std::string test_id, int64_t actual, 
@@ -823,25 +833,29 @@
                            bool verbose)
 {
   double prec = pow(10,-((double)(ns3::TimeStepPrecision::Get ()))) * precMultFactor;
-  if ((actual < (expected-prec)) || (actual > (expected+prec))) {
-    std::cout << "FAIL " << test_id 
-              << " Expected:" << expected 
-              << " Actual: " << actual
-              << " Precision: " << prec << std::endl;
-    *flag = false;
-  } else {
-    if (verbose) {
-      std::cout << "PASS " << test_id 
+  if ((actual < (expected-prec)) || (actual > (expected+prec))) 
+    {
+      std::cout << "FAIL " << test_id 
                 << " Expected:" << expected 
-                << " Actual: " << actual 
+                << " Actual: " << actual
                 << " Precision: " << prec << std::endl;
+      *flag = false;
+    } 
+  else 
+    {
+      if (verbose) 
+        {
+          std::cout << "PASS " << test_id 
+                    << " Expected:" << expected 
+                    << " Actual: " << actual 
+                    << " Precision: " << prec << std::endl;
+        }
     }
-  }
 }
 
 
 static TimeTests g_time_tests;
   
-};
+}
 
 #endif /* RUN_SELF_TESTS */
--- a/src/simulator/wscript	Sat Jan 03 23:14:32 2009 +0000
+++ b/src/simulator/wscript	Fri Jan 09 11:44:13 2009 +0000
@@ -48,6 +48,7 @@
         'list-scheduler.cc',
         'map-scheduler.cc',
         'heap-scheduler.cc',
+        'calendar-scheduler.cc',
         'event-impl.cc',
         'simulator.cc',
         'default-simulator-impl.cc',
@@ -71,6 +72,7 @@
         'list-scheduler.h',
         'map-scheduler.h',
         'heap-scheduler.h',
+        'calendar-scheduler.h',
         'simulation-singleton.h',
         'timer.h',
         'timer-impl.h',
--- a/utils/bench-simulator.cc	Sat Jan 03 23:14:32 2009 +0000
+++ b/utils/bench-simulator.cc	Fri Jan 09 11:44:13 2009 +0000
@@ -168,6 +168,10 @@
         {
           Simulator::SetScheduler (CreateObject<MapScheduler> ());
         } 
+      else if (strcmp ("--calendar", argv[0]) == 0)
+        {
+          Simulator::SetScheduler (CreateObject<CalendarScheduler> ());
+        }
       else if (strcmp ("--debug", argv[0]) == 0) 
         {
           g_debug = true;