--- 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;