diff --git a/.hgtags b/.hgtags
index 9c382aec9..e38d93c33 100644
--- a/.hgtags
+++ b/.hgtags
@@ -31,3 +31,4 @@ dfd0bc16dc991313896f351530a3dc5a25f62e15 ns-3.3-RC4
58ae52c5845ff03ba08dc921e13e6cf3604c810a ns-3.3-RC5
4267fd454004f5a60e517496f43a01000ccebc72 ns-3.3-RC6
2efae18e73794c0acd8061a9bd5c74b69f1b0d93 ns-3.3
+5396ecd09060bcb1e7b1f750bb170cbfde7a77c2 ns-3.4
diff --git a/AUTHORS b/AUTHORS
index 71bd5f3a3..65ab81a16 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -14,4 +14,14 @@ David Gross (gdavid.devel@gmail.com)
Mehdi Benamor (mehdi.benamor@telecom-bretagne.eu)
Angelos Chatzipapas (chatzipa@ceid.upatras.gr)
Luis Cortes (cortes@gatech.edu)
+Kulin Shah (m.kulin@gmail.com)
+Sam Jansen (sam.jansen@gmail.com)
+Timo Bingmann (timo.bingmann@student.kit.edu)
+Kirill V. Andreev (kirillano@yandex.ru)
+Providence Salumu Munga (Providence.Salumu@gmail.com, Providence.Salumu_Munga@it-sudparis.eu)
+Mauro Tortonesi (mauro.tortonesi@unife.it)
+Aleksey Kovalenko (kovalenko@iitp.ru)
+Liu Jian (liujatp@gmail.com)
+Andrey Hippo (ahippo@yandex.ru)
+Francesco Malandrino (francesco.malandrino@gmail.com)
diff --git a/CHANGES.html b/CHANGES.html
index bac58e3c1..8e9f45398 100644
--- a/CHANGES.html
+++ b/CHANGES.html
@@ -44,53 +44,100 @@ to this file based on your experience, please contribute a patch or drop
us a note on ns-developers mailing list.
-
changes from ns-3.3 to ns-3.4
+
Changes from ns-3.3 to ns-3.4
-
new API:
+
Changes to build system
+
A major option regarding the downloading and building of ns-3 has been
+added for ns-3.4 -- the ns-3-allinone feature. This allows a user to
+get the most common options for ns-3 downloaded and built with a minimum
+amount of trouble. See the ns-3 tutorial for a detailed explanation of
+how to use this new feature.
+
+
The build system now runs build items in parallel by default. This includes
+the regression tests.
+
+
+
New API:
+
+
XML support has been added to the ConfigStore in /src/contrib/config-store.cc
+
+
The ns-2 calendar queue scheduler option has been ported to src/simulator
+
+
A ThreeLogDistancePropagationLossModel has been added to src/devices/wifi
+
ConstantAccelerationMobilityModel in src/mobility/constant-acceleration-mobility-model.h
+
+
A new emulation mode is supported with the TapBridge net device (see
+src/devices/tap-bridge)
+
+
A new facility for naming ns-3 Objects is included (see
+src/core/names.{cc,h})
+
+
Wifi multicast support has been added in src/devices/wifi
+
Changes to existing API:
+
-
A new emulation mode is supported with the TapBridge net device (see
-
src/devices/tap-bridge)
+
Some fairly significant changes have been made to the API of the
+random variable code. Please see the ns-3 manual and src/core/random-variable.cc
+for details.
+
+
The trace sources in the various NetDevice classes has been completely
+reworked to allow for a consistent set of trace sources across the
+devices. The names of the trace sources have been changed to provide
+some context with respect to the level at which the trace occurred.
+A new set of trace sources has been added which emulates the behavior
+of packet sniffers. These sources have been used to implement tcpdump-
+like functionality and are plumbed up into the helper classes. The
+user-visible changes are the trace source name changes and the ability
+to do promiscuous-mode pcap tracing via helpers. For further information
+regarding these changes, please see the ns-3 manual
+
+
StaticMobilityModel has been renamed ConstantPositionMobilityModel
+StaticSpeedMobilityModel has been renamed ConstantVelocityMobilityModel
+
+
The Callback templates have been extended to support more parameters.
+See src/core/callback.h
+
+
Many helper API have been changed to allow passing Object-based parameters
+as string names to ease working with the object name service.
+
+
The Config APIs now accept path segments that are names defined by the
+object name service.
+
+
Minor changes were made to make the system build under the Intel C++ compiler.
+
+
Trace hooks for association and deassociation to/from an access point were
+added to src/devices/wifi/nqsta-wifi-mac.cc
-
-
A new facility for naming ns-3 Objects is included (see
-
src/core/names.{cc,h})
-
-
-
changes to existing API:
+
Changed behavior:
-
The trace sources in the various NetDevice classes has been completely
-
reworked to allow for a consistent set of trace sources across the
-
devices. The names of the trace sources have been changed to provide
-
some context with respect to the level at which the trace occurred.
-
A new set of trace sources has been added which emulates the behavior
-
of packet sniffers. These sources have been used to implement tcpdump-
-
like functionality and are plumbed up into the helper classes. The
-
user-visible changes are the trace source name changes and the ability
-
to do promiscuous-mode pcap tracing via helpers. For further information
-
regarding these changes, please see the ns-3 manual
-
-
-
-
StaticMobilityModel has been renamed ConstantPositionMobilityModel
-
StaticSpeedMobilityModel has been renamed ConstantVelocityMobilityModel
+
The tracing system rework has introduced some significant changes in the
+behavior of some trace sources, specifically in the positioning of trace sources
+in the device code. For example, there were cases where the packet transmit
+trace source was hit before the packet was enqueued on the device transmit quueue.
+This now happens just before the packet is transmitted over the channel medium.
+The scope of the changes is too large to be included here. If you have concerns
+regarding trace semantics, please consult the net device documentation for details.
+As is usual, the ultimate source for documentation is the net device source code.
-
changes from ns-3.2 to ns-3.3
+
Changes from ns-3.2 to ns-3.3
-
new API:
+
New API:
-
ns-3 ABORT macros in src/core/abort.h
-
Config::MatchContainer
-
ConstCast and DynamicCast helper functions for Ptr casting
-
StarTopology added to several topology helpers
-
NetDevice::IsBridge ()
+
+ns-3 ABORT macros in src/core/abort.h
+Config::MatchContainer
+ConstCast and DynamicCast helper functions for Ptr casting
+StarTopology added to several topology helpers
+NetDevice::IsBridge ()
+
01-08-2008; changeset
@@ -226,7 +273,7 @@ mostly for internal use.
-
changes to existing API:
+
Changes to existing API:
05-09-2008; changeset
@@ -364,7 +411,7 @@ Rename all instances method names using "Set..Parameter" to "Set..Attribute"
-
changed behavior:
+
Changed behavior:
07-09-2008; changeset
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index 40196af8e..bed5b44b9 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -8,8 +8,8 @@ http://www.nsnam.org
including tutorials:
http://www.nsnam.org/tutorials.html
-Release 3.4 (pending)
-=====================
+Release 3.4
+===========
Availability
------------
@@ -18,7 +18,7 @@ http://www.nsnam.org/releases/ns-3.4.tar.bz2
Supported platforms
-------------------
-ns-3.2 has been tested on the following platforms:
+ns-3.4 has been tested on the following platforms:
- linux x86 gcc 4.2, 4.1, and, 3.4.6.
- linux x86_64 gcc 4.3.2, 4.2.3, 4.2.1, 4.1.3, 3.4.6
- MacOS X ppc and x86
@@ -34,6 +34,19 @@ New user-visible features
propagation loss model based on the ns-2 models. Fabian Mauchle contributed
multicast support.
+ b) Object Name Service: A facility allowing ns-3 Objects to be assigned
+ names has been added.
+
+ c) Tap Bridge: A second option for integrating ns-3 with real-world hosts
+ has been added. This allows for real hosts to talk over ns-3 net devices
+ and simulated networks.
+
+ d) A new build option (ns-3-allinone) has been provided to make it easier for
+ users to download and bulid commonly used ns-3 configurations.
+
+ e) The ns-3 calendar queue scheduler has been ported to ns-3.
+
+ f) XML support has been added to the ConfigStore.
API changes from ns-3.3
-----------------------
@@ -56,7 +69,8 @@ Future releases
Our next release, which is expected to happen in 2 to 4 months from now, will
feature the merging of some of our projects currently in development including
fuller IPv6 support, and IPv4 and routing protocol refactoring, and some smaller
-features such as an object naming facility and a new Global ARP package.
+features such as a new Global ARP package and possibly a new Testing and Validation
+suite,
Release 3.3
===========
@@ -68,7 +82,7 @@ http://www.nsnam.org/releases/ns-3.3.tar.bz2
Supported platforms
-------------------
-ns-3.2 has been tested on the following platforms:
+ns-3.3 has been tested on the following platforms:
- linux x86 gcc 4.2, 4.1, and, 3.4.6.
- linux x86_64 gcc 4.3.2, 4.2.3, 4.2.1, 4.1.3, 3.4.6
- MacOS X ppc and x86
diff --git a/bindings/python/ns3_module_bridge.py b/bindings/python/ns3_module_bridge.py
index 013863812..647193174 100644
--- a/bindings/python/ns3_module_bridge.py
+++ b/bindings/python/ns3_module_bridge.py
@@ -103,16 +103,6 @@ def register_Ns3BridgeNetDevice_methods(root_module, cls):
'ns3::Ptr< ns3::NetDevice >',
[param('uint32_t', 'n')],
is_const=True)
- ## bridge-net-device.h: void ns3::BridgeNetDevice::SetName(std::string const name) [member function]
- cls.add_method('SetName',
- 'void',
- [param('std::string const', 'name')],
- is_virtual=True)
- ## bridge-net-device.h: std::string ns3::BridgeNetDevice::GetName() const [member function]
- cls.add_method('GetName',
- 'std::string',
- [],
- is_const=True, is_virtual=True)
## bridge-net-device.h: void ns3::BridgeNetDevice::SetIfIndex(uint32_t const index) [member function]
cls.add_method('SetIfIndex',
'void',
diff --git a/bindings/python/ns3_module_core.py b/bindings/python/ns3_module_core.py
index 155e889e5..e108eba13 100644
--- a/bindings/python/ns3_module_core.py
+++ b/bindings/python/ns3_module_core.py
@@ -115,8 +115,12 @@ def register_types(module):
module.add_class('EnumChecker', parent=root_module['ns3::AttributeChecker'])
## enum.h: ns3::EnumValue [class]
module.add_class('EnumValue', parent=root_module['ns3::AttributeValue'])
+ ## random-variable.h: ns3::ErlangVariable [class]
+ module.add_class('ErlangVariable', parent=root_module['ns3::RandomVariable'])
## random-variable.h: ns3::ExponentialVariable [class]
module.add_class('ExponentialVariable', parent=root_module['ns3::RandomVariable'])
+ ## random-variable.h: ns3::GammaVariable [class]
+ module.add_class('GammaVariable', parent=root_module['ns3::RandomVariable'])
## random-variable.h: ns3::IntEmpiricalVariable [class]
module.add_class('IntEmpiricalVariable', parent=root_module['ns3::EmpiricalVariable'])
## integer.h: ns3::IntegerValue [class]
@@ -261,7 +265,9 @@ def register_methods(root_module):
register_Ns3EmptyAttributeValue_methods(root_module, root_module['ns3::EmptyAttributeValue'])
register_Ns3EnumChecker_methods(root_module, root_module['ns3::EnumChecker'])
register_Ns3EnumValue_methods(root_module, root_module['ns3::EnumValue'])
+ register_Ns3ErlangVariable_methods(root_module, root_module['ns3::ErlangVariable'])
register_Ns3ExponentialVariable_methods(root_module, root_module['ns3::ExponentialVariable'])
+ register_Ns3GammaVariable_methods(root_module, root_module['ns3::GammaVariable'])
register_Ns3IntEmpiricalVariable_methods(root_module, root_module['ns3::IntEmpiricalVariable'])
register_Ns3IntegerValue_methods(root_module, root_module['ns3::IntegerValue'])
register_Ns3LogNormalVariable_methods(root_module, root_module['ns3::LogNormalVariable'])
@@ -479,34 +485,34 @@ def register_Ns3Names_methods(root_module, cls):
cls.add_constructor([param('ns3::Names const &', 'arg0')])
## names.h: ns3::Names::Names() [constructor]
cls.add_constructor([])
- ## names.h: static bool ns3::Names::Add(std::string name, ns3::Ptr obj) [member function]
+ ## names.h: static void ns3::Names::Add(std::string name, ns3::Ptr obj) [member function]
cls.add_method('Add',
- 'bool',
+ 'void',
[param('std::string', 'name'), param('ns3::Ptr< ns3::Object >', 'obj')],
is_static=True)
- ## names.h: static bool ns3::Names::Add(std::string path, std::string name, ns3::Ptr object) [member function]
+ ## names.h: static void ns3::Names::Add(std::string path, std::string name, ns3::Ptr object) [member function]
cls.add_method('Add',
- 'bool',
+ 'void',
[param('std::string', 'path'), param('std::string', 'name'), param('ns3::Ptr< ns3::Object >', 'object')],
is_static=True)
- ## names.h: static bool ns3::Names::Add(ns3::Ptr context, std::string name, ns3::Ptr object) [member function]
+ ## names.h: static void ns3::Names::Add(ns3::Ptr context, std::string name, ns3::Ptr object) [member function]
cls.add_method('Add',
- 'bool',
+ 'void',
[param('ns3::Ptr< ns3::Object >', 'context'), param('std::string', 'name'), param('ns3::Ptr< ns3::Object >', 'object')],
is_static=True)
- ## names.h: static bool ns3::Names::Rename(std::string oldpath, std::string newname) [member function]
+ ## names.h: static void ns3::Names::Rename(std::string oldpath, std::string newname) [member function]
cls.add_method('Rename',
- 'bool',
+ 'void',
[param('std::string', 'oldpath'), param('std::string', 'newname')],
is_static=True)
- ## names.h: static bool ns3::Names::Rename(std::string path, std::string oldname, std::string newname) [member function]
+ ## names.h: static void ns3::Names::Rename(std::string path, std::string oldname, std::string newname) [member function]
cls.add_method('Rename',
- 'bool',
+ 'void',
[param('std::string', 'path'), param('std::string', 'oldname'), param('std::string', 'newname')],
is_static=True)
- ## names.h: static bool ns3::Names::Rename(ns3::Ptr context, std::string oldname, std::string newname) [member function]
+ ## names.h: static void ns3::Names::Rename(ns3::Ptr context, std::string oldname, std::string newname) [member function]
cls.add_method('Rename',
- 'bool',
+ 'void',
[param('ns3::Ptr< ns3::Object >', 'context'), param('std::string', 'oldname'), param('std::string', 'newname')],
is_static=True)
## names.h: static std::string ns3::Names::FindName(ns3::Ptr object) [member function]
@@ -1497,6 +1503,25 @@ def register_Ns3EnumValue_methods(root_module, cls):
is_virtual=True)
return
+def register_Ns3ErlangVariable_methods(root_module, cls):
+ ## random-variable.h: ns3::ErlangVariable::ErlangVariable(ns3::ErlangVariable const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::ErlangVariable const &', 'arg0')])
+ ## random-variable.h: ns3::ErlangVariable::ErlangVariable() [constructor]
+ cls.add_constructor([])
+ ## random-variable.h: ns3::ErlangVariable::ErlangVariable(unsigned int k, double lambda) [constructor]
+ cls.add_constructor([param('unsigned int', 'k'), param('double', 'lambda')])
+ ## random-variable.h: double ns3::ErlangVariable::GetValue() const [member function]
+ cls.add_method('GetValue',
+ 'double',
+ [],
+ is_const=True)
+ ## random-variable.h: double ns3::ErlangVariable::GetValue(unsigned int k, double lambda) const [member function]
+ cls.add_method('GetValue',
+ 'double',
+ [param('unsigned int', 'k'), param('double', 'lambda')],
+ is_const=True)
+ return
+
def register_Ns3ExponentialVariable_methods(root_module, cls):
## random-variable.h: ns3::ExponentialVariable::ExponentialVariable(ns3::ExponentialVariable const & arg0) [copy constructor]
cls.add_constructor([param('ns3::ExponentialVariable const &', 'arg0')])
@@ -1508,6 +1533,25 @@ def register_Ns3ExponentialVariable_methods(root_module, cls):
cls.add_constructor([param('double', 'm'), param('double', 'b')])
return
+def register_Ns3GammaVariable_methods(root_module, cls):
+ ## random-variable.h: ns3::GammaVariable::GammaVariable(ns3::GammaVariable const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::GammaVariable const &', 'arg0')])
+ ## random-variable.h: ns3::GammaVariable::GammaVariable() [constructor]
+ cls.add_constructor([])
+ ## random-variable.h: ns3::GammaVariable::GammaVariable(double alpha, double beta) [constructor]
+ cls.add_constructor([param('double', 'alpha'), param('double', 'beta')])
+ ## random-variable.h: double ns3::GammaVariable::GetValue() const [member function]
+ cls.add_method('GetValue',
+ 'double',
+ [],
+ is_const=True)
+ ## random-variable.h: double ns3::GammaVariable::GetValue(double alpha, double beta) const [member function]
+ cls.add_method('GetValue',
+ 'double',
+ [param('double', 'alpha'), param('double', 'beta')],
+ is_const=True)
+ return
+
def register_Ns3IntEmpiricalVariable_methods(root_module, cls):
## random-variable.h: ns3::IntEmpiricalVariable::IntEmpiricalVariable(ns3::IntEmpiricalVariable const & arg0) [copy constructor]
cls.add_constructor([param('ns3::IntEmpiricalVariable const &', 'arg0')])
@@ -1984,7 +2028,7 @@ def register_Ns3TracedValue__Unsigned_int_methods(root_module, cls):
cls.add_method('ConnectWithoutContext',
'void',
[param('ns3::CallbackBase const &', 'cb')])
- ## traced-value.h: void ns3::TracedValue::Connect(ns3::CallbackBase const & cb, std::basic_string,std::allocator > path) [member function]
+ ## traced-value.h: void ns3::TracedValue::Connect(ns3::CallbackBase const & cb, std::string path) [member function]
cls.add_method('Connect',
'void',
[param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
@@ -1992,7 +2036,7 @@ def register_Ns3TracedValue__Unsigned_int_methods(root_module, cls):
cls.add_method('DisconnectWithoutContext',
'void',
[param('ns3::CallbackBase const &', 'cb')])
- ## traced-value.h: void ns3::TracedValue::Disconnect(ns3::CallbackBase const & cb, std::basic_string,std::allocator > path) [member function]
+ ## traced-value.h: void ns3::TracedValue::Disconnect(ns3::CallbackBase const & cb, std::string path) [member function]
cls.add_method('Disconnect',
'void',
[param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
@@ -2140,7 +2184,7 @@ def register_functions(root_module):
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',
@@ -2160,7 +2204,7 @@ def register_functions(root_module):
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',
diff --git a/bindings/python/ns3_module_csma.py b/bindings/python/ns3_module_csma.py
index 17494ae9e..d7e8e9b4f 100644
--- a/bindings/python/ns3_module_csma.py
+++ b/bindings/python/ns3_module_csma.py
@@ -273,16 +273,6 @@ def register_Ns3CsmaNetDevice_methods(root_module, cls):
cls.add_method('GetEncapsulationMode',
'ns3::CsmaNetDevice::EncapsulationMode',
[])
- ## csma-net-device.h: void ns3::CsmaNetDevice::SetName(std::string const name) [member function]
- cls.add_method('SetName',
- 'void',
- [param('std::string const', 'name')],
- is_virtual=True)
- ## csma-net-device.h: std::string ns3::CsmaNetDevice::GetName() const [member function]
- cls.add_method('GetName',
- 'std::string',
- [],
- is_const=True, is_virtual=True)
## csma-net-device.h: void ns3::CsmaNetDevice::SetIfIndex(uint32_t const index) [member function]
cls.add_method('SetIfIndex',
'void',
diff --git a/bindings/python/ns3_module_emu.py b/bindings/python/ns3_module_emu.py
index 54ffede89..4fa5d12a1 100644
--- a/bindings/python/ns3_module_emu.py
+++ b/bindings/python/ns3_module_emu.py
@@ -80,16 +80,6 @@ def register_Ns3EmuNetDevice_methods(root_module, cls):
cls.add_method('SetAddress',
'void',
[param('ns3::Mac48Address', 'addr')])
- ## emu-net-device.h: void ns3::EmuNetDevice::SetName(std::string const name) [member function]
- cls.add_method('SetName',
- 'void',
- [param('std::string const', 'name')],
- is_virtual=True)
- ## emu-net-device.h: std::string ns3::EmuNetDevice::GetName() const [member function]
- cls.add_method('GetName',
- 'std::string',
- [],
- is_const=True, is_virtual=True)
## emu-net-device.h: void ns3::EmuNetDevice::SetIfIndex(uint32_t const index) [member function]
cls.add_method('SetIfIndex',
'void',
diff --git a/bindings/python/ns3_module_helper.py b/bindings/python/ns3_module_helper.py
index bdcf01d60..583c388bf 100644
--- a/bindings/python/ns3_module_helper.py
+++ b/bindings/python/ns3_module_helper.py
@@ -946,6 +946,8 @@ def register_Ns3StaticMulticastRouteHelper_methods(root_module, cls):
def register_Ns3TapBridgeHelper_methods(root_module, cls):
## tap-bridge-helper.h: ns3::TapBridgeHelper::TapBridgeHelper(ns3::TapBridgeHelper const & arg0) [copy constructor]
cls.add_constructor([param('ns3::TapBridgeHelper const &', 'arg0')])
+ ## tap-bridge-helper.h: ns3::TapBridgeHelper::TapBridgeHelper() [constructor]
+ cls.add_constructor([])
## tap-bridge-helper.h: ns3::TapBridgeHelper::TapBridgeHelper(ns3::Ipv4Address gateway) [constructor]
cls.add_constructor([param('ns3::Ipv4Address', 'gateway')])
## tap-bridge-helper.h: void ns3::TapBridgeHelper::SetAttribute(std::string n1, ns3::AttributeValue const & v1) [member function]
@@ -968,6 +970,10 @@ def register_Ns3TapBridgeHelper_methods(root_module, cls):
cls.add_method('Install',
'ns3::Ptr< ns3::NetDevice >',
[param('std::string', 'nodeName'), param('std::string', 'ndName')])
+ ## tap-bridge-helper.h: ns3::Ptr ns3::TapBridgeHelper::Install(ns3::Ptr node, ns3::Ptr nd, ns3::AttributeValue const & v1) [member function]
+ cls.add_method('Install',
+ 'ns3::Ptr< ns3::NetDevice >',
+ [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('ns3::AttributeValue const &', 'v1')])
return
def register_Ns3UdpEchoClientHelper_methods(root_module, cls):
diff --git a/bindings/python/ns3_module_node.py b/bindings/python/ns3_module_node.py
index 72cc4cd97..5b08a1038 100644
--- a/bindings/python/ns3_module_node.py
+++ b/bindings/python/ns3_module_node.py
@@ -2311,16 +2311,6 @@ def register_Ns3Channel_methods(root_module, cls):
is_static=True)
## channel.h: ns3::Channel::Channel() [constructor]
cls.add_constructor([])
- ## channel.h: ns3::Channel::Channel(std::string name) [constructor]
- cls.add_constructor([param('std::string', 'name')])
- ## channel.h: void ns3::Channel::SetName(std::string arg0) [member function]
- cls.add_method('SetName',
- 'void',
- [param('std::string', 'arg0')])
- ## channel.h: std::string ns3::Channel::GetName() [member function]
- cls.add_method('GetName',
- 'std::string',
- [])
## channel.h: uint32_t ns3::Channel::GetNDevices() const [member function]
cls.add_method('GetNDevices',
'uint32_t',
@@ -2750,16 +2740,6 @@ def register_Ns3NetDevice_methods(root_module, cls):
'ns3::TypeId',
[],
is_static=True)
- ## net-device.h: void ns3::NetDevice::SetName(std::string const name) [member function]
- cls.add_method('SetName',
- 'void',
- [param('std::string const', 'name')],
- is_pure_virtual=True, is_virtual=True)
- ## net-device.h: std::string ns3::NetDevice::GetName() const [member function]
- cls.add_method('GetName',
- 'std::string',
- [],
- is_pure_virtual=True, is_const=True, is_virtual=True)
## net-device.h: void ns3::NetDevice::SetIfIndex(uint32_t const index) [member function]
cls.add_method('SetIfIndex',
'void',
@@ -3016,16 +2996,6 @@ def register_Ns3SimpleNetDevice_methods(root_module, cls):
cls.add_method('SetAddress',
'void',
[param('ns3::Mac48Address', 'address')])
- ## simple-net-device.h: void ns3::SimpleNetDevice::SetName(std::string const name) [member function]
- cls.add_method('SetName',
- 'void',
- [param('std::string const', 'name')],
- is_virtual=True)
- ## simple-net-device.h: std::string ns3::SimpleNetDevice::GetName() const [member function]
- cls.add_method('GetName',
- 'std::string',
- [],
- is_const=True, is_virtual=True)
## simple-net-device.h: void ns3::SimpleNetDevice::SetIfIndex(uint32_t const index) [member function]
cls.add_method('SetIfIndex',
'void',
diff --git a/bindings/python/ns3_module_point_to_point.py b/bindings/python/ns3_module_point_to_point.py
index 1541d7d25..2360f1f62 100644
--- a/bindings/python/ns3_module_point_to_point.py
+++ b/bindings/python/ns3_module_point_to_point.py
@@ -175,16 +175,6 @@ def register_Ns3PointToPointNetDevice_methods(root_module, cls):
'uint16_t',
[],
is_const=True)
- ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetName(std::string const name) [member function]
- cls.add_method('SetName',
- 'void',
- [param('std::string const', 'name')],
- is_virtual=True)
- ## point-to-point-net-device.h: std::string ns3::PointToPointNetDevice::GetName() const [member function]
- cls.add_method('GetName',
- 'std::string',
- [],
- is_const=True, is_virtual=True)
## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetIfIndex(uint32_t const index) [member function]
cls.add_method('SetIfIndex',
'void',
diff --git a/bindings/python/ns3_module_tap_bridge.py b/bindings/python/ns3_module_tap_bridge.py
index 66185dc52..060f909a6 100644
--- a/bindings/python/ns3_module_tap_bridge.py
+++ b/bindings/python/ns3_module_tap_bridge.py
@@ -5,6 +5,8 @@ def register_types(module):
## tap-bridge.h: ns3::TapBridge [class]
module.add_class('TapBridge', parent=root_module['ns3::NetDevice'])
+ ## tap-bridge.h: ns3::TapBridge::Mode [enumeration]
+ module.add_enum('Mode', ['ILLEGAL', 'CONFIGURE_LOCAL', 'USE_LOCAL', 'USE_BRIDGE'], outer_class=root_module['ns3::TapBridge'])
## Register a nested module for the namespace Config
@@ -76,16 +78,14 @@ def register_Ns3TapBridge_methods(root_module, cls):
cls.add_method('Stop',
'void',
[param('ns3::Time', 'tStop')])
- ## tap-bridge.h: void ns3::TapBridge::SetName(std::string const name) [member function]
- cls.add_method('SetName',
+ ## tap-bridge.h: void ns3::TapBridge::SetMode(ns3::TapBridge::Mode mode) [member function]
+ cls.add_method('SetMode',
'void',
- [param('std::string const', 'name')],
- is_virtual=True)
- ## tap-bridge.h: std::string ns3::TapBridge::GetName() const [member function]
- cls.add_method('GetName',
- 'std::string',
- [],
- is_const=True, is_virtual=True)
+ [param('ns3::TapBridge::Mode', 'mode')])
+ ## tap-bridge.h: ns3::TapBridge::Mode ns3::TapBridge::GetMode() [member function]
+ cls.add_method('GetMode',
+ 'ns3::TapBridge::Mode',
+ [])
## tap-bridge.h: void ns3::TapBridge::SetIfIndex(uint32_t const index) [member function]
cls.add_method('SetIfIndex',
'void',
diff --git a/bindings/python/ns3_module_wifi.py b/bindings/python/ns3_module_wifi.py
index 564128159..383402cb2 100644
--- a/bindings/python/ns3_module_wifi.py
+++ b/bindings/python/ns3_module_wifi.py
@@ -228,8 +228,8 @@ def register_Ns3InterferenceHelper_methods(root_module, cls):
'ns3::Ptr< ns3::ErrorRateModel >',
[],
is_const=True)
- ## interference-helper.h: double ns3::InterferenceHelper::GetNoiseFloorW() const [member function]
- cls.add_method('GetNoiseFloorW',
+ ## interference-helper.h: double ns3::InterferenceHelper::GetNoiseFigure() const [member function]
+ cls.add_method('GetNoiseFigure',
'double',
[],
is_const=True)
@@ -237,10 +237,10 @@ def register_Ns3InterferenceHelper_methods(root_module, cls):
cls.add_method('SetErrorRateModel',
'void',
[param('ns3::Ptr< ns3::ErrorRateModel >', 'rate')])
- ## interference-helper.h: void ns3::InterferenceHelper::SetNoiseFloorW(double noiseFloor) [member function]
- cls.add_method('SetNoiseFloorW',
+ ## interference-helper.h: void ns3::InterferenceHelper::SetNoiseFigure(double value) [member function]
+ cls.add_method('SetNoiseFigure',
'void',
- [param('double', 'noiseFloor')])
+ [param('double', 'value')])
return
def register_Ns3InterferenceHelperSnrPer_methods(root_module, cls):
@@ -727,8 +727,8 @@ def register_Ns3AmrrWifiRemoteStation_methods(root_module, cls):
def register_Ns3ArfWifiRemoteStation_methods(root_module, cls):
## arf-wifi-manager.h: ns3::ArfWifiRemoteStation::ArfWifiRemoteStation(ns3::ArfWifiRemoteStation const & arg0) [copy constructor]
cls.add_constructor([param('ns3::ArfWifiRemoteStation const &', 'arg0')])
- ## arf-wifi-manager.h: ns3::ArfWifiRemoteStation::ArfWifiRemoteStation(ns3::Ptr stations, int minTimerTimeout, int minSuccessThreshold) [constructor]
- cls.add_constructor([param('ns3::Ptr< ns3::ArfWifiManager >', 'stations'), param('int', 'minTimerTimeout'), param('int', 'minSuccessThreshold')])
+ ## arf-wifi-manager.h: ns3::ArfWifiRemoteStation::ArfWifiRemoteStation(ns3::Ptr manager) [constructor]
+ cls.add_constructor([param('ns3::Ptr< ns3::ArfWifiManager >', 'manager')])
## arf-wifi-manager.h: void ns3::ArfWifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function]
cls.add_method('DoReportRxOk',
'void',
@@ -1667,6 +1667,11 @@ def register_Ns3WifiRemoteStationManager_methods(root_module, cls):
'bool',
[],
is_const=True)
+ ## wifi-remote-station-manager.h: ns3::WifiMode ns3::WifiRemoteStationManager::GetNonUnicastMode() const [member function]
+ cls.add_method('GetNonUnicastMode',
+ 'ns3::WifiMode',
+ [],
+ is_const=True)
## wifi-remote-station-manager.h: ns3::WifiRemoteStation * ns3::WifiRemoteStationManager::Lookup(ns3::Mac48Address address) [member function]
cls.add_method('Lookup',
'ns3::WifiRemoteStation *',
@@ -1707,10 +1712,10 @@ def register_Ns3YansWifiPhy_methods(root_module, cls):
cls.add_method('SetStandard',
'void',
[param('ns3::WifiPhyStandard', 'standard')])
- ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetRxNoise(double ratio) [member function]
- cls.add_method('SetRxNoise',
+ ## yans-wifi-phy.h: void ns3::YansWifiPhy::SetRxNoiseFigure(double noiseFigureDb) [member function]
+ cls.add_method('SetRxNoiseFigure',
'void',
- [param('double', 'ratio')])
+ [param('double', 'noiseFigureDb')])
## yans-wifi-phy.h: void ns3::YansWifiPhy::SetTxPowerStart(double start) [member function]
cls.add_method('SetTxPowerStart',
'void',
@@ -1751,8 +1756,8 @@ def register_Ns3YansWifiPhy_methods(root_module, cls):
cls.add_method('SetMobility',
'void',
[param('ns3::Ptr< ns3::Object >', 'mobility')])
- ## yans-wifi-phy.h: double ns3::YansWifiPhy::GetRxNoise() const [member function]
- cls.add_method('GetRxNoise',
+ ## yans-wifi-phy.h: double ns3::YansWifiPhy::GetRxNoiseFigure() const [member function]
+ cls.add_method('GetRxNoiseFigure',
'double',
[],
is_const=True)
@@ -1900,8 +1905,8 @@ def register_Ns3YansWifiPhy_methods(root_module, cls):
def register_Ns3AarfWifiRemoteStation_methods(root_module, cls):
## aarf-wifi-manager.h: ns3::AarfWifiRemoteStation::AarfWifiRemoteStation(ns3::AarfWifiRemoteStation const & arg0) [copy constructor]
cls.add_constructor([param('ns3::AarfWifiRemoteStation const &', 'arg0')])
- ## aarf-wifi-manager.h: ns3::AarfWifiRemoteStation::AarfWifiRemoteStation(ns3::Ptr stations, uint32_t minTimerThreshold, uint32_t minSuccessThreshold, double successK, uint32_t maxSuccessThreshold, double timerK) [constructor]
- cls.add_constructor([param('ns3::Ptr< ns3::AarfWifiManager >', 'stations'), param('uint32_t', 'minTimerThreshold'), param('uint32_t', 'minSuccessThreshold'), param('double', 'successK'), param('uint32_t', 'maxSuccessThreshold'), param('double', 'timerK')])
+ ## aarf-wifi-manager.h: ns3::AarfWifiRemoteStation::AarfWifiRemoteStation(ns3::Ptr stations) [constructor]
+ cls.add_constructor([param('ns3::Ptr< ns3::AarfWifiManager >', 'stations')])
## aarf-wifi-manager.h: void ns3::AarfWifiRemoteStation::ReportRecoveryFailure() [member function]
cls.add_method('ReportRecoveryFailure',
'void',
@@ -1912,6 +1917,11 @@ def register_Ns3AarfWifiRemoteStation_methods(root_module, cls):
'void',
[],
visibility='private', is_virtual=True)
+ ## aarf-wifi-manager.h: ns3::Ptr ns3::AarfWifiRemoteStation::GetManager() const [member function]
+ cls.add_method('GetManager',
+ 'ns3::Ptr< ns3::WifiRemoteStationManager >',
+ [],
+ is_const=True, visibility='private', is_virtual=True)
return
def register_Ns3AdhocWifiMac_methods(root_module, cls):
@@ -2697,16 +2707,6 @@ def register_Ns3WifiNetDevice_methods(root_module, cls):
'ns3::Ptr< ns3::WifiRemoteStationManager >',
[],
is_const=True)
- ## wifi-net-device.h: void ns3::WifiNetDevice::SetName(std::string const name) [member function]
- cls.add_method('SetName',
- 'void',
- [param('std::string const', 'name')],
- is_virtual=True)
- ## wifi-net-device.h: std::string ns3::WifiNetDevice::GetName() const [member function]
- cls.add_method('GetName',
- 'std::string',
- [],
- is_const=True, is_virtual=True)
## wifi-net-device.h: void ns3::WifiNetDevice::SetIfIndex(uint32_t const index) [member function]
cls.add_method('SetIfIndex',
'void',
diff --git a/bindings/python/ns3modulegen.py b/bindings/python/ns3modulegen.py
index 12363b1e4..50f6f2653 100755
--- a/bindings/python/ns3modulegen.py
+++ b/bindings/python/ns3modulegen.py
@@ -145,6 +145,7 @@ def main():
if 'TapBridge' not in enabled_features:
for clsname in ['TapBridge', 'TapBridgeHelper']:
root_module.classes.remove(root_module['ns3::%s' % clsname])
+ root_module.enums.remove(root_module['ns3::TapBridge::Mode'])
root_module.generate(out, '_ns3')
diff --git a/bindings/python/waf b/bindings/python/waf
old mode 100644
new mode 100755
diff --git a/bindings/python/wscript b/bindings/python/wscript
index 89cdccfec..d33fdf381 100644
--- a/bindings/python/wscript
+++ b/bindings/python/wscript
@@ -273,7 +273,7 @@ class all_ns3_headers_taskgen(TaskGen.task_gen):
def apply(self):
## get all of the ns3 headers
- ns3_dir_node = Build.bld.path.find_dir("ns3")
+ ns3_dir_node = self.bld.path.find_dir("ns3")
all_headers_inputs = []
for filename in self.to_list(self.source):
@@ -284,7 +284,7 @@ class all_ns3_headers_taskgen(TaskGen.task_gen):
## if self.source was empty, include all ns3 headers in enabled modules
if not all_headers_inputs:
- for ns3headers in Build.bld.all_task_gen:
+ for ns3headers in self.bld.all_task_gen:
if type(ns3headers).__name__ == 'ns3header_taskgen': # XXX: find less hackish way to compare
## skip headers not part of enabled modules
if self.env['NS3_ENABLED_MODULES']:
@@ -307,7 +307,7 @@ class all_ns3_headers_taskgen(TaskGen.task_gen):
pass
-def get_modules_and_headers():
+def get_modules_and_headers(bld):
"""
Gets a dict of
module_name => ([module_dep1, module_dep2, ...], [module_header1, module_header2, ...])
@@ -315,13 +315,13 @@ def get_modules_and_headers():
"""
retval = {}
- for module in Build.bld.all_task_gen:
+ for module in bld.all_task_gen:
if not module.name.startswith('ns3-'):
continue
module_name = module.name[4:] # strip the ns3- prefix
## find the headers object for this module
headers = []
- for ns3headers in Build.bld.all_task_gen:
+ for ns3headers in bld.all_task_gen:
if type(ns3headers).__name__ != 'ns3header_taskgen': # XXX: find less hackish way to compare
continue
if ns3headers.module != module_name:
@@ -338,8 +338,9 @@ class python_scan_task(Task.TaskBase):
"""
after = 'gen_everything_h_task'
before = 'cc cxx'
- def __init__(self, curdirnode, env):
- super(python_scan_task, self).__init__()
+ def __init__(self, curdirnode, env, bld):
+ self.bld = bld
+ super(python_scan_task, self).__init__(generator=self)
self.curdirnode = curdirnode
self.env = env
@@ -356,7 +357,7 @@ class python_scan_task(Task.TaskBase):
os.path.join(self.curdirnode.abspath(), 'ns3modulegen_generated.py'), # output file
]
scan = subprocess.Popen(argv, stdin=subprocess.PIPE)
- scan.stdin.write(repr(get_modules_and_headers()))
+ scan.stdin.write(repr(get_modules_and_headers(self.bld)))
scan.stdin.close()
retval = scan.wait()
print "Scan finished with exit code", retval
@@ -365,7 +366,7 @@ class python_scan_task(Task.TaskBase):
# signal stop (we generated files into the source dir and WAF
# can't cope with it, so we have to force the user to restart
# WAF)
- Build.bld.generator.stop = 1
+ self.bld.generator.stop = 1
return 0
@@ -384,7 +385,7 @@ def build(bld):
if Options.options.python_scan:
if not env['ENABLE_PYTHON_SCANNING']:
raise Utils.WafError("Cannot re-scan python bindings: (py)gccxml not available")
- python_scan_task(bld.path, env)
+ python_scan_task(bld.path, env, bld)
return
## Get a list of scanned modules; the set of scanned modules
@@ -412,7 +413,7 @@ def build(bld):
'ns3modulegen.log',
]
argv = ['NS3_ENABLED_FEATURES=${FEATURES}', '${PYTHON}', '${SRC[0]}', '${TGT[0]}']
- argv.extend(get_modules_and_headers().iterkeys())
+ argv.extend(get_modules_and_headers(bld).iterkeys())
for module in scanned_modules:
source.append("ns3_module_%s.py" % module)
local = "ns3_module_%s__local.py" % module
@@ -429,16 +430,13 @@ def build(bld):
if was_enabled:
features.append(name)
- bindgen = bld.new_task_gen('command', source=source, target=target,
- command=argv, variables=dict(FEATURES=(','.join(features))))
+ bindgen = bld.new_task_gen('command', source=source, target=target, command=argv)
+ bindgen.env['FEATURES'] = ','.join(features)
+ bindgen.dep_vars = ['FEATURES']
bindgen.before = 'cxx'
bindgen.after = 'gen_everything_h_task'
+ bindgen.name = "pybindgen-command"
- ## we build python bindings if either we have the tools to
- ## generate them or if the pregenerated source file is already
- ## present in the source dir.
- if env['ENABLE_PYTHON_BINDINGS'] \
- or os.path.exists(os.path.join(bld.path.abspath(), 'ns3module.cc')):
pymod = bld.new_task_gen('cxx', 'shlib', 'pyext')
pymod.source = ['ns3module.cc', 'ns3module_helpers.cc']
pymod.includes = '.'
diff --git a/doc/tutorial/building-topologies.texi b/doc/tutorial/building-topologies.texi
index 3819b124f..62ab61d42 100644
--- a/doc/tutorial/building-topologies.texi
+++ b/doc/tutorial/building-topologies.texi
@@ -53,6 +53,17 @@ example, but we will go over the entire script and examine some of the output.
Just as in the @code{first.cc} example (and in all ns-3 examples) the file
begins with an emacs mode line and some GPL boilerplate.
+The actual code begins by loading module include files just as was done in the
+@code{first.cc} example.
+
+@verbatim
+ #include "ns3/core-module.h"
+ #include "ns3/simulator-module.h"
+ #include "ns3/node-module.h"
+ #include "ns3/helper-module.h"
+ #include "ns3/global-routing-module.h"
+@end verbatim
+
One thing that can be surprisingly useful is a small bit of ASCII art that
shows a cartoon of the network topology constructed in the example. You will
find a similar ``drawing'' in most of our examples.
@@ -75,53 +86,47 @@ three ``extra'' nodes as seen below:
// LAN 10.1.2.0
@end verbatim
-The actual code begins by loading module include files just as was done in the
-@code{first.cc} example. Then the ns-3 namespace is @code{used} and a logging
-component is defined. This is all just as it was in @code{first.cc}, so there
-is nothing new yet.
+Then the ns-3 namespace is @code{used} and a logging component is defined.
+This is all just as it was in @code{first.cc}, so there is nothing new yet.
-@verbatim
- #include "ns3/core-module.h"
- #include "ns3/simulator-module.h"
- #include "ns3/node-module.h"
- #include "ns3/helper-module.h"
- #include "ns3/global-routing-module.h"
-
+@verbatim
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("SecondScriptExample");
@end verbatim
-The main program begins by enabling the @code{UdpEchoClientApplication} and
-@code{UdpEchoServerApplication} logging components at @code{INFO} level so
-we can see some output when we run the example. This should be entirely
-familiar to you so far.
+The main program begins with a slightly different twist. We use a verbose
+flag to determine whether or not the @code{UdpEchoClientApplication} and
+@code{UdpEchoServerApplication} logging components are enabled. This flag
+defaults to true (the logging components are enabled) but allows us to turn
+off logging during regression testing of this example.
-@verbatim
- int
- main (int argc, char *argv[])
- {
- LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
- LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
-@end verbatim
-
-A fixed seed is provided to the random number generators so that they will
-generate repeatable results.
-
-@verbatim
- RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
-@end verbatim
-
-Next, you will see some familiar code that will allow you to change the number
+You will see some familiar code that will allow you to change the number
of devices on the CSMA network via command line argument. We did something
similar when we allowed the number of packets sent to be changed in the section
-on command line arguments.
+on command line arguments. The last line makes sure you have at least one
+``extra'' node.
+
+The code consists of variations of previously covered API so you should be
+entirely comfortable with the following code at this point in the tutorial.
@verbatim
+ bool verbose = true;
uint32_t nCsma = 3;
+
CommandLine cmd;
- cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
+ cmd.AddValue (``nCsma'', ``Number of \"extra\" CSMA nodes/devices'', nCsma);
+ cmd.AddValue (``verbose'', ``Tell echo applications to log if true'', verbose);
+
cmd.Parse (argc,argv);
+
+ if (verbose)
+ {
+ LogComponentEnable(``UdpEchoClientApplication'', LOG_LEVEL_INFO);
+ LogComponentEnable(``UdpEchoServerApplication'', LOG_LEVEL_INFO);
+ }
+
+ nCsma = nCsma == 0 ? 1 : nCsma;
@end verbatim
The next step is to create two nodes that we will connect via the
@@ -147,12 +152,15 @@ The next line of code @code{Gets} the first node (as in having an index of one)
from the point-to-point node container and adds it to the container of nodes
that will get CSMA devices. The node in question is going to end up with a
point-to-point device @emph{and} a CSMA device. We then create a number of
-``extra'' nodes that compose the remainder of the CSMA network.
+``extra'' nodes that compose the remainder of the CSMA network. Since we
+already have one node in the CSMA network -- the one that will have both a
+point-to-point and CSMA net device, the number of ``extra'' nodes means the
+number nodes you desire in the CSMA section minus one.
The next bit of code should be quite familiar by now. We instantiate a
-@code{PointToPointHelper} and set the associated default attributes so that
-we create a five megabit per second transmitter on devices created using the
-helper and a two millisecond delay on channels created by the helper.
+@code{PointToPointHelper} and set the associated default @code{Attributes} so
+that we create a five megabit per second transmitter on devices created using
+the helper and a two millisecond delay on channels created by the helper.
@verbatim
PointToPointHelper pointToPoint;
@@ -171,13 +179,13 @@ We mentioned above that you were going to see a helper for CSMA devices and
channels, and the next lines introduce them. The @code{CsmaHelper} works just
like a @code{PointToPointHelper}, but it creates and connects CSMA devices and
channels. In the case of a CSMA device and channel pair, notice that the data
-rate is specified by a @emph{channel} attribute instead of a device attribute.
-This is because a real CSMA network does not allow one to mix, for example,
-10Base-T and 100Base-T devices on a given channel. We first set the data rate
-to 100 megabits per second, and then set the speed-of-light delay of the channel
-to 6560 nano-seconds (arbitrarily chosen as 1 nanosecond per foot over a 100
-meter segment). Notice that you can set an attribute using its native data
-type.
+rate is specified by a @emph{channel} @code{Attribute} instead of a device
+@code{Attribute}. This is because a real CSMA network does not allow one to mix,
+for example, 10Base-T and 100Base-T devices on a given channel. We first set
+the data rate to 100 megabits per second, and then set the speed-of-light delay
+of the channel to 6560 nano-seconds (arbitrarily chosen as 1 nanosecond per foot
+over a 100 meter segment). Notice that you can set an @code{Attribute} using
+its native data type.
@verbatim
CsmaHelper csma;
@@ -244,8 +252,8 @@ nodes that has a CSMA node and the client on the node having only a
point-to-point device.
First, we set up the echo server. We create a @code{UdpEchoServerHelper} and
-provide a required attribute value to the constructor which is the server port
-number. Recall that this port can be changed later using the
+provide a required @code{Attribute} value to the constructor which is the server
+port number. Recall that this port can be changed later using the
@code{SetAttribute} method if desired, but we require it to be provided to
the constructor.
@@ -268,7 +276,7 @@ if we create @code{nCsma} ``extra'' nodes the last one will be at index
code.
The client application is set up exactly as we did in the @code{first.cc}
-example script. Again, we provide required attributes to the
+example script. Again, we provide required @code{Attributes} to the
@code{UdpEchoClientHelper} in the constructor (in this case the remote address
and port). We tell the client to send packets to the server we just installed
on the last of the ``extra'' CSMA nodes. We install the client on the
@@ -286,7 +294,7 @@ leftmost point-to-point node seen in the topology illustration.
@end verbatim
Since we have actually built an internetwork here, we need some form of
-internetwork routing. @command{Ns-3} provides what we call a global route
+internetwork routing. @command{ns-3} provides what we call a global route
manager to set up the routing tables on nodes. This route manager has a
global function that runs though the nodes created for the simulation and does
the hard work of setting up routing for you.
@@ -302,15 +310,40 @@ is a one-liner:
GlobalRouteManager::PopulateRoutingTables ();
@end verbatim
-The remainder of the script should be very familiar to you. We just enable
-pcap tracing, run the simulation and exit the script. Notice that enabling
-pcap tracing using the CSMA helper is done in the same way as for the pcap
-tracing with the point-to-point helper.
+Next we enable pcap tracing. The first line of code to enable pcap tracing
+in the point-to-point helper should be familiar to you by now. The second
+line enables pcap tracing in the CSMA helper and there is an extra parameter
+you haven't encountered yet.
+
+@verbatim
+ PointToPointHelper::EnablePcapAll ("second");
+ CsmaHelper::EnablePcap ("second", csmaDevices.Get (0), true);
+@end verbatim
+
+The CSMA network is a multi-point-to-point network. This means that there
+can (and are in this case) multiple endpoints on a shared medium. Each of
+these endpoints has a net device associated with it. There are two basic
+alternatives to gathering trace information from such a network. One way
+is to create a trace file for each net device and store only the packets
+that are emitted or consumed by that net device. Another way is to pick
+one of the devices and place it in promiscuous mode. That single device
+then ``sniffs'' the network for all packets and stores them in a single
+pcap file. This is how @code{tcpdump}, for example, works. That final
+parameter tells the CSMA helper whether or not to capture packets in
+promiscuous mode.
+
+In this example, we are going to select one of the devices on the CSMA
+network and ask it to perform a promiscuous sniff of the network, thereby
+emulating what @code{tcpdump} would do. If you were on a Linux machine
+you might do something like @code{tcpdump -i eth0} to get the trace.
+In this case, we specify the device using @code{csmaDevices.Get(0)},
+which selects the zeroth device in the container. Setting the final
+parameter to true enables promiscuous captures.
+
+The last section of code just runs and cleans up the simulation just like
+the @code{first.cc} example.
@verbatim
- PointToPointHelper::EnablePcapAll ("second");
- CsmaHelper::EnablePcapAll ("second");
-
Simulator::Run ();
Simulator::Destroy ();
return 0;
@@ -318,27 +351,40 @@ tracing with the point-to-point helper.
@end verbatim
In order to run this example, you have to copy the @code{second.cc} example
-script into the scratch directory and use Waf to build just as you did with
+script into the scratch directory and use waf to build just as you did with
the @code{first.cc} example. If you are in the top-level directory of the
repository you would type,
@verbatim
- cp examples/second.cc scratch/
+ cp examples/second.cc scratch/mysecond.cc
./waf
- ./waf --run scratch/second
@end verbatim
+Warning: We use the file @code{second.cc} as one of our regression tests to
+verify that it works exactly as we think it should in order to make your
+tutorial experience a positive one. This means that an executable named
+@code{second} already exists in the project. To avoid any confusion
+about what you are executing, please do the renaming to @code{mysecond.cc}
+suggested above.
+
+If you are following the tutorial religiously (you are, aren't you) you will
+still have the NS_LOG variable set, so go ahead and clear that variable and
+run the program.
+
+@verbatim
+ export NS_LOG=
+ ./waf --run scratch/mysecond
+#end verbatim
+
Since we have set up the UDP echo applications to log just as we did in
@code{first.cc}, you will see similar output when you run the script.
@verbatim
- ~/repos/ns-3-dev > ./waf --run scratch/second
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
+ Entering directory `repos/ns-3-allinone/ns-3-dev/build'
+ Build finished successfully (00:00:00)
Sent 1024 bytes to 10.1.2.4
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.2.4
- ~/repos/ns-3-dev >
@end verbatim
Recall that the first message, @code{Sent 1024 bytes to 10.1.2.4} is the
@@ -349,38 +395,41 @@ the echo packet. The final message, @code{Received 1024 bytes from 10.1.2.4}
is from the echo client, indicating that it has received its echo back from
the server.
-If you now go and look in the top level directory, you will find a number of
-trace files:
+If you now go and look in the top level directory, you will find two trace
+files:
@verbatim
- ~/repos/ns-3-dev > ls *.pcap
- second-0-0.pcap second-1-1.pcap second-3-0.pcap
- second-1-0.pcap second-2-0.pcap second-4-0.pcap
- ~/repos/ns-3-dev >
+ second-0-0.pcap second-1-0.pcap second-2-0.pcap
@end verbatim
Let's take a moment to look at the naming of these files. They all have the
same form, @code{--.pcap}. For example, the first file
in the listing is @code{second-0-0.pcap} which is the pcap trace from node
-zero - device zero. There are no other devices on node zero so this is the
-only trace from that node.
+zero, device zero. This is the point-to-point net device on node zero. The
+file @code{second-1-0.pcap} is the pcap trace for device zero on node one,
+also a point-to-point net device; and the file @code{second-2-0.pcap} is the
+pcap trace for device zero on node two.
-Now look at @code{second-1-0.pcap} and @code{second-1-1.pcap}. The former is
-the pcap trace for device zero on node one and the latter is the trace file
-for device one on node one. If you refer back to the topology illustration at
-the start of the section, you will see that node one is the node that has
-both a point-to-point device and a CSMA device, so we should expect two pcap
-traces for that node.
+If you refer back to the topology illustration at the start of the section,
+you will see that node zero is the leftmost node of the point-to-point link
+and node one is the node that has both a point-to-point device and a CSMA
+device. You will see that node two is the first ``extra'' node on the CSMA
+network and its device zero was selected as the device to capture the
+promiscuous-mode trace.
Now, let's follow the echo packet through the internetwork. First, do a
tcpdump of the trace file for the leftmost point-to-point node --- node zero.
@verbatim
- ~/repos/ns-3-dev > tcpdump -r second-0-0.pcap -nn -tt
+ tcpdump -nn -tt -r second-0-0.pcap
+@end verbatim
+
+You should see the contents of the pcap file displayed:
+
+@verbatim
reading from file second-0-0.pcap, link-type PPP (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024
- 2.007382 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024
- ~/repos/ns-3-dev >
+ 2.007602 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024
@end verbatim
The first line of the dump indicates that the link type is PPP (point-to-point)
@@ -391,134 +440,163 @@ point-to-point link and be received by the point-to-point net device on node
one. Let's take a look:
@verbatim
- ~/repos/ns-3-dev > tcpdump -r second-1-0.pcap -nn -tt
- reading from file second-1-0.pcap, link-type PPP (PPP)
- 2.003686 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024
- 2.003695 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024
- ~/repos/ns-3-dev >
+ tcpdump -nn -tt -r second-1-0.pcap
+@end verbatim
+
+You should now see the pcap trace output of the other side of the point-to-point
+link:
+
+@verbatim
+reading from file second-1-0.pcap, link-type PPP (PPP)
+2.003686 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024
+2.003915 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024
@end verbatim
Here we see that the link type is also PPP as we would expect. You see the
-packet from IP address 10.1.1.1 headed toward 10.1.2.4 appear on this
-interface. Now, internally to this node, the packet will be forwarded to the
-CSMA interface and we should see it pop out the other device headed for its
-ultimate destination. Let's then look at second-1-1.pcap and see if its there.
+packet from IP address 10.1.1.1 (that was sent at 2.000000 seconds) headed
+toward IP address 10.1.2.4 appear on this interface. Now, internally to this
+node, the packet will be forwarded to the CSMA interface and we should see it
+pop out on that device headed for its ultimate destination.
+
+Remember that we selected node 2 as the promiscuous sniffer node for the CSMA
+network so let's then look at second-2-0.pcap and see if its there.
@verbatim
- ~/repos/ns-3-dev > tcpdump -r second-1-1.pcap -nn -tt
- reading from file second-1-1.pcap, link-type EN10MB (Ethernet)
- 2.003686 arp who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1
- 2.003687 arp reply 10.1.2.4 is-at 00:00:00:00:00:06
- 2.003687 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024
- 2.003691 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4
- 2.003691 arp reply 10.1.2.1 is-at 00:00:00:00:00:03
- 2.003695 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024
- ~/repos/ns-3-dev >
+ tcpdump -nn -tt -r second-2-0.pcap
+@end verbatim
+
+You should now see the promiscuous dump of node two, device zero:
+
+@verbatim
+ reading from file second-2-0.pcap, link-type EN10MB (Ethernet)
+ 2.003696 arp who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1
+ 2.003707 arp reply 10.1.2.4 is-at 00:00:00:00:00:06
+ 2.003801 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024
+ 2.003811 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4
+ 2.003822 arp reply 10.1.2.1 is-at 00:00:00:00:00:03
+ 2.003915 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024
@end verbatim
As you can see, the link type is now ``Ethernet''. Something new has appeared,
though. The bus network needs @code{ARP}, the Address Resolution Protocol.
-The node knows it needs to send the packet to IP address 10.1.2.4, but it
+Node one knows it needs to send the packet to IP address 10.1.2.4, but it
doesn't know the MAC address of the corresponding node. It broadcasts on the
CSMA network (ff:ff:ff:ff:ff:ff) asking for the device that has IP address
10.1.2.4. In this case, the rightmost node replies saying it is at MAC address
-00:00:00:00:00:06. This exchange is seen in the following lines,
+00:00:00:00:00:06. (Note that node two is not directly involved in this
+exchange, but is sniffing the network and reporting all of the traffic it sees.)
+
+This exchange is seen in the following lines,
@verbatim
- 2.003686 arp who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1
- 2.003687 arp reply 10.1.2.4 is-at 00:00:00:00:00:06
+ 2.003696 arp who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1
+ 2.003707 arp reply 10.1.2.4 is-at 00:00:00:00:00:06
@end verbatim
Then node one, device one goes ahead and sends the echo packet to the UDP echo
-server at IP address 10.1.2.4. We can now look at the pcap trace for the
-echo server,
+server at IP address 10.1.2.4.
@verbatim
- ~/repos/ns-3-dev > tcpdump -r second-4-0.pcap -nn -tt
- reading from file second-4-0.pcap, link-type EN10MB (Ethernet)
- 2.003686 arp who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1
- 2.003686 arp reply 10.1.2.4 is-at 00:00:00:00:00:06
- 2.003690 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024
- 2.003690 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4
- 2.003692 arp reply 10.1.2.1 is-at 00:00:00:00:00:03
- 2.003692 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024
- ~/repos/ns-3-dev >
+ 2.003801 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024
@end verbatim
-Again, you see that the link type is ``Ethernet''. The first two entries are
-the ARP exchange we just explained. The third packet is the echo packet
-being delivered to its final destination.
-
-The echo server turns the packet around and needs to send it back to the echo
-client on 10.1.1.1 but it knows that this address is on another network that
-it reaches via IP address 10.1.2.1. This is because we initialized global
+The server receives the echo request and turns the packet around trying to send
+it back to the source. The server knows that this address is on another network
+that it reaches via IP address 10.1.2.1. This is because we initialized global
routing and it has figured all of this out for us. But, the echo server node
doesn't know the MAC address of the first CSMA node, so it has to ARP for it
-just like the first CSMA node had to do. We leave it as an exercise for you
-to find the entries corresponding to the packet returning back on its way to
-the client (we have already dumped the traces and you can find them in those
-tcpdumps above.
-
-Let's take a look at one of the CSMA nodes that wasn't involved in the packet
-exchange:
+just like the first CSMA node had to do.
@verbatim
- ~/repos/ns-3-dev > tcpdump -r second-2-0.pcap -nn -tt
- reading from file second-2-0.pcap, link-type EN10MB (Ethernet)
- 2.003686 arp who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1
- 2.003691 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4
- ~/repos/ns-3-dev >
+ 2.003811 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4
+ 2.003822 arp reply 10.1.2.1 is-at 00:00:00:00:00:03
@end verbatim
-You can see that the CSMA channel is a broadcast medium and so all of the
-devices see the ARP requests involved in the packet exchange. The remaining
-pcap trace will be identical to this one.
+The server then sends the echo back to the forwarding node.
+
+@verbatim
+ 2.003915 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024
+@end verbatim
+
+Looking back at the rightmost node of the point-to-point link,
+
+@verbatim
+ tcpdump -nn -tt -r second-1-0.pcap
+@end verbatim
+
+You can now see the echoed packet coming back onto the point-to-point link as
+the last line of the trace dump.
+
+@verbatim
+reading from file second-1-0.pcap, link-type PPP (PPP)
+2.003686 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024
+2.003915 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024
+@end verbatim
+
+Lastly, you can look back at the node that originated the echo
+@verbatim
+ tcpdump -nn -tt -r second-0-0.pcap
+@end verbatim
+
+and see that the echoed packet arrives back at the source at 2.007602 seconds,
+
+@verbatim
+ reading from file second-0-0.pcap, link-type PPP (PPP)
+ 2.000000 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024
+ 2.007602 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024
+@end verbatim
Finally, recall that we added the ability to control the number of CSMA devices
in the simulation by command line argument. You can change this argument in
the same way as when we looked at changing the number of packets echoed in the
-@code{first.cc} example. Try setting the number of ``extra'' devices to four:
+@code{first.cc} example. Try running the program with the number of ``extra''
+devices set to four:
@verbatim
- ~/repos/ns-3-dev > ./waf --run "scratch/second --nCsma=4"
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
+ ./waf --run "scratch/mysecond --nCsma=4"
+@end verbatim
+
+You should now see,
+
+@verbatim
+ Entering directory `repos/ns-3-allinone/ns-3-dev/build'
+ Build finished successfully (00:00:00)
Sent 1024 bytes to 10.1.2.5
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.2.5
- ~/repos/ns-3-dev >
@end verbatim
Notice that the echo server has now been relocated to the last of the CSMA
-nodes, which is 10.1.2.5 instead of the default case, 10.1.2.4. You can
-increase the number to your hearts content, but remember that you will get a
-pcap trace file for every node in the simulation. One thing you can do to
-keep from getting all of those pcap traces with nothing but ARP exchanges in
-them is to be more specific about which nodes and devices you want to trace.
+nodes, which is 10.1.2.5 instead of the default case, 10.1.2.4.
-Let's take a look at @code{scratch/second.cc} and add that code enabling us
-to be more specific. The file we provided used the @code{EnablePcapAll}
-methods of the helpers to enable pcap on all devices. We now want to use the
-more specific method, @code{EnablePcap}, which takes a node number and device
-number as parameters. Go ahead and replace the @code{EnablePcapAll} calls
-with the calls below.
+It is possible that you may not be satisfied with a trace file generated by
+a bystander in the CSMA network. You may really want to get a trace from
+a single device and you may not be interested in any other traffic on the
+network. You can do this,
+
+Let's take a look at @code{scratch/mysecond.cc} and add that code enabling us
+to be more specific. @code{ns-3} helpers provide methods that take a node
+number and device number as parameters. Go ahead and replace the
+@code{EnablePcap} calls with the calls below.
@verbatim
PointToPointHelper::EnablePcap ("second", p2pNodes.Get (0)->GetId (), 0);
- CsmaHelper::EnablePcap ("second", csmaNodes.Get (nCsma)->GetId (), 0);
+ CsmaHelper::EnablePcap ("second", csmaNodes.Get (nCsma)->GetId (), 0, false);
+ CsmaHelper::EnablePcap ("second", csmaNodes.Get (nCsma-1)->GetId (), 0, false);
@end verbatim
We know that we want to create a pcap file with the base name "second" and
we also know that the device of interest in both cases is going to be zero,
-so those parameters are not really interesting. In order to get the node
-number, you have two choices: first, nodes are numbered in a monotonically
-increasing fashion starting from zero in the order in which you created them.
-One way to get a node number is to figure this number out ``manually'' by
-contemplating the order of node creation. If you take a look at the network
-topology illustration at the beginning of the file, we did this for you and
-you can see that the last CSMA node is going to be node number
-@code{nCsma + 1}. This approach can become annoyingly difficult in larger
-simulations.
+so those parameters are not really interesting.
+
+In order to get the node number, you have two choices: first, nodes are
+numbered in a monotonically increasing fashion starting from zero in the
+order in which you created them. One way to get a node number is to figure
+this number out ``manually'' by contemplating the order of node creation.
+If you take a look at the network topology illustration at the beginning of
+the file, we did this for you and you can see that the last CSMA node is
+going to be node number @code{nCsma + 1}. This approach can become
+annoyingly difficult in larger simulations.
An alternate way, which we use here, is to realize that the
@code{NodeContainers} contain pointers to @command{ns-3} @code{Node} Objects.
@@ -537,35 +615,54 @@ to the documentation for the @code{Node} class. If you now scroll down to the
documentation for the method. Using the @code{GetId} method can make
determining node numbers much easier in complex topologies.
-Now that we have got some trace filtering in place, it is reasonable to start
-increasing the number of CSMA devices in our simulation. If you build the
-new script and run the simulation setting @code{nCsma} to 100, you will see
-the following output:
+If you build the new script and run the simulation setting @code{nCsma} to 100,
@verbatim
- ~/repos/ns-3-dev > ./waf --run "scratch/second --nCsma=100"
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
+ ./waf --run "scratch/mysecond --nCsma=100"
+@end verbatim
+
+you will see the following output:
+
+@verbatim
+ Entering directory `repos/ns-3-allinone/ns-3-dev/build'
+ Build finished successfully (00:00:00)
Sent 1024 bytes to 10.1.2.101
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.2.101
- ~/repos/ns-3-dev >
@end verbatim
Note that the echo server is now located at 10.1.2.101 which corresponds to
having 100 ``extra'' CSMA nodes with the echo server on the last one. If you
-list the pcap files in the top level directory,
+list the pcap files in the top level directory you will see,
@verbatim
- ~/repos/ns-3-dev > ls *.pcap
- second-0-0.pcap second-101-0.pcap
- ~/repos/ns-3-dev >
+ second-0-0.pcap second-100-0.pcap second-101-0.pcap
@end verbatim
-you will see that we have, in fact, only created two trace files. The trace
-file @code{second-0-0.pcap} is the ``leftmost'' point-to-point device which is
-the echo packet source. The file @code{second-101-0.pcap} corresponds to the
-rightmost CSMA device which is where the echo server resides.
+The trace file @code{second-0-0.pcap} is the ``leftmost'' point-to-point device
+which is the echo packet source. The file @code{second-101-0.pcap} corresponds
+to the rightmost CSMA device which is where the echo server resides. You may
+have noticed that the final parameter on the call to enable pcap tracing on the
+echo server node was false. This means that the trace gathered on that node
+was in non-promiscuous mode.
+
+To illustrate the difference between promiscuous and non-promiscuous traces, we
+also requested a non-promiscuous trace for the next-to-last node. Go ahead and
+take a look at the @code{tcpdump} for @code{second-10-0.pcap}.
+
+@verbatim
+ tcpdump -nn -tt -r second-100-0.pcap
+@end verbatim
+
+You can now see that node 100 is really a bystander in the echo exchange. The
+only packets that it receives are the ARP requests which are broadcast to the
+entire CSMA network.
+
+@verbatim
+reading from file second-100-0.pcap, link-type EN10MB (Ethernet)
+2.003696 arp who-has 10.1.2.101 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1
+2.003811 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.101
+@end verbatim
@c ========================================================================
@c Building a Wireless Network Topology
@@ -651,36 +748,27 @@ component is defined. This should all be quite familiar by now.
NS_LOG_COMPONENT_DEFINE ("ThirdScriptExample");
@end verbatim
-As has become the norm in this tutorial, the main program begins by enabling
-the @code{UdpEchoClientApplication} and @code{UdpEchoServerApplication}
-logging components at @code{INFO} level so we can see some output when we run
-the simulation.
-
-@verbatim
- int
- main (int argc, char *argv[])
- {
- LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
- LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
-@end verbatim
-
-A fixed seed is provided to the random number generators so that they will
-generate repeatable results.
-
-@verbatim
- RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
-@end verbatim
-
-Next, you will see more familiar code that will allow you to change the number
-of devices on the CSMA and Wifi networks via command line argument.
+The main program begins just like @code{second.cc} by adding some command line
+parameters for enabling or disabling logging components and for changing the
+number of devices created.
@verbatim
+ bool verbose = true;
uint32_t nCsma = 3;
uint32_t nWifi = 3;
+
CommandLine cmd;
- cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
- cmd.AddValue ("nWifi", "Number of wifi STA devices", nWifi);
+ cmd.AddValue (``nCsma'', ``Number of \"extra\" CSMA nodes/devices'', nCsma);
+ cmd.AddValue (``nWifi'', ``Number of wifi STA devices'', nWifi);
+ cmd.AddValue (``verbose'', ``Tell echo applications to log if true'', verbose);
+
cmd.Parse (argc,argv);
+
+ if (verbose)
+ {
+ LogComponentEnable(``UdpEchoClientApplication'', LOG_LEVEL_INFO);
+ LogComponentEnable(``UdpEchoServerApplication'', LOG_LEVEL_INFO);
+ }
@end verbatim
Just as in all of the previous examples, the next step is to create two nodes
@@ -692,8 +780,8 @@ that we will connect via the point-to-point link.
@end verbatim
Next, we see an old friend. We instantiate a @code{PointToPointHelper} and
-set the associated default attributes so that we create a five megabit per
-second transmitter on devices created using the helper and a two millisecond
+set the associated default @code{Attributes} so that we create a five megabit
+per second transmitter on devices created using the helper and a two millisecond
delay on channels created by the helper. We then @code{Intall} the devices
on the nodes and the channel between them.
@@ -721,8 +809,8 @@ that will get CSMA devices. The node in question is going to end up with a
point-to-point device and a CSMA device. We then create a number of ``extra''
nodes that compose the remainder of the CSMA network.
-We then instantiate a @code{CsmaHelper} and set its attributes as we did in
-the previous example. We create a @code{NetDeviceContainer} to keep track of
+We then instantiate a @code{CsmaHelper} and set its @code{Attributes} as we did
+in the previous example. We create a @code{NetDeviceContainer} to keep track of
the created CSMA net devices and then we @code{Install} CSMA devices on the
selected nodes.
@@ -775,7 +863,6 @@ Once the PHY helper is configured, we can focus on the MAC layer:
wifi.SetRemoteStationManager ("ns3::AarfWifiManager");
@end verbatim
-
The @code{SetRemoteStationManager} method tells the helper the type of
rate control algorithm to use. Here, it is asking the helper to use the AARF
algorithm --- details are, of course, available in Doxygen.
@@ -795,8 +882,8 @@ will be used to set the value of the ``Ssid'' @code{Attribute} of the MAC
layer implementation. The particular kind of MAC layer is specified by
@code{Attribute} as being of the "ns3::NqstaWifiMac" type. This means that
the MAC will use a ``non-QoS station'' (nqsta) state machine. Finally, the
-``ActiveProbing'' attribute is set to false. This means that probe requests
-will not be sent by MACs created by this helper.
+``ActiveProbing'' @code{Attribute} is set to false. This means that probe
+requests will not be sent by MACs created by this helper.
Once all the station-specific parameters are fully configured, both at the
MAC and PHY layers, we can invoke our now-familiar @code{Install} method to
@@ -821,11 +908,11 @@ requirements of the AP.
In this case, the @code{WifiHelper} is going to create MAC layers of the
``ns3::NqapWifiMac'' (Non-Qos Access Point) type. We set the
-``BeaconGeneration'' attribute to true and also set an interval between
+``BeaconGeneration'' @code{Attribute} to true and also set an interval between
beacons of 2.5 seconds.
The next lines create the single AP which shares the same set of PHY-level
-attributes (and channel) as the stations:
+@code{Attributes} (and channel) as the stations:
@verbatim
NetDeviceContainer apDevices;
@@ -835,8 +922,8 @@ attributes (and channel) as the stations:
Now, we are going to add mobility models. We want the STA nodes to be mobile,
wandering around inside a bounding box, and we want to make the AP node
stationary. We use the @code{MobilityHelper} to make this easy for us.
-First, we instantiate a @code{MobilityHelper} object and set some attributes
-controlling the ``position allocator'' functionality.
+First, we instantiate a @code{MobilityHelper} object and set some
+@code{Attributes} controlling the ``position allocator'' functionality.
@verbatim
MobilityHelper mobility;
@@ -873,10 +960,10 @@ STA nodes.
We want the access point to remain in a fixed position during the simulation.
We accomplish this by setting the mobility model for this node to be the
-@code{ns3::StaticMobilityModel}:
+@code{ns3::ConstantPositionMobilityModel}:
@verbatim
- mobility.SetMobilityModel ("ns3::StaticMobilityModel");
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (wifiApNode);
@end verbatim
@@ -960,18 +1047,20 @@ loop.
Simulator::Stop (Seconds (10.0));
@end verbatim
-We use the same trick as in the @code{second.cc} script to only generate
-pcap traces from the nodes we find interesting. Note that we use the same
-``formula'' to get pcap tracing enabled on Wifi devices as we did on the
-CSMA and point-to-point devices.
+We create just enough tracing to cover all three networks:
@verbatim
- WifiHelper::EnablePcap ("third",
- wifiStaNodes.Get (nWifi - 1)->GetId (), 0);
- CsmaHelper::EnablePcap ("third",
- csmaNodes.Get (nCsma)->GetId (), 0);
+ PointToPointHelper::EnablePcapAll ("third");
+ YansWifiPhyHelper::EnablePcap ("third", apDevices.Get (0));
+ CsmaHelper::EnablePcap ("third", csmaDevices.Get (0), true);
@end verbatim
+These three lines of code will start pcap tracing on both of the point-to-point
+nodes that serves as our backbone, will start a promiscuous (monitor) mode
+trace on the Wifi network, and will start a promiscuous trace on the CSMA
+network. This will let us see all of the traffic with a minimum number of
+trace files.
+
Finally, we actually run the simulation, clean up and then exit the program.
@verbatim
@@ -987,22 +1076,20 @@ the @code{second.cc} example. If you are in the top-level directory of the
repository you would type,
@verbatim
- cp examples/third.cc scratch/
+ cp examples/third.cc scratch/mythird.cc
./waf
- ./waf --run scratch/third
+ ./waf --run scratch/mythird
@end verbatim
Since we have set up the UDP echo applications just as we did in the
@code{second.cc} script, you will see similar output.
@verbatim
- ~/repos/ns-3-dev > ./waf --run scratch/third
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
+ Entering directory `repos/ns-3-allinone-dev/ns-3-dev/build'
+ Build finished successfully (00:00:00)
Sent 1024 bytes to 10.1.2.4
Received 1024 bytes from 10.1.3.3
Received 1024 bytes from 10.1.2.4
- ~/repos/ns-3-dev >
@end verbatim
Recall that the first message, @code{Sent 1024 bytes to 10.1.2.4} is the
@@ -1013,74 +1100,123 @@ generated when it receives the echo packet. The final message,
@code{Received 1024 bytes from 10.1.2.4} is from the echo client, indicating
that it has received its echo back from the server.
-If you now go and look in the top level directory, you will find two trace
-files:
+If you now go and look in the top level directory, you will find four trace
+files, two from node zero and two from node one:
@verbatim
- ~/repos/ns-3-dev > ls *.pcap
- third-4-0.pcap third-7-0.pcap
- ~/repos/ns-3-dev >
+third-0-0.pcap third-0-1.pcap third-1-0.pcap third-1-1.pcap
@end verbatim
-The file ``third-4-0.pcap'' corresponds to the pcap trace for node four -
-device zero. This is the CSMA network node that acted as the echo server.
-Take a look at the tcpdump for this device:
+The file ``third-0-0.pcap'' corresponds to the point-to-point device on node
+zero -- the left side of the ``backbone.'' The file ``third-1-0.pcap''
+corresponds to the point-to-point device on node one -- the right side of the
+``backbone.'' The file ``third-0-1.pcap'' will be the promiscuous (monitor
+mode) trace from the Wifi network and the file ``third-1-1.pcap'' will be the
+promiscuous trace from the CSMA network. Can you verify this by inspecting
+the code?
+
+Since the echo client is on the Wifi network, let's start there. Let's take
+a look at the promiscuous (monitor mode) trace we captured on that network.
@verbatim
- ~/repos/ns-3-dev > tcpdump -r third-4-0.pcap -nn -tt
- reading from file third-4-0.pcap, link-type EN10MB (Ethernet)
+ tcpdump -nn -tt -r third-0-1.pcap
+@end verbatim
+
+You should see some wifi-looking contents you haven't seen here before:
+
+@verbatim
+ reading from file third-0-1.pcap, link-type IEEE802_11 (802.11)
+ 0.000025 Beacon () [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS
+ 0.000263 Assoc Request () [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit]
+ 0.000279 Acknowledgment RA:00:00:00:00:00:07
+ 0.000357 Assoc Response AID(0) :: Succesful
+ 0.000501 Acknowledgment RA:00:00:00:00:00:0a
+ 0.000748 Assoc Request () [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit]
+ 0.000764 Acknowledgment RA:00:00:00:00:00:08
+ 0.000842 Assoc Response AID(0) :: Succesful
+ 0.000986 Acknowledgment RA:00:00:00:00:00:0a
+ 0.001242 Assoc Request () [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit]
+ 0.001258 Acknowledgment RA:00:00:00:00:00:09
+ 0.001336 Assoc Response AID(0) :: Succesful
+ 0.001480 Acknowledgment RA:00:00:00:00:00:0a
+ 2.000112 arp who-has 10.1.3.4 (ff:ff:ff:ff:ff:ff) tell 10.1.3.3
+ 2.000128 Acknowledgment RA:00:00:00:00:00:09
+ 2.000206 arp who-has 10.1.3.4 (ff:ff:ff:ff:ff:ff) tell 10.1.3.3
+ 2.000487 arp reply 10.1.3.4 is-at 00:00:00:00:00:0a
+ 2.000659 Acknowledgment RA:00:00:00:00:00:0a
+ 2.002169 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024
+ 2.002185 Acknowledgment RA:00:00:00:00:00:09
+ 2.009771 arp who-has 10.1.3.3 (ff:ff:ff:ff:ff:ff) tell 10.1.3.4
+ 2.010029 arp reply 10.1.3.3 is-at 00:00:00:00:00:09
+ 2.010045 Acknowledgment RA:00:00:00:00:00:09
+ 2.010231 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024
+ 2.011767 Acknowledgment RA:00:00:00:00:00:0a
+ 2.500000 Beacon () [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS
+ 5.000000 Beacon () [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS
+ 7.500000 Beacon () [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS
+@end verbatim
+
+You can see that the link type is now 802.11 as you would expect. You can
+probably understand what is going on and find the IP echo request and response
+packets in this trace. We leave it as an exercise to completely parse the
+trace dump.
+
+Now, look at the pcap file of the right side of the point-to-point link,
+
+@verbatim
+ tcpdump -nn -tt -r third-0-0.pcap
+@end verbatim
+
+Again, you should see some familiar looking contents:
+
+@verbatim
+ reading from file third-0-0.pcap, link-type PPP (PPP)
+ 2.002169 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024
+ 2.009771 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024
+@end verbatim
+
+This is the echo packet going from left to right (from Wifi to CSMA) and back
+again across the point-to-point link.
+
+Now, look at the pcap file of the right side of the point-to-point link,
+
+@verbatim
+ tcpdump -nn -tt -r third-1-0.pcap
+@end verbatim
+
+Again, you should see some familiar looking contents:
+
+@verbatim
+ reading from file third-1-0.pcap, link-type PPP (PPP)
+ 2.005855 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024
+ 2.006084 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024
+@end verbatim
+
+This is also the echo packet going from left to right (from Wifi to CSMA) and
+back again across the point-to-point link with slightly different timings
+as you might expect.
+
+The echo server is on the CSMA network, let's look at the promiscuous trace
+there:
+
+@verbatim
+ tcpdump -nn -tt -r third-1-1.pcap
+@end verbatim
+
+You should see some familiar looking contents:
+
+@verbatim
+ reading from file third-1-1.pcap, link-type EN10MB (Ethernet)
2.005855 arp who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1
- 2.005855 arp reply 10.1.2.4 is-at 00:00:00:00:00:06
- 2.005859 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024
- 2.005859 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4
- 2.005861 arp reply 10.1.2.1 is-at 00:00:00:00:00:03
- 2.005861 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024
- ~/repos/ns-3-dev >
+ 2.005877 arp reply 10.1.2.4 is-at 00:00:00:00:00:06
+ 2.005877 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024
+ 2.005980 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4
+ 2.005980 arp reply 10.1.2.1 is-at 00:00:00:00:00:03
+ 2.006084 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024
@end verbatim
-This should be familiar and easily understood. If you've forgotten, go back
-and look at the discussion in @code{second.cc}. This is the same sequence.
-
-Now, take a look at the other trace file, ``third-7-0.pcap.'' This is the
-trace file for the wireless STA node that acts as the echo client.
-
-@verbatim
- ~/repos/ns-3-dev > tcpdump -r third-7-0.pcap -nn -tt
- reading from file third-7-0.pcap, link-type IEEE802_11 (802.11)
- 0.000146 Beacon (ns-3-ssid) ...
- H: 0
- 0.000180 Assoc Request (ns-3-ssid) ...
- 0.000336 Acknowledgment RA:00:00:00:00:00:07
- 0.000454 Assoc Response AID(0) :: Succesful
- 0.000514 Acknowledgment RA:00:00:00:00:00:0a
- 0.000746 Assoc Request (ns-3-ssid) ...
- 0.000902 Acknowledgment RA:00:00:00:00:00:09
- 0.001020 Assoc Response AID(0) :: Succesful
- 0.001036 Acknowledgment RA:00:00:00:00:00:0a
- 0.001219 Assoc Request (ns-3-ssid) ...
- 0.001279 Acknowledgment RA:00:00:00:00:00:08
- 0.001478 Assoc Response AID(0) :: Succesful
- 0.001538 Acknowledgment RA:00:00:00:00:00:0a
- 2.000000 arp who-has 10.1.3.4 (ff:ff:ff:ff:ff:ff) tell 10.1.3.3
- 2.000172 Acknowledgment RA:00:00:00:00:00:09
- 2.000318 arp who-has 10.1.3.4 (ff:ff:ff:ff:ff:ff) tell 10.1.3.3
- 2.000581 arp reply 10.1.3.4 is-at 00:00:00:00:00:0a
- 2.000597 Acknowledgment RA:00:00:00:00:00:0a
- 2.000693 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, length 1024
- 2.002229 Acknowledgment RA:00:00:00:00:00:09
- 2.009663 arp who-has 10.1.3.3 (ff:ff:ff:ff:ff:ff) tell 10.1.3.4
- 2.009697 arp reply 10.1.3.3 is-at 00:00:00:00:00:09
- 2.009869 Acknowledgment RA:00:00:00:00:00:09
- 2.011487 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, length 1024
- 2.011503 Acknowledgment RA:00:00:00:00:00:0a
- 2.500112 Beacon[|802.11]
- 5.000112 Beacon[|802.11]
- 7.500112 Beacon[|802.11]
- ~/repos/ns-3-dev >
-@end verbatim
-
-You can see that the link type is now 802.11 as you would expect. We leave
-it as an exercise to parse the dump and trace packets across the internetwork.
+This should be easily understood. If you've forgotten, go back and look at
+the discussion in @code{second.cc}. This is the same sequence.
Now, we spent a lot of time setting up mobility models for the wireless network
and so it would be a shame to finish up without even showing that the STA
@@ -1088,13 +1224,13 @@ nodes are actually moving around. Let's do this by hooking into the
@code{MobilityModel} course change trace source. This is usually considered
a fairly advanced topic, but let's just go for it.
-As mentioned in the Tweaking Ns-3 section, the @command{ns-3} tracing system
+As mentioned in the ``Tweaking ns-3'' section, the @command{ns-3} tracing system
is divided into trace sources and trace sinks, and we provide functions to
connect the two. We will use the mobility model predefined course change
trace source to originate the trace events. We will need to write a trace
sink to connect to that source that will display some pretty information for
us. Despite its reputation as being difficult, it's really quite simple.
-Just before the main program of the @code{scratch/third.cc} script, add the
+Just before the main program of the @code{scratch/mythird.cc} script, add the
following function:
@verbatim
@@ -1150,41 +1286,40 @@ If you now run the simulation, you will see the course changes displayed as
they happen.
@verbatim
- ~/repos/ns-3-dev > ./waf --run scratch/third
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
+ Build finished successfully (00:00:01)
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10, y = 0
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.1304, y = 0.493761
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.70417, y = 1.39837
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.94799, y = 2.05274
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.82597, y = 1.57404
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.3003, y = 0.723347
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.41539, y = -0.811313
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.46199, y = -1.11303
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.52738, y = -1.46869
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 6.67099, y = -1.98503
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 5.6835, y = -2.14268
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 4.70932, y = -1.91689
Sent 1024 bytes to 10.1.2.4
Received 1024 bytes from 10.1.3.3
Received 1024 bytes from 10.1.2.4
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.74083, y = 1.62109
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.00146, y = 0.655647
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.98731, y = 0.823279
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.50206, y = 1.69766
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.68108, y = 2.26862
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.25992, y = 1.45317
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.55655, y = 0.742346
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.21992, y = 1.68398
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.81273, y = 0.878638
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.83171, y = 1.07256
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.60027, y = 0.0997156
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.45367, y = 0.620978
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.68484, y = 1.26043
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.53659, y = 0.736479
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.51876, y = 0.548502
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.89778, y = 1.47389
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.98984, y = 1.893
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 9.91524, y = 1.51402
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.98761, y = 1.14054
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.16617, y = 0.570239
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.02954, y = 1.56086
- /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.09551, y = 2.55868
- ~/repos/ns-3-dev >
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 5.53175, y = -2.48576
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 4.58021, y = -2.17821
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 4.18915, y = -1.25785
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 4.7572, y = -0.434856
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 4.62404, y = 0.556238
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 4.74127, y = 1.54934
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 5.73934, y = 1.48729
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 6.18521, y = 0.59219
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 6.58121, y = 1.51044
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.27897, y = 2.22677
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 6.42888, y = 1.70014
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.40519, y = 1.91654
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 6.51981, y = 1.45166
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.34588, y = 2.01523
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.81046, y = 2.90077
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 6.89186, y = 3.29596
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.46617, y = 2.47732
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.05492, y = 1.56579
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 8.00393, y = 1.25054
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.00968, y = 1.35768
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.33503, y = 2.30328
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.18682, y = 3.29223
+ /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.96865, y = 2.66873
@end verbatim
If you are feeling brave, there is a list of all trace sources in the
@@ -1194,7 +1329,8 @@ Under the ``core'' section, you will find a link to ``The list of all trace
sources.'' You may find it interesting to try and hook some of these
traces yourself. Additionally in the ``Modules'' documentation, there is
a link to ``The list of all attributes.'' You can set the default value of
-any of these attributes via the command line as we have previously discussed.
+any of these @code{Attributes} via the command line as we have previously
+discussed.
We have just scratched the surface of @command{ns-3} in this tutorial, but we
hope we have covered enough to get you started doing useful work.
diff --git a/doc/tutorial/conceptual-overview.texi b/doc/tutorial/conceptual-overview.texi
index 040ade27c..cb38386bb 100644
--- a/doc/tutorial/conceptual-overview.texi
+++ b/doc/tutorial/conceptual-overview.texi
@@ -362,21 +362,6 @@ enable on each component. These two lines of code enable debug logging at the
INFO level for echo clients and servers. This will result in the application
printing out messages as packets are sent and received during the simulation.
-The next line of code is used to give a fixed seed to the random number
-generators so that they will generate repeatable results. In the example
-programs, it allows us to thouroughly document the output of the trace files
-in a consistent way. Having a fixed seed also allows us to use the examples
-in our regression testing framework.
-
-@verbatim
- RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
-@end verbatim
-
-Random variables are very important in understanding how to get repeatable
-results, so you are encouraged to read the Doxygen and manual sections to
-understand what is going on there. For us, the main concern is in making
-random backoff algorithms consistent across runs.
-
Now we will get directly to the business of creating a topology and running
a simulation. We use the topology helper objects to make this job as
easy as possible.
@@ -439,7 +424,7 @@ The next three lines in the script are,
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
@end verbatim
-The first line
+The first line,
@verbatim
PointToPointHelper pointToPoint;
@@ -461,12 +446,12 @@ to what we call an @code{Attribute} of the @code{PointToPointNetDevice}.
If you look at the Doxygen for class @code{ns3::PointToPointNetDevice} and
find the documentation for the @code{GetTypeId} method, you will find a list
of @code{Attributes} defined for the device. Among these is the ``DataRate''
-attribute. Most user-visible @command{ns-3} objects have similar lists of
-attributes. We use this mechanism to easily configure simulations without
+@code{Attribute}. Most user-visible @command{ns-3} objects have similar lists of
+@code{Attributes}. We use this mechanism to easily configure simulations without
recompiling as you will see in a following section.
Similar to the ``DataRate'' on the @code{PointToPointNetDevice} you will find a
-``Delay'' attribute associated with the @code{PointToPointChannel}. The
+``Delay'' @code{Attribute} associated with the @code{PointToPointChannel}. The
final line,
@verbatim
@@ -502,8 +487,9 @@ is created. For each node in the @code{NodeContainer} (there must be exactly
two for a point-to-point link) a @code{PointToPointNetDevice} is created and
saved in the device container. A @code{PointToPointChannel} is created and
the two @code{PointToPointNetDevices} are attached. When objects are created
-by the @code{PointToPointHelper}, the attributes previously set in the helper
-are used to initialize the corresponding attributes in the created objects.
+by the @code{PointToPointHelper}, the @code{Attributes} previously set in the
+helper are used to initialize the corresponding @code{Attributes} in the
+created objects.
After executing the @code{pointToPoint.Install (nodes)} call we will have
two nodes, each with an installed point-to-point net device and a
@@ -590,13 +576,13 @@ created.
The first line of code in the above snippet declares the
@code{UdpEchoServerHelper}. As usual, this isn't the application itself, it
is an object used to help us create the actual applications. One of our
-conventions is to place required attributes in the helper constructor. In this
-case, the helper can't do anything useful unless it is provided with a port
-number that the client also knows about. Rather than just picking one and
-hoping it all works out, we require the port number as a parameter to the
+conventions is to place required @code{Attributes} in the helper constructor.
+In this case, the helper can't do anything useful unless it is provided with
+a port number that the client also knows about. Rather than just picking one
+and hoping it all works out, we require the port number as a parameter to the
constructor. The constructor, in turn, simply does a @code{SetAttribute}
-with the passed value. You can, if desired, set the ``Port'' attribute to
-another value later.
+with the passed value. You can, if desired, set the ``Port'' @code{Attribute}
+to another value later.
Similar to many other helper objects, the @code{UdpEchoServerHelper} object
has an @code{Install} method. It is the execution of this method that actually
@@ -649,12 +635,12 @@ that is managed by an @code{UdpEchoClientHelper}.
clientApps.Stop (Seconds (10.0));
@end verbatim
-For the echo client, however, we need to set five different attributes. The
-first two attributes are set during construction of the
+For the echo client, however, we need to set five different @code{Attributes}.
+The first two @code{Attributes} are set during construction of the
@code{UdpEchoClientHelper}. We pass parameters that are used (internally to
-the helper) to set the ``RemoteAddress'' and ``RemotePort'' attributes in
-accordance with our convention to make required attributes parameters in the
-helper constructors.
+the helper) to set the ``RemoteAddress'' and ``RemotePort'' @code{Attributes}
+in accordance with our convention to make required @code{Attributes} parameters
+in the helper constructors.
Recall that we used an @code{Ipv4InterfaceContainer} to keep track of the IP
addresses we assigned to our devices. The zeroth interface in the
@@ -666,12 +652,12 @@ are creating the helper and telling it so set the remote address of the client
to be the IP address assigned to the node on which the server resides. We
also tell it to arrange to send packets to port nine.
-The ``MaxPackets'' attribute tells the client the maximum number of packets
-we allow it to send during the simulation. The ``Interval'' attribute tells
-the client how long to wait between packets, and the ``PacketSize'' attribute
-tells the client how large its packet payloads should be. With this
-particular combination of attributes, we are telling the client to send one
-1024-byte packet.
+The ``MaxPackets'' @code{Attribute} tells the client the maximum number of
+packets we allow it to send during the simulation. The ``Interval''
+@code{Attribute} tells the client how long to wait between packets, and the
+``PacketSize'' @code{Attribute} tells the client how large its packet payloads
+should be. With this particular combination of @code{Attributes}, we are
+telling the client to send one 1024-byte packet.
Just as in the case of the echo server, we tell the echo client to @code{Start}
and @code{Stop}, but here we start the client one second after the server is
@@ -738,34 +724,40 @@ built if you run Waf. Let's try it. Copy @code{examples/first.cc} into
the @code{scratch} directory.
@verbatim
- ~/repos/ns-3-dev > cp examples/first.cc scratch/
+ ~/repos/ns-3-dev > cp examples/first.cc scratch/myfirst.cc
@end verbatim
-and then build it using waf,
+Now build your first example script using waf:
@verbatim
- ~/repos/ns-3-dev > ./waf
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- [467/511] cxx: scratch/first.cc -> build/debug/scratch/first_1.o
- [468/511] cxx: scratch/multiple-sources/simple-main.cc -> build/debug/scratch/multiple-sources/simple-main_2.o
- [469/511] cxx: scratch/multiple-sources/simple-simulation.cc -> build/debug/scratch/multiple-sources/simple-simulation_2.o
- [470/511] cxx: scratch/simple.cc -> build/debug/scratch/simple_3.o
- [508/511] cxx_link: build/debug/scratch/first_1.o -> build/debug/scratch/first
- Compilation finished successfully
- ~/repos/ns-3-dev >
+ ./waf
+@end verbatim
+
+You should see messages reporting that your @code{myfirst} example was built
+successfully.
+
+@verbatim
+ Entering directory `repos/ns-3-allinone-dev/ns-3-dev/build'
+ [563/648] cxx: scratch/myfirst.cc -> build/debug/scratch/myfirst_3.o
+ [646/648] cxx_link: build/debug/scratch/myfirst_3.o -> build/debug/scratch/myfirst
+ Build finished successfully (00:00:02)
@end verbatim
You can now run the example (note that if you build your program in the scratch
directory you must run it out of the scratch directory):
@verbatim
- ~/repos/ns-3-dev > ./waf --run scratch/first
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
+ ./waf --run scratch/myfirst
+@end verbatim
+
+You should see some output:
+
+@verbatim
+ Entering directory `repos/ns-3-allinone-dev/ns-3-dev/build'
+ Build finished successfully (00:00:00)
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2
- ~/repos/ns-3-dev >
@end verbatim
Here you see that the build system checks to make sure that the file has been
@@ -793,38 +785,42 @@ links, one can browse the source tree.
The top-level directory for one of our @emph{repositories} will look
something like:
+
@verbatim
-drwxr-xr-x [up]
-drwxr-xr-x doc manifest
-drwxr-xr-x examples manifest
-drwxr-xr-x ns3 manifest
-drwxr-xr-x regression manifest
-drwxr-xr-x samples manifest
-drwxr-xr-x scratch manifest
-drwxr-xr-x src manifest
-drwxr-xr-x tutorial manifest
-drwxr-xr-x utils manifest
--rw-r--r-- 135 .hgignore file | revisions | annotate
--rw-r--r-- 891 .hgtags file | revisions | annotate
--rw-r--r-- 441 AUTHORS file | revisions | annotate
--rw-r--r-- 17987 LICENSE file | revisions | annotate
--rw-r--r-- 4948 README file | revisions | annotate
--rw-r--r-- 4917 RELEASE_NOTES file | revisions | annotate
--rw-r--r-- 7 VERSION file | revisions | annotate
--rwxr-xr-x 99143 waf file | revisions | annotate
--rwxr-xr-x 28 waf.bat file | revisions | annotate
--rw-r--r-- 30584 wscript file | revisions | annotate
+drwxr-xr-x [up]
+drwxr-xr-x bindings python files
+drwxr-xr-x doc files
+drwxr-xr-x examples files
+drwxr-xr-x ns3 files
+drwxr-xr-x regression files
+drwxr-xr-x samples files
+drwxr-xr-x scratch files
+drwxr-xr-x src files
+drwxr-xr-x utils files
+-rw-r--r-- 2009-03-24 00:51 -0700 505 .hgignore file | revisions | annotate
+-rw-r--r-- 2009-03-24 00:51 -0700 1682 .hgtags file | revisions | annotate
+-rw-r--r-- 2009-03-24 00:51 -0700 686 AUTHORS file | revisions | annotate
+-rw-r--r-- 2009-03-24 00:51 -0700 14893 CHANGES.html file | revisions | annotate
+-rw-r--r-- 2009-03-24 00:51 -0700 17987 LICENSE file | revisions | annotate
+-rw-r--r-- 2009-03-24 00:51 -0700 3742 README file | revisions | annotate
+-rw-r--r-- 2009-03-24 00:51 -0700 13505 RELEASE_NOTES file | revisions | annotate
+-rw-r--r-- 2009-03-24 00:51 -0700 6 VERSION file | revisions | annotate
+-rw-r--r-- 2009-03-24 00:51 -0700 9257 regression.py file | revisions | annotate
+-rwxr-xr-x 2009-03-24 00:51 -0700 81285 waf file | revisions | annotate
+-rwxr-xr-x 2009-03-24 00:51 -0700 28 waf.bat file | revisions | annotate
+-rw-r--r-- 2009-03-24 00:51 -0700 26270 wscript file | revisions | annotate
+-rw-r--r-- 2009-03-24 00:51 -0700 6636 wutils.py file | revisions | annotate
@end verbatim
The source code is mainly in the @code{src} directory. You can view source
-code by clicking on the @code{manifest} link to the right of the directory
-name. If you click on the @code{manifest} link to the right of the src
-directory you will find a subdirectory. If you click on the @code{manifest}
-link next to the @code{core} subdirectory in under @code{src}, you will find
-a list of files. The first file you will find is @code{assert.h}. If you
-click on the @code{file} link, you will be sent to the source file for
-@code{assert.h}.
+code either by clicking on the directory name or by clicking on the @code{files}
+link to the right of the directory name. If you click on the @code{src}
+directory you be taken to the lising of the @code{src} subdirectories. If you
+click on @code{core} subdirectory, you will find a list of files. The first file
+you will find (as of this writing) is @code{abort.h}. If you
+click on @code{abort.h} link, you will be sent to the source file for @code{abort.h}.
Our example scripts are in the @code{examples} directory. The source code for
the helpers we have used in this chapter can be found in the
-@code{src/helpers} directory.
+@code{src/helpers} directory. Feel free to poke around in the directory tree to
+get a feel for what is there and the style of @command{ns-3} programs.
diff --git a/doc/tutorial/getting-started.texi b/doc/tutorial/getting-started.texi
index 1a1106893..a4bc52aac 100644
--- a/doc/tutorial/getting-started.texi
+++ b/doc/tutorial/getting-started.texi
@@ -44,78 +44,228 @@ the Getting Started section of the @command{ns-3} web site:
@cindex tarball
The @command{ns-3} code is available in Mercurial repositories on the server
-code.nsnam.org. You can download a tarball release at
+code.nsnam.org. You can also download a tarball release at
@uref{http://www.nsnam.org/releases/}, or you can work with repositories
-using Mercurial.
+using Mercurial. We recommend using Mercurial unless there's a good reason
+not to. See the end of this section for instructions on how to get a tarball
+release.
@cindex repository
-If you go to the following link: @uref{http://code.nsnam.org/},
-you will see a number of repositories. Many are the private repositories of
-the @command{ns-3} development team. The repositories of interest to you will
-be prefixed with ``ns-3''. The current development snapshot (unreleased)
-of @command{ns-3} may be found at: @uref{http://code.nsnam.org/ns-3-dev/}.
-Official releases of @command{ns-3} will be numbered as @code{ns-3.}
-with any required hotfixes added as minor release numbers. For example, a
-second hotfix to a hypothetical release nine of @command{ns-3} would be
-numbered @code{ns-3.9.2}.
-
-The current development snapshot (unreleased) of @command{ns-3} may be found
-at: @uref{http://code.nsnam.org/ns-3-dev/}. The developers attempt to keep
-this repository in a consistent, working state but it is a development area
-with unreleased code present, so you may want to consider staying with an
-official release if you do not need newly-introduced features.
-
-Since the release numbers are going to be changing, I will stick with
-the more constant ns-3-dev here in the tutorial, but you can replace the
-string ``ns-3-dev'' with your choice of release (e.g., ns-3.2) in the text
-below. You can find the latest version of the code either by inspection of
-the repository list or by going to the ``Getting Started'' web page and
-looking for the latest release identifier.
+The simplest way to get started using Mercurial repositories is to use the
+@code{ns-3-allinone} environment. This is a set of scripts that manages the
+downloading and building of various subystems of @command{ns-3} for you. We
+recommend that you begin your @command{ns-3} adventures in this environment
+as it can really simplify your life at this point.
+@subsection Downloading ns-3 Using Mercurial
One practice is to create a directory called @code{repos} in one's home
directory under which one can keep local Mercurial repositories.
@emph{Hint: we will assume you do this later in the tutorial.} If you adopt
-that approach, you can get a copy of the development version of
-@command{ns-3} by typing the following into your Linux shell (assuming you
-have installed Mercurial):
+that approach, you can get a copy of @code{ns-3-allinone} by typing the
+following into your Linux shell (assuming you have installed Mercurial):
@verbatim
cd
mkdir repos
cd repos
- hg clone http://code.nanam.org/ns-3-dev
+ hg clone http://code.nsnam.org/ns-3-allinone
+@end verbatim
+
+As the hg (Mercurial) command executes, you should see something like the
+following displayed,
+
+@verbatim
+ destination directory: ns-3-allinone
+ requesting all changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 26 changesets with 40 changes to 7 files
+ 7 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@end verbatim
+
+After the clone command completes, you should have a directory called
+@code{ns-3-allinone} under your @code{~/repos} directory, the contents of which should
+look something like the following:
+
+@verbatim
+ build.py* constants.py dist.py* download.py* README util.py
+@end verbatim
+
+Notice that you really just downloaded some Python scripts. The next step
+will be to use those scripts to download and build the @command{ns-3}
+distribution of your choice.
+
+@cindex repository
+If you go to the following link: @uref{http://code.nsnam.org/},
+you will see a number of repositories. Many are the private repositories of
+the @command{ns-3} development team. The repositories of interest to you will
+be prefixed with ``ns-3''. Official releases of @command{ns-3} will be
+numbered as @code{ns-3..}. For example, a second hotfix to a
+still hypothetical release nine of @command{ns-3} would be numbered as
+@code{ns-3.9.2}.
+
+We have had a regression testing framework in place since the first release.
+For each release, a set of output files that define ``good behavior'' are saved.
+These known good output files are called reference traces and are associated
+with a given release by name. For example, in @uref{http://code.nsnam.org/}
+you will find a repository named @code{ns-3.1} which is the first stable release
+of @command{ns-3}. You will also find a separate repository named
+@code{ns-3.1-ref-traces} that holds the reference traces for the @code{ns-3.1}
+release. It is crucial to keep these files consistent if you want to do any
+regression testing of your repository. This is a good idea to do at least once
+to verify everything has built correctly.
+
+The current development snapshot (unreleased) of @command{ns-3} may be found
+at @uref{http://code.nsnam.org/ns-3-dev/} and the associated reference traces
+may be found at @uref{http://code.nsnam.org/ns-3-dev-ref-traces/}. The
+developers attempt to keep these repository in consistent, working states but
+they are in a development area with unreleased code present, so you may want
+to consider staying with an official release if you do not need newly-
+introduced features.
+
+Since the release numbers are going to be changing, I will stick with
+the more constant ns-3-dev here in the tutorial, but you can replace the
+string ``ns-3-dev'' with your choice of release (e.g., ns-3.4 and
+ns-3.4-ref-traces) in the text below. You can find the latest version of the
+code either by inspection of the repository list or by going to the ``Getting
+Started'' web page and looking for the latest release identifier.
+
+Go ahead and change into the @code{ns-3-allinone} directory you created when
+you cloned that repository. We are now going to use the @code{download.py}
+script to pull down the various pieces of @command{ns-3} you will be using/
+
+Go ahead and type the following into your shell (remember you can substitute
+the name of your chosen release number instead of @code{ns-3-dev} -- like
+@code{"ns-3.4"} and @code{"ns-3.4-ref-traces"} if you want to work with a
+stable release).
+
+@verbatim
+ ./download.py -n ns-3-dev -r ns-3-dev-ref-traces
@end verbatim
As the hg (Mercurial) command executes, you should see something like the
following,
@verbatim
- destination directory: ns-3-dev
+ #
+ # Get NS-3
+ #
+
+ Cloning ns-3 branch
+ => hg clone http://code.nsnam.org/ns-3-dev ns-3-dev
requesting all changes
adding changesets
adding manifests
adding file changes
- added 3276 changesets with 12301 changes to 1353 files
- 594 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ added 4292 changesets with 15368 changes to 1671 files
+ 823 files updated, 0 files merged, 0 files removed, 0 files unresolved
@end verbatim
-After the clone command completes, you should have a directory called
-ns-3-dev under your @code{~/repos} directory, the contents of which should
-look something like the following:
+This is output by the download script as it fetches the actual @code{ns-3}
+code from the repository. Next, you should see something like,
@verbatim
- AUTHORS examples/ README samples/ utils/ waf.bat*
- build/ LICENSE regression/ scratch/ VERSION wscript
- doc/ ns3/ RELEASE_NOTES src/ waf*
+ #
+ # Get the regression traces
+ #
+
+ Synchronizing reference traces using Mercurial.
+ => hg clone http://code.nsnam.org/ns-3-dev-ref-traces ns-3-dev-ref-traces
+ requesting all changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 79 changesets with 1102 changes to 222 files
+ 206 files updated, 0 files merged, 0 files removed, 0 files unresolved
@end verbatim
-Similarly, if working from a released version instead, you can simply
+This is the download script fetching the reference trace files for you.
+The download script is smart enough to know that on some platforms various
+pieces of ns-3 are not supported. On your platform you may not see some
+of these pieces come down. However, on most platforms, the process should
+continue with something like,
+
+@verbatim
+ #
+ # Get PyBindGen
+ #
+
+ Required pybindgen version: 0.10.0.630
+ Trying to fetch pybindgen; this will fail if no network connection is available. Hit Ctrl-C to skip.
+ => bzr checkout -rrevno:630 https://launchpad.net/pybindgen pybindgen
+ Fetch was successful.
+@end verbatim
+
+This was the download script getting the Python bindings generator for you.
+Next you should see (modulo platform variations) something along the lines of,
+
+@verbatim
+ #
+ # Get NSC
+ #
+
+ Required NSC version: nsc-0.5.0
+ Retrieving nsc from https://secure.wand.net.nz/mercurial/nsc
+ => hg clone https://secure.wand.net.nz/mercurial/nsc nsc
+ requesting all changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 270 changesets with 17375 changes to 14991 files
+ 10614 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@end verbatim
+
+This part of the process is the script downloading the Network Simulation
+Cradle for you.
+
+After the clone command completes, you should have several new directories
+under @code{~/repos/ns-3-allinone}:
+
+@verbatim
+ build.py* constants.pyc download.py* ns-3-dev-ref-traces/ pybindgen/ util.py
+ constants.py dist.py* ns-3-dev/ nsc/ README util.pyc
+@end verbatim
+
+Go ahead and change into @code{ns-3-dev} under your @code{~/repos/ns-3-allinone}
+directory. You should see something like the following there:
+
+@verbatim
+ AUTHORS examples/ regression/ scratch/ waf*
+ bindings/ LICENSE regression.py src/ waf.bat*
+ CHANGES.html ns3/ RELEASE_NOTES utils/ wscript
+ doc/ README samples/ VERSION wutils.py
+@end verbatim
+
+You are now ready to build the @command{ns-3} distribution.
+
+@subsection Downloading ns-3 Using a Tarball
+The process for downloading @command{ns-3} via tarball is simpler than the
+Mercurial process since all of the pieces are pre-packaged for you. You just
+have to pick a release, download it and decompress it.
+
+As mentioned above, one practice is to create a directory called @code{repos}
+in one's home directory under which one can keep local Mercurial repositories.
+One could also keep a @code{tarballs} directory. @emph{Hint: the tutorial
+will assume you downloaded into a @code{repos} directory, so remember the
+placekeeper.} If you adopt the @code{tarballs} directory approach, you can
+get a copy of a release by typing the following into your Linux shell
+(substitute the appropriate version numbers, of course):
+
@verbatim
cd
- mkdir repos
- wget http://www.nsnam.org/releases/ns-3.2.tar.bz2
- bunzip2 ns-3.2.tar.bz2
- tar xvf ns-3.2.tar
+ mkdir tarballs
+ cd tarballs
+ wget http://www.nsnam.org/releases/ns-allinone-3.4.tar.bz2
+ tar xjf ns-3.4.tar.bz2
+@end verbatim
+
+If you change into the directory @code{ns-allinone-3.4} you should see a
+number of files:
+
+@verbatim
+build.py* ns-3.4-RC2/ nsc-0.5.0/ util.py
+constants.py ns-3.4-RC2-ref-traces/ pybindgen-0.10.0.630/
@end verbatim
You are now ready to build the @command{ns-3} distribution.
@@ -127,19 +277,61 @@ You are now ready to build the @command{ns-3} distribution.
@node Building ns-3
@section Building ns-3
+@subsection Building with build.py
+@cindex building with build.py
+The first time you build the @command{ns-3} project you should build using the
+@command{allinone} environment. This will get the project configured for you
+in the most commonly useful way.
+
+Change into the directory you created in the download section above. If you
+downloaded using Mercurial you should have a directory called
+@code{ns-3-allinone} under your @code{~/repos} directory. If you downloaded
+using a tarball you should have a directory called something like
+@code{ns-3-allinone-3.4} under your @code{~/tarballs} directory. Take a deep
+breath and type the following:
+
+@verbatim
+ ./build.py
+@end verbatim
+
+You will see lots of typical compiler output messages displayed as the build
+script builds the various pieces you downloaded. Eventually you should see the
+following magic words:
+
+@verbatim
+ Build finished successfully (00:02:37)
+ Leaving directory `./ns-3-dev'
+@end verbatim
+
+Once the project has built you can say goodbye to your old friends, the
+@code{ns-3-allinone} scripts. You got what you needed from them and will now
+interact directly with Waf and we do it in the @code{ns-3-dev} directory and
+not in the @code{ns-3-allinone} directory. Go ahead and change into the
+@code{ns-3-dev} directory (or the directory for the appropriate release you
+downloaded.
+
+@verbatim
+ cd ns-3-dev
+@end verbatim
+
+@subsection Building with Waf
@cindex building with Waf
@cindex configuring Waf
@cindex building debug version with Waf
@cindex compiling with Waf
@cindex unit tests with Waf
@cindex regression tests with Waf
-We use Waf to build the @command{ns-3} project. The first thing you will need
-to do is to configure the build. For reasons that will become clear later,
-we are going to work with debug builds in the tutorial. To explain to Waf
-that it should do debug builds you will need to execute the following command,
+We use Waf to configure and build the @command{ns-3} project. It's not
+strictly required at this point, but it will be valuable to take a slight
+detour and look at how to make changes to the configuration of the project.
+Probably the most useful configuration change you can make will be to
+build the optimized version of the code. By default you have configured
+your project to build the debug version. Let's tell the project to do
+make an optimized build. To explain to Waf that it should do optimized
+builds you will need to execute the following command,
@verbatim
- ./waf -d debug configure
+ ./waf -d optimized configure
@end verbatim
This runs Waf out of the local directory (which is provided as a convenience
@@ -147,57 +339,82 @@ for you). As the build system checks for various dependencies you should see
output that looks similar to the following,
@verbatim
-Checking for program g++ : ok /usr/bin/g++
-Checking for compiler version : ok Version 4.0.1
-Checking for program cpp : ok /usr/bin/cpp
-Checking for program ar : ok /usr/bin/ar
-Checking for program ranlib : ok /usr/bin/ranlib
-Checking for compiler could create programs : ok
-Checking for compiler could create shared libs : ok
-Checking for compiler could create static libs : ok
-Checking for flags -O2 -DNDEBUG : ok
-Checking for flags -g -DDEBUG : ok
-Checking for flags -g3 -O0 -DDEBUG : ok
-Checking for flags -Wall : ok
-Checking for g++ : ok
-Checking for -Wno-error=deprecated-declarations compilation flag support : no
-Checking for header stdlib.h : ok
-Checking for header stdlib.h : ok
-Checking for header signal.h : ok
-Checking for library rt : not found
-Checking for header pthread.h : ok
-Checking for high precision time implementation: 128-bit integer
-Checking for header stdint.h : ok
-Checking for header inttypes.h : ok
-Checking for header sys/inttypes.h : not found
-Checking for package gtk+-2.0 >= 2.12 : not found
-Checking for library sqlite3 : ok
-Checking for package goocanvas gthread-2.0 : not found
-Checking for program python : ok /usr/local/bin/python
-Checking for Python version >= 2.3 : ok 2.4.3
-Checking for library python2.4 : not found
-Checking for library python2.4 : not found
-Checking for library python24 : not found
-Checking for program python2.4-config : not found
-Checking for header Python.h : not found
-Checking for program diff : ok /usr/bin/diff
-Checking for program hg : ok /opt/local/bin/hg
+Checking for program g++ : ok /usr/bin/g++
+Checking for program cpp : ok /usr/bin/cpp
+Checking for program ar : ok /usr/bin/ar
+Checking for program ranlib : ok /usr/bin/ranlib
+Checking for g++ : ok
+Checking for program pkg-config : ok /usr/bin/pkg-config
+Checking for regression reference traces : ok ../ns-3-dev-ref-traces (guessed)
+Checking for -Wno-error=deprecated-declarations support : yes
+Checking for header stdlib.h : ok
+Checking for header signal.h : ok
+Checking for header pthread.h : ok
+Checking for high precision time implementation : 128-bit integer
+Checking for header stdint.h : ok
+Checking for header inttypes.h : ok
+Checking for header sys/inttypes.h : not found
+Checking for library rt : ok
+Checking for header netpacket/packet.h : ok
+Checking for header linux/if_tun.h : ok
+Checking for pkg-config flags for GTK_CONFIG_STORE : ok
+Package libxml-2.0 was not found in the pkg-config search path.
+Perhaps you should add the directory containing `libxml-2.0.pc'
+to the PKG_CONFIG_PATH environment variable
+No package 'libxml-2.0' found
+Checking for pkg-config flags for LIBXML2 : not found
+Checking for library sqlite3 : ok
+Checking for NSC location : ok ../nsc (guessed)
+Checking for library dl : ok
+Checking for NSC supported architecture x86_64 : ok
+Package goocanvas was not found in the pkg-config search path.
+Perhaps you should add the directory containing `goocanvas.pc'
+to the PKG_CONFIG_PATH environment variable
+No package 'goocanvas' found
+Checking for pkg-config flags for MOBILITY_VISUALIZER : not found
+Checking for program python : ok /usr/bin/python
+Checking for Python version >= 2.3 : ok 2.5.2
+Checking for library python2.5 : ok
+Checking for program python2.5-config : ok /usr/bin/python2.5-config
+Checking for header Python.h : ok
+Checking for -fvisibility=hidden support : yes
+Checking for pybindgen location : ok ../pybindgen (guessed)
+Checking for Python module pybindgen : ok
+Checking for pybindgen version : ok 0.10.0.630
+Checking for Python module pygccxml : ok
+Checking for pygccxml version : ok 0.9.5
+Checking for program gccxml : ok /usr/local/bin/gccxml
+Checking for gccxml version : ok 0.9.0
+Checking for program sudo : ok /usr/bin/sudo
+Checking for program hg : ok /usr/bin/hg
+Checking for program valgrind : ok /usr/bin/valgrind
---- Summary of optional NS-3 features:
-Threading Primitives : enabled
-Real Time Simulator : enabled
-GtkConfigStore : not enabled (library 'gtk+-2.0 >= 2.12' not found)
-SQlite stats data output : enabled
-Network Simulation Cradle : not enabled (--enable-nsc configure option not given)
-Python Bindings : not enabled (Python development headers not found.)
-Configuration finished successfully; project is now ready to build.
+Threading Primitives : enabled
+Real Time Simulator : enabled
+Emulated Net Device : enabled
+Tap Bridge : enabled
+GtkConfigStore : enabled
+XmlIo : not enabled (library 'libxml-2.0 >= 2.7' not found)
+SQlite stats data output : enabled
+Network Simulation Cradle : enabled
+Python Bindings : enabled
+Python API Scanning Support : enabled
+Use sudo to set suid bit : not enabled (option --enable-sudo not selected)
+Configuration finished successfully (00:00:02); project is now ready to build.
@end verbatim
-Note the trailing portion of the above output. Some ns-3 options are
-not enabled by default or require support from the underlying system.
-For instance, to enable Python bindings, Python development headers must
-be installed on the host machine, and they were not found in the above
-example, so Python scripting will not be supported in the resulting build.
-For this tutorial, we will focus on the non-optional pieces of ns-3.
+Note the last part of the above output. Some ns-3 options are not enabled by
+default or require support from the underlying system to work properly
+For instance, to enable XmlTo, the library libxml-2.0 must be found on the
+system. in the example above, this library was not found and the corresponding
+feature was not enabled. There is a feature to use sudo to set the suid bit of
+certain programs. This was not enabled by default.
+
+Now go ahead and switch back to the debug build.
+
+@verbatim
+ ./waf -d debug configure
+@end verbatim
The build system is now configured and you can build the debug versions of
the @command{ns-3} programs by simply typing,
@@ -206,15 +423,29 @@ the @command{ns-3} programs by simply typing,
./waf
@end verbatim
-(Hint: if you have a multicore machine, use the "-j JOBS" option to speed
-up your build, where JOBS is the number of cores)
-You will see many Waf status messages displayed as the system compiles. The
-most important is the last one:
+Some waf commands are meaningful during the build phase and some commands are valid
+in the configuration phase. For example, if you wanted to use the emulation
+features of @command{ns-3} you might want to enable setting the suid bit using
+sudo. This is a configuration command, and so you could have run the following
+command
@verbatim
- Compilation finished successfully
+ ./waf -d debug --enable-sudo configure
@end verbatim
+If you had done this, waf would have run sudo to change the socket creator
+programs to run as root. There are many other configure- and build-time options
+available in waf. To explore these options, type:
+
+@verbatim
+ ./waf -- help
+@end verbatim
+
+We'll use some of the testing-related commands in the next section.
+
+Okay, sorry, I made you build the @command{ns-3} part of the system twice,
+but now you know how to change the configuration and build optimized code.
+
@c ========================================================================
@c Testing ns-3
@c ========================================================================
@@ -234,19 +465,22 @@ You should see a report from each unit test that executes indicating that the
test has passed.
@verbatim
- ~/repos/ns-3-dev > ./waf check
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
+ Entering directory `repos/ns-3-allinone/ns-3-dev/build'
+ Build finished successfully (00:00:00)
+ -- Running NS-3 C++ core unit tests...
PASS AddressHelper
PASS Wifi
PASS DcfManager
-
...
-
PASS Object
PASS Ptr
PASS Callback
- ~/repos/ns-3-dev >
+ -- Running NS-3 Python bindings unit tests...
+ ...........
+ ----------------------------------------------------------------------
+ Ran 11 tests in 0.003s
+
+ OK
@end verbatim
This command is typically run by @code{users} to quickly verify that an
@@ -255,60 +489,66 @@ This command is typically run by @code{users} to quickly verify that an
@cindex regression tests
You can also run our regression test suite to ensure that your distribution and
tool chain have produced binaries that generate output that is identical to
-reference output files stored in a central location. To run the regression
-tests, you provide Waf with the regression flag.
+known-good reference output files. You downloaded these reference traces to
+your machine during the download process above. (Warning: The @code{ns-3.2}
+and @code{ns-3.3} releases do not use the @code{ns-3-allinone} environment
+and require you to be online when you run regression tests because they
+dynamically synchronize the reference traces directory with an online
+repository immediately prior to the run).
+
+During regression testing Waf will run a number of tests that generate what we
+call trace files. The content of these trace files are compared with the
+reference traces. If they are identical, the regression tests report a PASS
+status. If a regression test fails you will see a FAIL indication along with a
+pointer to the offending trace file and its associated reference trace file
+along with a suggestion on diff parameters and options in order to see what
+has gone awry. If the error was discovered in a pcap file, it will be useful
+to convert the pcap files to text using tcpdump prior to comparison.
+
+Some regression tests wmay be SKIPped if the required support
+is not present.
+
+To run the regression tests, you provide Waf with the regression flag.
@verbatim
./waf --regression
@end verbatim
-Waf will verify that the current files in the @command{ns-3} distribution are
-built and will then look for trace files in the aforementioned centralized
-location. If your tool chain includes Mercurial, the regression tests will
-be downloaded from a repository at @code{code.nsnam.org}. If you do not have
-Mercurial installed, the reference traces will be downloaded from a tarball
-located in the releases section of @code{www.nsnam.org}. The particular name
-of the reference trace location is built from the @command{ns-3} version
-located in the VERSION file, so don't change that string yourself unless you
-know what you are doing. (Warning: The ns-3.2 release requires you
-to be online when you run regression tests because it synchronizes the
-trace directory with an online repository).
-
-Once the reference traces are downloaded to your local machine, Waf will run
-a number of tests that generate what we call trace files. The content of
-these trace files are compared with the reference traces just downloaded. If
-they are identical, the regression tests report a PASS status. If the
-regression tests pass, you should see something like,
+You should see messages indicating that many tests are being run and are
+passing.
@verbatim
- ~/repos/ns-3-dev > ./waf --regression
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
- ========== Running Regression Tests ==========
- Synchronizing reference traces using Mercurial.
- Pulling http://code.nsnam.org/ns-3-dev-ref-traces from repo.
- Skipping csma-bridge: Python bindings not available.
- SKIP test-csma-bridge
- PASS test-csma-broadcast
+ Entering directory `repos/ns-3-allinone/ns-3-dev/build'
+ [647/669] regression-test (test-csma-bridge)
+ [648/669] regression-test (test-csma-broadcast)
+ [649/669] regression-test (test-csma-multicast)
+ [650/669] regression-test (test-csma-one-subnet)
PASS test-csma-multicast
- PASS test-csma-one-subnet
- PASS test-csma-packet-socket
- PASS test-realtime-udp-echo
- PASS test-simple-error-model
- PASS test-simple-global-routing
- PASS test-simple-point-to-point-olsr
- PASS test-tcp-large-transfer
- PASS test-udp-echo
- PASS test-wifi-wired-bridging
-
- ~/repos/ns-3-dev >
+ [651/669] regression-test (test-csma-packet-socket)
+ PASS test-csma-bridge
+ ...
+ Regression testing summary:
+ PASS: 22 of 22 tests passed
+ Build finished successfully (00:00:23)
@end verbatim
-If a regression tests fails you will see a FAIL indication along with a
-pointer to the offending trace file and its associated reference trace file
-along with a suggestion on diff parameters and options in order to see what
-has gone awry. Python regression tests will be SKIPped if Python bindings
-are not built.
+If you want to take a look at an example of what might be checked during
+a regression test, you can do the following:
+
+@verbatim
+ cd build/debug/regression/traces/second.ref
+ tcpdump -nn -tt -r second-2-0.pcap
+@end verbatim
+
+The output should be clear to anyone who is familiar with tcpdump or net
+sniffers. We'll have much more to say on pcap files later in this tutorial.
+
+Remember to cd back into the top-level @command{ns-3} directory
+after you are done:
+
+@verbatim
+ cd ../../../../..
+@end verbatim
@c ========================================================================
@c Running a Script
diff --git a/doc/tutorial/in-process/introduction.texi b/doc/tutorial/in-process/introduction.texi
index f57fa0236..17cb4d7c9 100644
--- a/doc/tutorial/in-process/introduction.texi
+++ b/doc/tutorial/in-process/introduction.texi
@@ -487,7 +487,7 @@ the following into your Linux shell (assuming you have installed Mercurial):
cd
mkdir repos
cd !$
- hg clone http://code.nanam.org/ns-3-dev
+ hg clone http://code.nsnam.org/ns-3-dev
@end verbatim
As the hg command executes, you should see something like the following,
diff --git a/doc/tutorial/introduction.texi b/doc/tutorial/introduction.texi
index 6580bcbb7..299264155 100644
--- a/doc/tutorial/introduction.texi
+++ b/doc/tutorial/introduction.texi
@@ -24,7 +24,7 @@
The @command{ns-3} simulator is a discrete-event network simulator targeted
primarily for research and educational use. The
@uref{http://www.nsnam.org,,ns-3 project},
-started in 2006, is an open-source project developing ns-3.
+started in 2006, is an open-source project developing @command{ns-3}.
Primary documentation for the @command{ns-3} project is available in four
forms:
@@ -43,7 +43,7 @@ information into working simulations. In this tutorial, we will build
several example simulations, introducing and explaining key concepts and
features as we go.
-As the tutorial unfolds, we will introduce the full ns-3 documentation
+As the tutorial unfolds, we will introduce the full @command{ns-3} documentation
and provide pointers to source code for those interested in delving deeper
into the workings of the system.
@@ -52,9 +52,9 @@ A few key points are worth noting at the onset:
@item Ns-3 is not an extension of @uref{http://www.isi.edu/nsnam/ns,,ns-2};
it is a new simulator. The two simulators are both written in C++ but
@command{ns-3} is a new simulator that does not support the ns-2 APIs. Some
-models from ns-2 have already been ported from ns-2 to ns-3. The project will
-continue to maintain ns-2 while ns-3 is being built, and will study transition
-and integration mechanisms.
+models from ns-2 have already been ported from ns-2 to @command{ns-3}. The
+project will continue to maintain ns-2 while @command{ns-3} is being built,
+and will study transition and integration mechanisms.
@item @command{Ns-3} is open-source, and the project strives to maintain an
open environment for researchers to contribute and share their software.
@end itemize
@@ -63,36 +63,36 @@ open environment for researchers to contribute and share their software.
@section For ns-2 Users
For those familiar with ns-2, the most visible outward change when moving to
-ns-3 is the choice of scripting language. Ns-2 is
+@command{ns-3} is the choice of scripting language. Ns-2 is
scripted in OTcl and results of simulations can be visualized using the
Network Animator @command{nam}. It is not possible to run a simulation
in ns-2 purely from C++ (i.e., as a main() program without any OTcl).
Moreover, some components of ns-2 are written in C++ and others in OTcl.
-In ns-3, the simulator is written entirely in C++, with optional
+In @command{ns-3}, the simulator is written entirely in C++, with optional
Python bindings. Simulation scripts can therefore be written in C++
or in Python. The results of some simulations can be visualized by
-@command{nam}, but new animators are under development. Since ns-3
+@command{nam}, but new animators are under development. Since @command{ns-3}
generates pcap packet trace files, other utilities can be used to
analyze traces as well.
In this tutorial, we will first concentrate on scripting
directly in C++ and interpreting results via ascii trace files.
But there are similarities as well (both, for example, are based on C++
-objects, and some code from ns-2 has already been ported to ns-3).
-We will try to highlight differences between ns-2 and ns-3
+objects, and some code from ns-2 has already been ported to @command{ns-3}).
+We will try to highlight differences between ns-2 and @command{ns-3}
as we proceed in this tutorial.
A question that we often hear is "Should I still use ns-2 or move to
-ns-3?" The answer is that it depends. ns-3 does not have all of the
-models that ns-2 currently has, but on the other hand, ns-3 does have
-new capabilities (such as handling multiple interfaces on nodes
+@command{ns-3}?" The answer is that it depends. @command{ns-3} does not have
+all of the models that ns-2 currently has, but on the other hand, @command{ns-3}
+does have new capabilities (such as handling multiple interfaces on nodes
correctly, use of IP addressing and more alignment with Internet
protocols and designs, more detailed 802.11 models, etc.). ns-2
-models can usually be ported to ns-3 (a porting guide is under
-development). There is active development on multiple fronts for ns-3.
-The ns-3 developers believe (and certain early users have proven) that
-ns-3 is ready for active use, and should be an attractive alternative
-for users looking to start new simulation projects.
+models can usually be ported to @command{ns-3} (a porting guide is under
+development). There is active development on multiple fronts for
+@command{ns-3}. The @command{ns-3} developers believe (and certain early users
+have proven) that @command{ns-3} is ready for active use, and should be an
+attractive alternative for users looking to start new simulation projects.
@node Contributing
@section Contributing
@@ -119,7 +119,7 @@ We realize that if you are reading this document, contributing back to
the project is probably not your foremost concern at this point, but
we want you to be aware that contributing is in the spirit of the project and
that even the act of dropping us a note about your early experience
-with ns-3 (e.g. "this tutorial section was not clear..."),
+with @command{ns-3} (e.g. "this tutorial section was not clear..."),
reports of stale documentation, etc. are much appreciated.
@node Tutorial Organization
@@ -160,14 +160,14 @@ broad sequences of events.
@cindex architecture
There are several important resources of which any @command{ns-3} user must be
aware. The main web site is located at @uref{http://www.nsnam.org} and
-provides access to basic information about the ns-3 system. Detailed
+provides access to basic information about the @command{ns-3} system. Detailed
documentation is available through the main web site at
@uref{http://www.nsnam.org/documents.html}. You can also find documents
relating to the system architecture from this page.
-There is a Wiki that complements the main ns-3 web site which you will find at
-@uref{http://www.nsnam.org/wiki/}. You will find user and developer FAQs
-there, as well as troubleshooting guides, third-party contributed code,
+There is a Wiki that complements the main @command{ns-3} web site which you will
+find at @uref{http://www.nsnam.org/wiki/}. You will find user and developer
+FAQs there, as well as troubleshooting guides, third-party contributed code,
papers, etc.
@cindex mercurial repository
@@ -221,7 +221,7 @@ using the Python language.
The build system @code{Waf} is used on the @command{ns-3} project. It is one
of the new generation of Python-based build systems. You will not need to
-understand any Python to build the existing ns-3 system, and will
+understand any Python to build the existing @command{ns-3} system, and will
only have to understand a tiny and intuitively obvious subset of Python in
order to extend the system in most cases.
@@ -233,9 +233,9 @@ found at @uref{http://freehackers.org/~tnagy/waf.html}.
@cindex C++
@cindex Python
-As mentioned above, scripting in ns-3 is done in C++ or Python.
-As of ns-3.2, most of the ns-3 API is available in Python, but the models
-are written in C++ in either case. A working
+As mentioned above, scripting in @command{ns-3} is done in C++ or Python.
+As of ns-3.2, most of the @command{ns-3} API is available in Python, but the
+models are written in C++ in either case. A working
knowledge of C++ and object-oriented concepts is assumed in this document.
We will take some time to review some of the more advanced concepts or
possibly unfamiliar language features, idioms and design patterns as they
@@ -255,7 +255,7 @@ The @command{ns-3} system uses several components of the GNU ``toolchain''
for development. A
software toolchain is the set of programming tools available in the given
environment. For a quick review of what is included in the GNU toolchain see,
-@uref{http://en.wikipedia.org/wiki/GNU_toolchain}. ns-3 uses gcc,
+@uref{http://en.wikipedia.org/wiki/GNU_toolchain}. @command{ns-3} uses gcc,
GNU binutils, and gdb. However, we do not use the GNU build system,
either make or autotools, using Waf instead.
diff --git a/doc/tutorial/tweaking.texi b/doc/tutorial/tweaking.texi
index 6736655e9..8a7ebcbf5 100644
--- a/doc/tutorial/tweaking.texi
+++ b/doc/tutorial/tweaking.texi
@@ -82,8 +82,8 @@ documentation and now would be a good time to peruse the Logging Module
documentation if you have not done so.
Now that you have read the documentation in great detail, let's use some of
-that knowledge to get some interesting information out of the @code{first.cc}
-example script you have already built.
+that knowledge to get some interesting information out of the
+@code{scratch/myfirst.cc} example script you have already built.
@node Enabling Logging
@subsection Enabling Logging
@@ -92,17 +92,22 @@ Let's use the NS_LOG environment variable to turn on some more logging, but
to get our bearings, go ahead and run the script just as you did previously,
@verbatim
- ~/repos/ns-3-dev > ./waf --run scratch/first
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
+ ./waf --run scratch/myfirst
+@end verbatim
+
+You should see the now familiar output of the first @command{ns-3} example
+program
+
+@verbatim
+ Entering directory `repos/ns-3-dev/build'
Compilation finished successfully
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2
- ~/repos/ns-3-dev >
@end verbatim
-It turns out that the ``Sent'' and ``Received'' messages are actually logging
-messages from the @code{UdpEchoClientApplication} and
+It turns out that the ``Sent'' and ``Received'' messages you see above are
+actually logging messages from the @code{UdpEchoClientApplication} and
@code{UdpEchoServerApplication}. We can ask the client application, for
example, to print more information by setting its logging level via the
NS_LOG environment variable.
@@ -113,7 +118,7 @@ will have to convert my examples to the ``setenv VARIABLE value'' syntax
required by those shells.
Right now, the UDP echo client application is responding to the following line
-of code in @code{first.cc},
+of code in @code{scratch/myfirst.cc},
@verbatim
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
@@ -127,7 +132,7 @@ increase the logging level and get more information without changing the
script and recompiling by setting the NS_LOG environment variable like this:
@verbatim
- ~/repos/ns-3-dev > export NS_LOG=UdpEchoClientApplication=level_all
+ export NS_LOG=UdpEchoClientApplication=level_all
@end verbatim
This sets the shell environment variable @code{NS_LOG} to the string,
@@ -143,21 +148,19 @@ you run the script with NS_LOG set this way, the @command{ns-3} logging
system will pick up the change and you should see the following output:
@verbatim
- ~/repos/ns-3-dev > ./waf --run scratch/first
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
+ Entering directory `repos/ns-3-allinone/ns-3-dev/build'
+ Build finished successfully (00:00:00)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
- UdpEchoClientApplication:HandleRead(0x62c640, 0x62cd70)
+ UdpEchoClientApplication:HandleRead(0x638180, 0x6389b0)
Received 1024 bytes from 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
- ~/repos/ns-3-dev >
@end verbatim
The additional debug information provided by the application is from
@@ -198,21 +201,19 @@ that every message from the given log component is prefixed with the component
name.
@verbatim
- ~/repos/ns-3-dev > ./waf --run scratch/first
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
+ Entering directory `repos/ns-3-allinone/ns-3-dev/build'
+ Build finished successfully (00:00:00)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
- UdpEchoClientApplication:HandleRead(0x62c710, 0x62ce40)
+ UdpEchoClientApplication:HandleRead(0x638180, 0x6389b0)
UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
- ~/repos/ns-3-dev >
@end verbatim
You can now see all of the messages coming from the UDP echo client application
@@ -227,17 +228,16 @@ the NS_LOG environment variable.
UdpEchoServerApplication=level_all|prefix_func'
@end verbatim
-Note that you will need to remove the newline after the @code{:} in the
-example text above.
+Warning: You will need to remove the newline after the @code{:} in the
+example text above which is only there for document formatting purposes.
Now, if you run the script you will see all of the log messages from both the
echo client and server applications. You may see that this can be very useful
in debugging problems.
@verbatim
- ~/repos/ns-3-dev > ./waf --run scratch/first
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
+ Entering directory `repos/ns-3-allinone/ns-3-dev/build'
+ Build finished successfully (00:00:00)
UdpEchoServerApplication:UdpEchoServer()
UdpEchoClientApplication:UdpEchoClient()
UdpEchoServerApplication:StartApplication()
@@ -247,7 +247,7 @@ in debugging problems.
UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
UdpEchoServerApplication:HandleRead(): Echoing packet
- UdpEchoClientApplication:HandleRead(0x62c760, 0x62ce90)
+ UdpEchoClientApplication:HandleRead(0x638320, 0x638b50)
UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
UdpEchoServerApplication:StopApplication()
UdpEchoClientApplication:StopApplication()
@@ -255,7 +255,6 @@ in debugging problems.
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()
- ~/repos/ns-3-dev >
@end verbatim
It is also sometimes useful to be able to see the simulation time at which a
@@ -266,12 +265,12 @@ log message is generated. You can do this by ORing in the prefix_time bit.
UdpEchoServerApplication=level_all|prefix_func|prefix_time'
@end verbatim
-If you run the script now, you should see the following output:
+Again, you will have to remove the newline above. If you run the script now,
+you should see the following output:
@verbatim
- ~/repos/ns-3-dev > ./waf --run scratch/first
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
+ Entering directory `repos/ns-3-allinone/ns-3-dev/build'
+ Build finished successfully (00:00:00)
0s UdpEchoServerApplication:UdpEchoServer()
0s UdpEchoClientApplication:UdpEchoClient()
1s UdpEchoServerApplication:StartApplication()
@@ -281,7 +280,7 @@ If you run the script now, you should see the following output:
2s UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): Echoing packet
- 2.00737s UdpEchoClientApplication:HandleRead(0x62c8c0, 0x62d020)
+ 2.00737s UdpEchoClientApplication:HandleRead(0x638490, 0x638cc0)
2.00737s UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
@@ -289,15 +288,14 @@ If you run the script now, you should see the following output:
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()
- ~/repos/ns-3-dev >
@end verbatim
You can see that the constructor for the UdpEchoServer was called at a
simulation time of 0 seconds. This is actually happening before the
simulation starts. The same for the UdpEchoClient constructor.
-Recall that the @code{first.cc} script started the echo server application at
-one second into the simulation. You can now see that the
+Recall that the @code{scratch/first.cc} script started the echo server
+application at one second into the simulation. You can now see that the
@code{StartApplication} method of the server is, in fact, called at one second
(or one billion nanoseconds). You can also see that the echo client
application is started at a simulation time of two seconds as we requested in
@@ -322,29 +320,29 @@ turning on all of the logging components in the system. Try setting the
The asterisk above is the logging component wildcard. This will turn on all
of the logging in all of the components used in the simulation. I won't
-reproduce the output here (as of this writing it produces 772 lines of output
+reproduce the output here (as of this writing it produces 974 lines of output
for the single packet echo) but you can redirect this information into a file
and look through it with your favorite editor if you like,
@verbatim
- ~/repos/ns-3-dev > ./waf --run scratch/first >& log.out
+ ./waf --run scratch/myfirst > log.out 2>&1
@end verbatim
-I personally use this quite a bit when I am presented with a problem and I
-have no idea where things are going wrong. I can follow the progress of the
-code quite easily without having to set breakpoints and step through code
-in a debugger. When I have a general idea about what is going wrong, I
-transition into a debugger for fine-grained examination of the problem. This
-kind of output can be especially useful when your script does something
-completely unexpected. If you are stepping using a debugger you may miss an
-unexpected excursion completely. Logging the excursion makes it quickly
-visible.
+I personally use this volume of logging quite a bit when I am presented with
+a problem and I have no idea where things are going wrong. I can follow the
+progress of the code quite easily without having to set breakpoints and step
+through code in a debugger. When I have a general idea about what is going
+wrong, I transition into a debugger for fine-grained examination of the
+problem. This kind of output can be especially useful when your script does
+something completely unexpected. If you are stepping using a debugger you
+may miss an unexpected excursion completely. Logging the excursion makes it
+quickly visible.
@node Adding Logging to your Code
@subsection Adding Logging to your Code
@cindex NS_LOG
You can add new logging to your simulations by making calls to the log
-component via several macros. Let's do so in the @code{first.cc} script we
+component via several macros. Let's do so in the @code{myfirst.cc} script we
have in the @code{scratch} directory.
Recall that we have defined a logging component in that script:
@@ -357,43 +355,56 @@ You now know that you can enable all of the logging for this component by
setting the @code{NS_LOG} environment variable to the various levels. Let's
go ahead add some logging to the script. The macro used to add an
informational level log message is @code{NS_LOG_INFO}. Go ahead and add one
-just before we start creating the nodes that tells you that the script is
+(just before we start creating the nodes) that tells you that the script is
``Creating Topology.'' This is done as in this code snippet,
+Open @code{scratch/myfirst.cc} in your favorite editor and add the line,
+
@verbatim
NS_LOG_INFO ("Creating Topology");
@end verbatim
+right before the lines,
+
+@verbatim
+ NodeContainer nodes;
+ nodes.Create (2);
+@end verbatim
+
Now build the script using waf and clear the @code{NS_LOG} variable to turn
off the torrent of logging we previously enabled:
@verbatim
- ~/repos/ns-3-dev > export NS_LOG=
+ ./waf
+ export NS_LOG=
@end verbatim
-Now, if you run the script, you will not see your new message since its
-associated logging component (@code{FirstScriptExample}) has not been enabled.
-In order to see your message you will have to enable the
-@code{FirstScriptExample} logging component with a level greater than or equal
-to @code{NS_LOG_INFO}. If you just want to see this particular level of
-logging, you can enable it by,
+Now, if you run the script,
@verbatim
- ~/repos/ns-3-dev > export NS_LOG=FirstScriptExample=info
+ ./waf --run scratch/myfirst
+@end verbatim
+
+you will @emph{not} see your new message since its associated logging
+component (@code{FirstScriptExample}) has not been enabled. In order to see your
+message you will have to enable the @code{FirstScriptExample} logging component
+with a level greater than or equal to @code{NS_LOG_INFO}. If you just want to
+see this particular level of logging, you can enable it by,
+
+@verbatim
+ export NS_LOG=FirstScriptExample=info
@end verbatim
If you now run the script you will see your new ``Creating Topology'' log
message,
@verbatim
- ~/repos/ns-3-dev > ./waf --run scratch/first
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
+ Entering directory `repos/ns-3-allinone/ns-3-dev/build'
+ Build finished successfully (00:00:00)
Creating Topology
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2
- ~/repos/ns-3-dev >
@end verbatim
@c ========================================================================
@@ -427,35 +438,33 @@ in the following code,
@end verbatim
This simple two line snippet is actually very useful by itself. It opens the
-door to the @command{ns-3} global variable and attribute systems. Go ahead
-and add that two lines of code to the @code{first.cc} script at the start of
-@code{main}. Go ahead and build the script and run it, but ask the script
-for help in the following way,
+door to the @command{ns-3} global variable and @code{Attribute} systems. Go
+ahead and add that two lines of code to the @code{scratch/first.cc} script at
+the start of @code{main}. Go ahead and build the script and run it, but ask
+the script for help in the following way,
@verbatim
- ~/repos/ns-3-dev > ./waf --run "scratch/first --PrintHelp"
+ ./waf --run "scratch/myfirst --PrintHelp"
@end verbatim
-This will ask Waf to run the @code{scratch/first} script and pass the command
+This will ask Waf to run the @code{scratch/myfirst} script and pass the command
line argument @code{--PrintHelp} to the script. The quotes are required to
sort out which program gets which argument. The command line parser will
now see the @code{--PrintHelp} argument and respond with,
@verbatim
- ~/repos/ns-3-dev > ./waf --run ``scratch/first --PrintHelp''
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
+ Entering directory `repos/ns-3-allinone/ns-3-dev/build'
+ Build finished successfully (00:00:00)
--PrintHelp: Print this help message.
--PrintGroups: Print the list of groups.
--PrintTypeIds: Print all TypeIds.
--PrintGroup=[group]: Print all TypeIds of group.
--PrintAttributes=[typeid]: Print all attributes of typeid.
--PrintGlobals: Print the list of globals.
- ~/repos/ns-3-dev >
@end verbatim
Let's focus on the @code{--PrintAttributes} option. We have already hinted
-at the @command{ns-3} attribute system while walking through the
+at the @command{ns-3} @code{Attribute} system while walking through the
@code{first.cc} script. We looked at the following lines of code,
@verbatim
@@ -466,17 +475,17 @@ at the @command{ns-3} attribute system while walking through the
and mentioned that @code{DataRate} was actually an @code{Attribute} of the
@code{PointToPointNetDevice}. Let's use the command line argument parser
-to take a look at the attributes of the PointToPointNetDevice. The help
+to take a look at the @code{Attributes} of the PointToPointNetDevice. The help
listing says that we should provide a @code{TypeId}. This corresponds to the
-class name of the class to which the attributes belong. In this case it will
-be @code{ns3::PointToPointNetDevice}. Let's go ahead and type in,
+class name of the class to which the @code{Attributes} belong. In this case it
+will be @code{ns3::PointToPointNetDevice}. Let's go ahead and type in,
@verbatim
- ./waf --run "scratch/first --PrintAttributes=ns3::PointToPointNetDevice"
+ ./waf --run "scratch/myfirst --PrintAttributes=ns3::PointToPointNetDevice"
@end verbatim
-The system will print out all of the attributes of this kind of net device.
-Among the attributes you will see listed is,
+The system will print out all of the @code{Attributes} of this kind of net device.
+Among the @code{Attributes} you will see listed is,
@verbatim
--ns3::PointToPointNetDevice::DataRate=[32768bps]:
@@ -484,7 +493,7 @@ Among the attributes you will see listed is,
@end verbatim
This is the default value that will be used when a @code{PointToPointNetDevice}
-is created in the system. We overrode this default with the attribute
+is created in the system. We overrode this default with the @code{Attribute}
setting in the @code{PointToPointHelper} above. Let's use the default values
for the point-to-point devices and channels by deleting the
@code{SetDeviceAttribute} call and the @code{SetChannelAttribute} call from
@@ -518,24 +527,26 @@ time prefix.
If you run the script, you should now see the following output,
@verbatim
- ~/repos/ns-3-dev > ./waf --run scratch/first
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
- 0ns UdpEchoServerApplication:UdpEchoServer()
- 1000000000ns UdpEchoServerApplication:StartApplication()
+ Build finished successfully (00:00:00)
+ 0s UdpEchoServerApplication:UdpEchoServer()
+ 1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
- 2257324218ns Received 1024 bytes from 10.1.1.1
- 2257324218ns Echoing packet
+ 2.25732s Received 1024 bytes from 10.1.1.1
+ 2.25732s Echoing packet
Received 1024 bytes from 10.1.1.2
- 10000000000ns UdpEchoServerApplication:StopApplication()
+ 10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()
- ~/repos/ns-3-dev >
@end verbatim
Recall that the last time we looked at the simulation time at which the packet
-was received by the echo server, it was at 2.0036864 seconds. Now it is
-receiving the packet at about 2.257 seconds. This is because we just dropped
+was received by the echo server, it was at 2.00369 seconds.
+
+@verbatim
+ 2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
+@end verbatim
+
+Now it is receiving the packet at 2.25732 seconds. This is because we just dropped
the data rate of the @code{PointToPointNetDevice} down to its default of
32768 bits per second from five megabits per second.
@@ -544,20 +555,21 @@ speed our simulation up again. We do this in the following way, according to
the formula implied by the help item:
@verbatim
- ./waf --run "scratch/first --ns3::PointToPointNetDevice::DataRate=5Mbps"
+ ./waf --run "scratch/myfirst --ns3::PointToPointNetDevice::DataRate=5Mbps"
@end verbatim
-This will set the default value of the @code{DataRate} attribute back to
-five megabits per second. To get the original behavior of the script back,
-we will have to set the speed-of-light delay of the channel. We can ask the
-command line system to print out the @code{Attributes} of the channel just
-like we did the net device:
+This will set the default value of the @code{DataRate} @code{Attribute} back to
+five megabits per second. Are you surprised by the result? It turns out that
+in order to get the original behavior of the script back, we will have to set
+the speed-of-light delay of the channel as well. We can ask the command line
+system to print out the @code{Attributes} of the channel just like we did for
+the net device:
@verbatim
- ./waf --run "scratch/first --PrintAttributes=ns3::PointToPointChannel"
+ ./waf --run "scratch/myfirst --PrintAttributes=ns3::PointToPointChannel"
@end verbatim
-We discover the @code{Delay} attribute of the channel is set in the following
+We discover the @code{Delay} @code{Attribute} of the channel is set in the following
way:
@verbatim
@@ -568,7 +580,7 @@ way:
We can then set both of these default values through the command line system,
@verbatim
- ./waf --run "scratch/first
+ ./waf --run "scratch/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::Delay=2ms"
@end verbatim
@@ -577,25 +589,26 @@ in which case we recover the timing we had when we explicitly set the
@code{DataRate} and @code{Delay} in the script:
@verbatim
- Compilation finished successfully
- 0ns UdpEchoServerApplication:UdpEchoServer()
- 1000000000ns UdpEchoServerApplication:StartApplication()
+ Entering directory `repos/ns-3-allinone/ns-3-dev/build'
+ Build finished successfully (00:00:00)
+ 0s UdpEchoServerApplication:UdpEchoServer()
+ 1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
- 2003686400ns Received 1024 bytes from 10.1.1.1
- 2003686400ns Echoing packet
+ 2.00369s Received 1024 bytes from 10.1.1.1
+ 2.00369s Echoing packet
Received 1024 bytes from 10.1.1.2
- 10000000000ns UdpEchoServerApplication:StopApplication()
+ 10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()
@end verbatim
-Note that the packet is again received by the server at 2.0036864 seconds. We
-could actually set any of the attributes used in the script in this way. In
-particular we could set the @code{UdpEchoClient} attribute @code{MaxPackets}
+Note that the packet is again received by the server at 2.00369 seconds. We
+could actually set any of the @code{Attributes} used in the script in this way.
+In particular we could set the @code{UdpEchoClient Attribute MaxPackets}
to some other value than one.
How would you go about that? Give it a try. Remember you have to comment
-out the place we override the default attribute in the script. Then you
+out the place we override the default @code{Attribute} in the script. Then you
have to rebuild the script using the default. You will also have to find the
syntax for actually setting the new default atribute value using the command
line help facility. Once you have this figured out you should be able to
@@ -604,7 +617,7 @@ folks, we'll tell you that your command line should end up looking something
like,
@verbatim
- ./waf --run "scratch/first
+ ./waf --run "scratch/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::Delay=2ms
--ns3::UdpEchoClient::MaxPackets=2"
@@ -619,7 +632,7 @@ completely different way. Let's add a local variable called @code{nPackets}
to the @code{main} function. We'll initialize it to one to match our previous
default behavior. To allow the command line parser to change this value, we
need to hook the value into the parser. We do this by adding a call to
-@code{AddValue}. Go ahead and change the @code{scratch/first.cc} script to
+@code{AddValue}. Go ahead and change the @code{scratch/myfirst.cc} script to
start with the following code,
@verbatim
@@ -636,20 +649,25 @@ start with the following code,
@end verbatim
Scroll down to the point in the script where we set the @code{MaxPackets}
-attribute and change it so that it is set to the variable @code{nPackets}
+@code{Attribute} and change it so that it is set to the variable @code{nPackets}
instead of the constant @code{1} as is shown below.
@verbatim
- echoClient.SetAppAttribute ("MaxPackets", UintegerValue (nPackets));
+ echoClient.SetAttribute ("MaxPackets", UintegerValue (nPackets));
@end verbatim
Now if you run the script and provide the @code{--PrintHelp} argument, you
should see your new @code{User Argument} listed in the help display.
+Try,
+
@verbatim
- ~/repos/ns-3-dev > ./waf --run "scratch/first --PrintHelp"
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
+ ./waf --run "scratch/myfirst --PrintHelp"
+@end verbatim
+
+@verbatim
+ Entering directory `repos/ns-3-allinone/ns-3-dev/build'
+ Build finished successfully (00:00:00)
--PrintHelp: Print this help message.
--PrintGroups: Print the list of groups.
--PrintTypeIds: Print all TypeIds.
@@ -658,33 +676,43 @@ should see your new @code{User Argument} listed in the help display.
--PrintGlobals: Print the list of globals.
User Arguments:
--nPackets: Number of packets to echo
- ~/repos/ns-3-dev >
@end verbatim
If you want to specify the number of packets to echo, you can now do so by
setting the @code{--nPackets} argument in the command line,
@verbatim
- ~/repos/ns-3-dev > ./waf --run "scratch/first --nPackets=2"
- Entering directory `/home/craigdo/repos/ns-3-dev/build'
- Compilation finished successfully
+ ./waf --run "scratch/myfirst --nPackets=2"
+@end verbatim
+
+You should now see
+
+@verbatim
+ Entering directory `repos/ns-3-allinone/ns-3-dev/build'
+ Build finished successfully (00:00:00)
+ 0s UdpEchoServerApplication:UdpEchoServer()
+ 1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
- Received 1024 bytes from 10.1.1.1
+ 2.25732s Received 1024 bytes from 10.1.1.1
+ 2.25732s Echoing packet
Received 1024 bytes from 10.1.1.2
Sent 1024 bytes to 10.1.1.2
- Received 1024 bytes from 10.1.1.1
+ 3.25732s Received 1024 bytes from 10.1.1.1
+ 3.25732s Echoing packet
Received 1024 bytes from 10.1.1.2
- ~/repos/ns-3-dev >
+ 10s UdpEchoServerApplication:StopApplication()
+ UdpEchoServerApplication:DoDispose()
+ UdpEchoServerApplication:~UdpEchoServer()
@end verbatim
You have now echoed two packets.
You can see that if you are an @command{ns-3} user, you can use the command
-line argument system to control global values and attributes. If you are a
-model author, you can add new attributes to your Objects and they will
-automatically be available for setting by your users through the command line
-system. If you are a script author, you can add new variables to your scripts
-and hook them into the command line system quite painlessly.
+line argument system to control global values and @code{Attributes}. If you are
+a model author, you can add new @code{Attributes} to your @code{Objects} and
+they will automatically be available for setting by your users through the
+command line system. If you are a script author, you can add new variables to
+your scripts and hook them into the command line system quite painlessly.
@c ========================================================================
@c Using the Tracing System
@@ -764,17 +792,26 @@ generated by many scripts.
@cindex tracing packets
Let's just jump right in and add some ASCII tracing output to our
-@code{first.cc} script. The first thing you need to do is to add the
-following code to the script just before the call to @code{Simulator::Run ()}.
+@code{scratch/myfirst.cc} script.
+
+The first thing you need to do is to add the following include to the top of
+the script just after the GNU GPL comment:
+
+@verbatim
+ #include
+@end verbatim
+
+Then, right before the before the call to @code{Simulator::Run ()}, add the
+following lines of code.
@verbatim
std::ofstream ascii;
- ascii.open ("first.tr");
+ ascii.open ("myfirst.tr");
PointToPointHelper::EnableAsciiAll (ascii);
@end verbatim
The first two lines are just vanilla C++ code to open a stream that will be
-written to a file named ``first.tr.'' See your favorite C++ tutorial if you
+written to a file named ``myfirst.tr.'' See your favorite C++ tutorial if you
are unfamiliar with this code. The last line of code in the snippet above
tells @command{ns-3} that you want to enable ASCII tracing on all
point-to-point devices in your simulation; and you want the (provided) trace
@@ -782,32 +819,24 @@ sinks to write out information about packet movement in ASCII format to the
stream provided. For those familiar with @command{ns-2}, the traced events are
equivalent to the popular trace points that log "+", "-", "d", and "r" events.
-Since we have used a @code{std::ofstream} object, we also need to include the
-appropriate header. Add the following line to the script (I typically add it
-above the ns-3 includes):
-
-@verbatim
- #include
-@end verbatim
-
You can now build the script and run it from the command line:
@verbatim
- ./waf --run scratch/first
+ ./waf --run scratch/myfirst
@end verbatim
-@cindex first.tr
-Just as you have seen previously, you may see some messages from Waf and then
-the ``Compilation finished successfully'' with some number of messages from
+@cindex myfirst.tr
+Just as you have seen many times before, you will see some messages from Waf and then
+the ``Build finished successfully'' with some number of messages from
the running program.
-When it ran, the program will have created a file named @code{first.tr}.
+When it ran, the program will have created a file named @code{myfirst.tr}.
Because of the way that Waf works, the file is not created in the local
directory, it is created at the top-level directory of the repository by
default. If you want to control where the traces are saved you can use the
@code{--cwd} option of Waf to specify this. We have not done so, thus we
need to change into the top level directory of our repo and take a look at
-the ASCII trace file @code{first.tr} in your favorite editor.
+the ASCII trace file @code{myfirst.tr} in your favorite editor.
@subsubsection Parsing Ascii Traces
@cindex parsing ascii traces
@@ -844,7 +873,7 @@ number on the left side:
03 ns3::PppHeader (
04 Point-to-Point Protocol: IP (0x0021))
05 ns3::Ipv4Header (
- 06 tos 0x0 ttl 64 id 0 offset 0 flags [none]
+ 06 tos 0x0 ttl 64 id 0 protocol 17 offset 0 flags [none]
07 length: 1052 10.1.1.1 > 10.1.1.2)
08 ns3::UdpHeader (
09 length: 1032 49153 > 9)
@@ -898,7 +927,7 @@ device on the node with the echo server. I have reproduced that event below.
@verbatim
00 r
01 2.25732
- 02 /NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/Rx
+ 02 /NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/MacRx
03 ns3::PppHeader (
04 Point-to-Point Protocol: IP (0x0021))
05 ns3::Ipv4Header (
@@ -917,7 +946,7 @@ be familiar as you have seen it before in a previous section.
The trace source namespace entry (reference 02) has changed to reflect that
this event is coming from node 1 (@code{/NodeList/1}) and the packet reception
-trace source (@code{/Rx}). It should be quite easy for you to follow the
+trace source (@code{/MacRx}). It should be quite easy for you to follow the
progress of the packet through the topology by looking at the rest of the
traces in the file.
@@ -937,54 +966,54 @@ traces. In this tutorial, we concentrate on viewing pcap traces with tcpdump.
The code used to enable pcap tracing is a one-liner.
@verbatim
- PointToPointHelper::EnablePcapAll ("first");
+ PointToPointHelper::EnablePcapAll ("myfirst");
@end verbatim
Go ahead and insert this line of code after the ASCII tracing code we just
-added to @code{scratch/first.cc}. Notice that we only passed the string
-``first,'' and not ``first.pcap'' or something similar. This is because the
+added to @code{scratch/myfirst.cc}. Notice that we only passed the string
+``myfirst,'' and not ``myfirst.pcap'' or something similar. This is because the
parameter is a prefix, not a complete file name. The helper will actually
create a trace file for every point-to-point device in the simulation. The
file names will be built using the prefix, the node number, the device number
and a ``.pcap'' suffix.
-In our example script, we will eventually see files named ``first-0-0.pcap''
-and ``first.1-0.pcap'' which are the pcap traces for node 0-device 0 and
+In our example script, we will eventually see files named ``myfirst-0-0.pcap''
+and ``myfirst.1-0.pcap'' which are the pcap traces for node 0-device 0 and
node 1-device 0, respectively.
Once you have added the line of code to enable pcap tracing, you can run the
script in the usual way:
@verbatim
- ./waf --run scratch/first
+ ./waf --run scratch/myfirst
@end verbatim
If you look at the top level directory of your distribution, you should now
-see three log files: @code{first.tr} is the ASCII trace file we have
-previously examined. @code{first-0-0.pcap} and @code{first-1-0.pcap}
+see three log files: @code{myfirst.tr} is the ASCII trace file we have
+previously examined. @code{myfirst-0-0.pcap} and @code{myfirst-1-0.pcap}
are the new pcap files we just generated.
@subsubsection Reading output with tcpdump
@cindex tcpdump
The easiest thing to do at this point will be to use @code{tcpdump} to look
-at the @code{pcap} files. Output from dumping both files is shown below:
+at the @code{pcap} files.
@verbatim
- ~/repos/ns-3-dev > /usr/sbin/tcpdump -r first-0-0.pcap -nn -tt
- reading from file first-0-0.pcap, link-type PPP (PPP)
+ tcpdump -nn -tt -r myfirst-0-0.pcap
+ reading from file myfirst-0-0.pcap, link-type PPP (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024
2.514648 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024
- ~/repos/ns-3-dev > /usr/sbin/tcpdump -r first-1-0.pcap -nn -tt
- reading from file first-1-0.pcap, link-type PPP (PPP)
+
+ tcpdump -nn -tt -r myfirst-1-0.pcap
+ reading from file myfirst-1-0.pcap, link-type PPP (PPP)
2.257324 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024
2.257324 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024
- ~/repos/ns-3-dev >
@end verbatim
-You can see in the dump of ``first-0.0.pcap'' (the client device) that the
+You can see in the dump of @code{myfirst-0.0.pcap} (the client device) that the
echo packet is sent at 2 seconds into the simulation. If you look at the
-second dump (of ``first-1-0.pcap'') you can see that packet being received
-at 2.257324 seconds. You see the packet being echoed at 2.257324 seconds
+second dump (@code{first-1-0.pcap}) you can see that packet being received
+at 2.257324 seconds. You see the packet being echoed back at 2.257324 seconds
in the second dump, and finally, you see the packet being received back at
the client in the first dump at 2.514648 seconds.
diff --git a/examples/second.cc b/examples/second.cc
index c6a4d0f79..10ab69418 100644
--- a/examples/second.cc
+++ b/examples/second.cc
@@ -37,8 +37,8 @@ int
main (int argc, char *argv[])
{
bool verbose = true;
-
uint32_t nCsma = 3;
+
CommandLine cmd;
cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
cmd.AddValue ("verbose", "Tell echo applications to log if true", verbose);
@@ -51,6 +51,8 @@ main (int argc, char *argv[])
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
}
+ nCsma = nCsma == 0 ? 1 : nCsma;
+
NodeContainer p2pNodes;
p2pNodes.Create (2);
@@ -102,8 +104,8 @@ main (int argc, char *argv[])
GlobalRouteManager::PopulateRoutingTables ();
- PointToPointHelper::EnablePcap ("second", p2pDevices.Get (1));
- CsmaHelper::EnablePcap ("second", csmaDevices.Get (0), true);
+ PointToPointHelper::EnablePcapAll ("second");
+ CsmaHelper::EnablePcap ("second", csmaDevices.Get (1), true);
Simulator::Run ();
Simulator::Destroy ();
diff --git a/examples/tap-wifi-dumbbell.cc b/examples/tap-wifi-dumbbell.cc
index f2b85d46b..c149b6248 100644
--- a/examples/tap-wifi-dumbbell.cc
+++ b/examples/tap-wifi-dumbbell.cc
@@ -20,7 +20,8 @@
// | external |
// | Linux |
// | Host |
-// | "left" |
+// | |
+// | "mytap" |
// +----------+
// | n0 n3 n4
// | +--------+ +------------+ +------------+
@@ -61,7 +62,7 @@
// item).
//
// ./waf --run tap-wifi-dumbbell&
-// sudo route add -net 10.1.3.0 netmask 255.255.255.0 dev left gw 10.1.1.2
+// sudo route add -net 10.1.3.0 netmask 255.255.255.0 dev thetap gw 10.1.1.2
// ping 10.1.3.4
//
// Take a look at the pcap traces and note that the timing reflects the
@@ -77,9 +78,33 @@
// traffic data rate and watch the ping timing change dramatically.
//
// ./waf --run "tap-wifi-dumbbell --ns3::OnOffApplication::DataRate=100kb/s"&
-// sudo route add -net 10.1.3.0 netmask 255.255.255.0 dev left gw 10.1.1.2
+// sudo route add -net 10.1.3.0 netmask 255.255.255.0 dev thetap gw 10.1.1.2
// ping 10.1.3.4
//
+// 4) Try to run this in UseLocal mode. This allows you to provide an existing
+// pre-configured tap device to the simulation. The IP address and MAC
+// address in this mode do not have to match those of the ns-3 device.
+//
+// sudo tunctl -t mytap
+// sudo ifconfig mytap hw ether 08:00:2e:00:00:01
+// sudo ifconfig mytap 10.1.1.1 netmask 255.255.255.0 up
+// ./waf --run "tap-wifi-dumbbell --mode=UseLocal --tapName=mytap"&
+// ping 10.1.1.3
+//
+// 5) Try to run this in UseBridge mode. This allows you to bridge an ns-3
+// simulation to an existing pre-configured bridge. This uses tap devices
+// just for illustration, you can create your own bridge if you want.
+//
+// sudo tunctl -t mytap1
+// sudo ifconfig mytap1 0.0.0.0 promisc up
+// sudo tunctl -t mytap2
+// sudo ifconfig mytap2 0.0.0.0 promisc up
+// sudo brctl addbr mybridge
+// sudo brctl addif mybridge mytap1
+// sudo brctl addif mybridge mytap2
+// sudo ifconfig mybridge 10.1.1.5 netmask 255.255.255.0 up
+// ./waf --run "tap-wifi-dumbbell --mode=UseBridge --tapName=mytap2"&
+// ping 10.1.1.3
#include
#include
@@ -98,7 +123,12 @@ NS_LOG_COMPONENT_DEFINE ("TapDumbbellExample");
int
main (int argc, char *argv[])
{
+ std::string mode = "ConfigureLocal";
+ std::string tapName = "thetap";
+
CommandLine cmd;
+ cmd.AddValue("mode", "Mode setting of TapBridge", mode);
+ cmd.AddValue("tapName", "Name of the OS tap device", tapName);
cmd.Parse (argc, argv);
GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
@@ -145,9 +175,10 @@ main (int argc, char *argv[])
ipv4Left.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer interfacesLeft = ipv4Left.Assign (devicesLeft);
- TapBridgeHelper bridgeLeft (interfacesLeft.GetAddress (1));
- bridgeLeft.SetAttribute ("DeviceName", StringValue ("left"));
- bridgeLeft.Install (nodesLeft.Get (0), devicesLeft.Get (0));
+ TapBridgeHelper tapBridge (interfacesLeft.GetAddress (1));
+ tapBridge.SetAttribute ("Mode", StringValue (mode));
+ tapBridge.SetAttribute ("DeviceName", StringValue (tapName));
+ tapBridge.Install (nodesLeft.Get (0), devicesLeft.Get (0));
//
// Now, create the right side.
diff --git a/examples/tcp-large-transfer.cc b/examples/tcp-large-transfer.cc
index 78b576834..18b6e9947 100644
--- a/examples/tcp-large-transfer.cc
+++ b/examples/tcp-large-transfer.cc
@@ -57,9 +57,14 @@ static uint32_t txBytes = 2000000;
void StartFlow(Ptr, Ipv4Address, uint16_t);
void WriteUntilBufferFull (Ptr, uint32_t);
+static void
+CwndTracer (uint32_t oldval, uint32_t newval)
+{
+ NS_LOG_INFO ("Moving cwnd from " << oldval << " to " << newval);
+}
+
int main (int argc, char *argv[])
{
-
// Users may find it convenient to turn on explicit debugging
// for selected modules; the below lines suggest how to do this
// LogComponentEnable("TcpL4Protocol", LOG_LEVEL_ALL);
@@ -67,9 +72,6 @@ int main (int argc, char *argv[])
// LogComponentEnable("PacketSink", LOG_LEVEL_ALL);
// LogComponentEnable("TcpLargeTransfer", LOG_LEVEL_ALL);
-
- // Allow the user to override any of the defaults and the above
- // Bind()s at run-time, via command-line arguments
CommandLine cmd;
cmd.Parse (argc, argv);
@@ -140,6 +142,9 @@ int main (int argc, char *argv[])
Socket::CreateSocket (n0n1.Get (0), TcpSocketFactory::GetTypeId ());
localSocket->Bind ();
+ // Trace changes to the congestion window
+ Config::ConnectWithoutContext ("/NodeList/0/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow", MakeCallback (&CwndTracer));
+
// ...and schedule the sending "Application"; This is similar to what an
// ns3::Application subclass would do internally.
Simulator::ScheduleNow (&StartFlow, localSocket,
diff --git a/examples/tcp-nsc-lfn.cc b/examples/tcp-nsc-lfn.cc
index 4976e636e..b79674413 100644
--- a/examples/tcp-nsc-lfn.cc
+++ b/examples/tcp-nsc-lfn.cc
@@ -43,6 +43,11 @@ using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("TcpNscLfn");
+static void
+CwndTracer (uint32_t oldval, uint32_t newval)
+{
+ NS_LOG_INFO ("Moving cwnd from " << oldval << " to " << newval);
+}
int main (int argc, char *argv[])
{
@@ -133,6 +138,10 @@ int main (int argc, char *argv[])
clientApp.Stop (Seconds (runtime + 1.0 + i));
}
+ // Trace changes to the congestion window
+ Config::ConnectWithoutContext ("/NodeList/1/$ns3::NscTcpL4Protocol/SocketList/0/CongestionWindow",
+ MakeCallback (&CwndTracer));
+
// This tells ns-3 to generate pcap traces.
PointToPointHelper::EnablePcapAll ("tcp-nsc-lfn");
diff --git a/examples/third.cc b/examples/third.cc
index 996bbbd74..b6a5551bc 100644
--- a/examples/third.cc
+++ b/examples/third.cc
@@ -40,11 +40,10 @@ NS_LOG_COMPONENT_DEFINE ("ThirdScriptExample");
int
main (int argc, char *argv[])
{
-
bool verbose = true;
-
uint32_t nCsma = 3;
uint32_t nWifi = 3;
+
CommandLine cmd;
cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
cmd.AddValue ("nWifi", "Number of wifi STA devices", nWifi);
@@ -162,7 +161,7 @@ main (int argc, char *argv[])
Simulator::Stop (Seconds (10.0));
- PointToPointHelper::EnablePcap ("third", p2pDevices.Get (0));
+ PointToPointHelper::EnablePcapAll ("third");
YansWifiPhyHelper::EnablePcap ("third", apDevices.Get (0));
CsmaHelper::EnablePcap ("third", csmaDevices.Get (0), true);
diff --git a/examples/wifi-adhoc.cc b/examples/wifi-adhoc.cc
index 50e99073a..6f0e0bc54 100644
--- a/examples/wifi-adhoc.cc
+++ b/examples/wifi-adhoc.cc
@@ -251,6 +251,24 @@ int main (int argc, char *argv[])
dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
gnuplot.AddDataset (dataset);
+ NS_LOG_DEBUG ("aarf-cd");
+ experiment = Experiment ("aarf-cd");
+ wifi.SetRemoteStationManager ("ns3::AarfcdWifiManager");
+ dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+ gnuplot.AddDataset (dataset);
+
+ NS_LOG_DEBUG ("cara");
+ experiment = Experiment ("cara");
+ wifi.SetRemoteStationManager ("ns3::CaraWifiManager");
+ dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+ gnuplot.AddDataset (dataset);
+
+ NS_LOG_DEBUG ("rraa");
+ experiment = Experiment ("rraa");
+ wifi.SetRemoteStationManager ("ns3::RraaWifiManager");
+ dataset = experiment.Run (wifi, wifiPhy, wifiChannel);
+ gnuplot.AddDataset (dataset);
+
NS_LOG_DEBUG ("ideal");
experiment = Experiment ("ideal");
wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
diff --git a/examples/wifi-ap.cc b/examples/wifi-ap.cc
index 6bd6c74d1..e5cc5d84e 100644
--- a/examples/wifi-ap.cc
+++ b/examples/wifi-ap.cc
@@ -32,14 +32,14 @@
using namespace ns3;
void
-DevTxTrace (std::string context, Ptr p, Mac48Address address)
+DevTxTrace (std::string context, Ptr p)
{
- std::cout << " TX to=" << address << " p: " << *p << std::endl;
+ std::cout << " TX p: " << *p << std::endl;
}
void
-DevRxTrace (std::string context, Ptr p, Mac48Address address)
+DevRxTrace (std::string context, Ptr p)
{
- std::cout << " RX from=" << address << " p: " << *p << std::endl;
+ std::cout << " RX p: " << *p << std::endl;
}
void
PhyRxOkTrace (std::string context, Ptr packet, double snr, WifiMode mode, enum WifiPreamble preamble)
@@ -168,8 +168,8 @@ int main (int argc, char *argv[])
Simulator::Stop (Seconds (44.0));
- Config::Connect ("/NodeList/*/DeviceList/*/Tx", MakeCallback (&DevTxTrace));
- Config::Connect ("/NodeList/*/DeviceList/*/Rx", MakeCallback (&DevRxTrace));
+ Config::Connect ("/NodeList/*/DeviceList/*/Mac/MacTx", MakeCallback (&DevTxTrace));
+ Config::Connect ("/NodeList/*/DeviceList/*/Mac/MacRx", MakeCallback (&DevRxTrace));
Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/RxOk", MakeCallback (&PhyRxOkTrace));
Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/RxError", MakeCallback (&PhyRxErrorTrace));
Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/Tx", MakeCallback (&PhyTxTrace));
diff --git a/examples/wifi-wired-bridging.cc b/examples/wifi-wired-bridging.cc
index f75ce7810..0ce26cab5 100644
--- a/examples/wifi-wired-bridging.cc
+++ b/examples/wifi-wired-bridging.cc
@@ -157,8 +157,6 @@ int main (int argc, char *argv[])
wifiX += 20.0;
}
- GlobalRouteManager::PopulateRoutingTables ();
-
Address dest;
std::string protocol;
if (sendIp)
diff --git a/regression.py b/regression.py
index 161f8b79b..653731cc5 100644
--- a/regression.py
+++ b/regression.py
@@ -3,10 +3,9 @@ import os
import sys
import shutil
import pproc as subprocess
-import urllib
+import errno
# WAF modules
-import Build
import Options
import Utils
import Task
@@ -66,9 +65,11 @@ class regression_test_task(Task.TaskBase):
after = 'cc cxx cc_link cxx_link'
color = 'BLUE'
- def __init__(self, env, test_name, test_scripts_dir, build_traces_dir, reference_traces):
- super(regression_test_task, self).__init__()
+ def __init__(self, bld, env, test_name, test_scripts_dir, build_traces_dir, reference_traces):
+ self.bld = bld
+ self.generator = self
self.env = env
+ super(regression_test_task, self).__init__(generator=self, env=env)
self.test_name = test_name
self.test_scripts_dir = test_scripts_dir
self.build_traces_dir = build_traces_dir
@@ -77,6 +78,9 @@ class regression_test_task(Task.TaskBase):
def __str__(self):
return 'regression-test (%s)\n' % self.test_name
+ def runnable_status(self):
+ return Task.RUN_ME
+
def run(self):
"""Run a single test"""
sys.path.insert(0, self.test_scripts_dir)
@@ -118,7 +122,11 @@ class regression_test_task(Task.TaskBase):
if Options.options.regression_generate:
# clean the target dir
- shutil.rmtree(reference_traces_path, ignore_errors=True)
+ try:
+ shutil.rmtree(reference_traces_path)
+ except OSError, ex:
+ if ex.errno not in [errno.ENOENT]:
+ raise
os.makedirs(reference_traces_path)
result = self.run_reference_generate(reference_traces_path, program, arguments, is_pyscript)
if result == 0:
@@ -127,7 +135,11 @@ class regression_test_task(Task.TaskBase):
print "GENERATE FAIL " + self.test_name
else:
# clean the target dir
- shutil.rmtree(trace_output_path, ignore_errors=True)
+ try:
+ shutil.rmtree(trace_output_path)
+ except OSError, ex:
+ if ex.errno not in [errno.ENOENT]:
+ raise
os.makedirs(trace_output_path)
# run it
result = self.run_reference_test(reference_traces_path, trace_output_path, program, arguments, is_pyscript)
@@ -147,13 +159,13 @@ class regression_test_task(Task.TaskBase):
script = os.path.abspath(os.path.join('..', *os.path.split(program)))
argv = [self.env['PYTHON'], script] + arguments
try:
- wutils.run_argv(argv, cwd=trace_output_path)
+ wutils.run_argv(argv, self.env, cwd=trace_output_path)
except Utils.WafError, ex:
print >> sys.stderr, ex
return 1
else:
try:
- wutils.run_program(program,
+ wutils.run_program(program, self.env,
command_template=wutils.get_command_template(self.env, arguments),
cwd=trace_output_path)
except Utils.WafError, ex:
@@ -179,13 +191,13 @@ class regression_test_task(Task.TaskBase):
script = os.path.abspath(os.path.join('..', *os.path.split(program)))
argv = [self.env['PYTHON'], script] + arguments
try:
- retval = wutils.run_argv(argv, cwd=trace_output_path)
+ retval = wutils.run_argv(argv, self.env, cwd=trace_output_path)
except Utils.WafError, ex:
print >> sys.stderr, ex
return 1
else:
try:
- retval = wutils.run_program(program,
+ retval = wutils.run_program(program, self.env,
command_template=wutils.get_command_template(self.env, arguments),
cwd=trace_output_path)
except Utils.WafError, ex:
@@ -198,13 +210,17 @@ class regression_test_collector_task(Task.TaskBase):
after = 'regression_test_task'
color = 'BLUE'
- def __init__(self, test_tasks):
- super(regression_test_collector_task, self).__init__()
+ def __init__(self, bld, test_tasks):
+ self.bld = bld
+ super(regression_test_collector_task, self).__init__(generator=self)
self.test_tasks = test_tasks
def __str__(self):
return 'regression-test-collector\n'
+ def runnable_status(self):
+ return Task.RUN_ME
+
def run(self):
failed_tests = [test for test in self.test_tasks if test.result is not None and test.result != 0]
skipped_tests = [test for test in self.test_tasks if test.result is None]
@@ -248,5 +264,7 @@ def run_regression(bld, reference_traces):
build_traces_dir = bld.path.find_or_declare('regression/traces').abspath(bld.env)
tasks = []
for test in tests:
- tasks.append(regression_test_task(bld.env, test, test_scripts_dir, build_traces_dir, reference_traces))
- regression_test_collector_task(tasks)
+ task = regression_test_task(bld, bld.env, test, test_scripts_dir, build_traces_dir, reference_traces)
+ #bld.task_manager.add_task(task)
+ tasks.append(task)
+ regression_test_collector_task(bld, tasks)
diff --git a/samples/main-random-variable.cc b/samples/main-random-variable.cc
new file mode 100644
index 000000000..de16cd6da
--- /dev/null
+++ b/samples/main-random-variable.cc
@@ -0,0 +1,377 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 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
+ * 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: Timo Bingmann
+ */
+#include "ns3/random-variable.h"
+#include "ns3/gnuplot.h"
+#include