--- a/.hgignore Fri Dec 16 18:50:05 2011 +0100
+++ b/.hgignore Fri Dec 16 18:51:18 2011 +0100
@@ -7,6 +7,7 @@
^testpy-output
^doc/html
^doc/latex
+^doc/ns3-object.txt
^\.lock-wafbuild
^\.waf
^doc/introspected-doxygen\.h$
--- a/README Fri Dec 16 18:50:05 2011 +0100
+++ b/README Fri Dec 16 18:51:18 2011 +0100
@@ -24,14 +24,15 @@
will be contributed by the community in an open collaboration
process.
-Contributing to the ns-3 project is still a very informal
-process because that process depends heavily on the background
-of the people involved, the amount of time they can invest
-and the type of model they want to work on.
+The process of contributing to the ns-3 project varies with
+the people involved, the amount of time they can invest
+and the type of model they want to work on, but the current
+process that the project tries to follow is described here:
+http://www.nsnam.org/developers/contributing-code/
-Despite this lack of a formal process, there are a number of
-steps which naturally stem from the open-source roots of the
-project. These steps are described in doc/contributing.txt
+This README excerpts some details from a more extensive
+tutorial that is maintained at:
+http://www.nsnam.org/documentation/latest/
2) Building ns-3
----------------
@@ -47,9 +48,13 @@
included in the file doc/build.txt
However, the real quick and dirty way to get started is to
-type the command "./waf configure; ./waf" the the directory which contains
+type the command
+ ./waf configure --enable-examples
+followed by
+ ./waf
+in the the directory which contains
this README file. The files built will be copied in the
-build/debug or build/optimized.
+build/ directory.
The current codebase is expected to build and run on the
set of platforms listed in the RELEASE_NOTES file.
@@ -60,15 +65,16 @@
3) Running ns-3
---------------
-On recent Linux systems, once you have built ns-3, it
-should be easy to run the sample programs with the
-following command:
+On recent Linux systems, once you have built ns-3 (with examples
+enabled), it should be easy to run the sample programs with the
+following command, such as:
-./waf --run simple-global-routing
+ ./waf --run simple-global-routing
That program should generate a simple-global-routing.tr text
trace file and a set of simple-global-routing-xx-xx.pcap binary
pcap trace files, which can be read by tcpdump -tt -r filename.pcap
+The program source can be found in the examples/routing directory.
4) Getting access to the ns-3 documentation
-------------------------------------------
@@ -79,18 +85,19 @@
some ns-3 documentation.
All of that documentation should always be available from
-the ns-3 website: http:://www.nsnam.org/ but we
-include some of it in this release for ease of use.
+the ns-3 website: http:://www.nsnam.org/documentation/.
This documentation includes:
- a tutorial
- - a manual
+ - a reference manual
+
+ - models in the ns-3 model library
- a wiki for user-contributed tips: http://www.nsnam.org/wiki/
- - an API documentation generated using doxygen: this is
+ - API documentation generated using doxygen: this is
a reference manual, most likely not very well suited
as introductory text:
http://www.nsnam.org/doxygen/index.html
--- a/RELEASE_NOTES Fri Dec 16 18:50:05 2011 +0100
+++ b/RELEASE_NOTES Fri Dec 16 18:51:18 2011 +0100
@@ -18,12 +18,61 @@
Bugs fixed
----------
+ - bug 962 - list of paths to reach objects contains bogus entries
+ - bug 1001 - Buffer::CopyData() doesn't return the number of bytes copied
+ - bug 1010 - Uan model sleep patch
+ - bug 1020 - Wrong usage of the originator sequence number in HWMP PREP
+ - bug 1021 - Beacon collision avoidance in Mesh module works incorrectly
+ - bug 1039 - Nagle's algorithm in TCP
+ - bug 1055 - Wrong UAN's Thorp absorption loss model formula
+ - bug 1059 - Unable to load trace files created from SUMO and TraNS Lite
+ - bug 1112 - Advance m_nextTxSequence upon retransmit after RTO
+ - bug 1137 - mpi module is hard-coded for openmpi
+ - bug 1166 - IPV4 TCP failed to send a RST when connect arrives before listen
+ - bug 1186 - Ipv4Header lacks DSCP and ECN
+ - bug 1204 - Can't Parse Time +100000000.0ns
+ - bug 1219 - Coding style of ns2-mobility-helper-test-suite.cc is fixed
+ - bug 1257 - waf install __init__ Python files even with --disable-python
+ - bug 1263 - waf configure fails on FreeBSD 9.0-BETA2 amd64
+ - bug 1266 - gdb cannot be loaded
+ - bug 1227 - Spurious RTO due to low min RTO
+ - bug 1229 - Multiplication overflow in WaypointMobilityModel::EndMobility
+ - bug 1242 - m_lastRtt in tcp-socket-base.cc not implemented
+ - bug 1256 - TCP unnecessary snd.nxt advance
+ - bug 1265 - Make ns-3 directory "movable"
+ - bug 1269 - sqlite3 not found on FreeBSD
+ - bug 1270 - "Checking boost includes" weirdness
+ - bug 1278 - Ipv4ClickRouting::HandleScheduleFromClick bug
+ - bug 1281 - Checksum not calculated when doing IP fragmentation
+ - bug 1285 - IPv6 Localhost is marked as GLOBAL instead of HOST
+ - bug 1290 - buffer-test.cc gets a valgrind error
+ - bug 1295 - Missing const qualifiers in TopologyRead
+ - bug 1299 - EnableAsciiIpv4All tracing doesn't show transmitted/recvd packets
+ - bug 1300 - HalfDuplexIdealPhy notify SpectrumInterference of AbortRx
+ - bug 1301 - Ns2MobilityHelper causes Node GetPosition() to return NaN
+ - bug 1305 - do not list modules built upon exiting waf shell
+ - bug 1312: TopologyRead Assert condition fix
+ - IPv4 packets double fragmentation was broken
+ - Fix wifi-clear-channel-cmu.cc example
+ - NetAnim: fix for bcast packet reuse
+ - Missing PropagationLossModel.CalcRxPower in Python bindings
+ - Corrected compilation behavior in Ubuntu 11.10 due to ldd behavior change
+ - Added required PTHREAD dependency to RT library check.
Supported platforms
-------------------
+ns-3.13 has been tested on the following platforms. Not all features are
+available on all platforms; check the Installation page on the project wiki.
+
+- Ubuntu 11.04 (32/64 bit) with g++-4.5.2
+- Ubuntu 10.04.3 LTS (64 bit) with g++-4.4.3, g++-3.4.6
+- OS X Lion with g++-4.2.1
+- OS X Snow Leopard with g++-4.2.1
+- Fedora Core 14 (64 bit) with g++-4.5.1
New user-visible features
-------------------------
+- IPv6 address generator
Known issues
------------
--- a/doc/build.txt Fri Dec 16 18:50:05 2011 +0100
+++ b/doc/build.txt Fri Dec 16 18:51:18 2011 +0100
@@ -23,28 +23,28 @@
To see valid configure options, type ./waf --help. The most important
option is -d <debug level>. Valid debug levels (which are listed in
-waf --help) are: "debug" or "optimized". It is
+waf --help) are: "debug" or "optimized", with debug being default. It is
also possible to change the flags used for compilation with (e.g.):
-CXXFLAGS="-O3" ./waf configure.
+CXXFLAGS="-O3" ./waf configure. By default, ns-3 is built as debug code,
+with examples and tests disabled, and with python bindings enabled.
[ Note: Unlike some other build tools, to change the build target,
the option must be supplied during the configure stage rather than
the build stage (i.e., "./waf -d optimized" will not work; instead, do
"./waf -d optimized configure; ./waf" ]
-The resulting binaries are placed in build/<debuglevel>/srcpath.
+The resulting executables and libraries are placed in build/.
Other waf usages include:
1. ./waf configure --enable-examples --enable-tests
Turn on examples and tests.
- 2. ./waf --doxygen
- Run doxygen to generate documentation
+ 2. ./waf configure --disable-python
+ Disable python bindings.
- 3. ./waf --lcov-report
- Run code coverage analysis (assuming the project was configured
-with --enable-gcov)
+ 3. ./waf --doxygen
+ Run doxygen to generate documentation
4. ./waf --run "program [args]"
Run a ns3 program, given its target name, with the given
@@ -79,29 +79,29 @@
1. Create the module directory under src;
2. Add the source files to it;
3. Add a 'wscript' describing it;
- 4. Add the module subdirectory name to the all_modules list in src/wscript.
+
+A convenience program to auto-generate the template of a new module can
+be found in src/create-module.py.
A module's wscript file is basically a regular Waf script. A ns-3
module is created as a cpp/shlib object, like this:
def build(bld):
- obj = bld.create_obj('cpp', 'shlib')
-
- ## set module name; by convention it starts with ns3-
- obj.name = 'ns3-mymodule'
- obj.target = obj.name
-
- ## list dependencies to other modules
- obj.uselib_local = ['ns3-core']
+ module = bld.create_ns3_module('ns3-mymodule', ['core'])
+ module.source = [
+ 'model/ns3-mymodule.cc',
+ 'helper/ns3-mymodule-helper.cc',
+ ]
- ## list source files (private or public header files excluded)
- obj.source = [
- 'mymodule.cc',
- ]
+ headers = bld.new_task_gen(features=['ns3header'])
+ headers.module = 'ns3-mymodule'
+ headers.source = [
+ 'model/ns3-mymodule.h',
+ 'helper/ns3-mymodule-helper.h',
+ ]
- ## list module public header files
- headers = bld.create_obj('ns3header')
- headers.source = [
- 'mymodule-header.h',
- ]
+ if bld.env.ENABLE_EXAMPLES:
+ bld.add_subdirs('examples')
+ # bld.ns3_python_bindings()
+
--- a/doc/doxygen.conf Fri Dec 16 18:50:05 2011 +0100
+++ b/doc/doxygen.conf Fri Dec 16 18:51:18 2011 +0100
@@ -25,7 +25,7 @@
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
-PROJECT_NAME = "NS-3 "
+PROJECT_NAME = "ns-3 "
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
@@ -590,8 +590,7 @@
# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
FILE_PATTERNS = *.h \
- *.tcc \
- node-list.cc
+ *.cc
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
@@ -603,11 +602,7 @@
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
-EXCLUDE = src/olsr/model/olsr-state.h \
- src/olsr/model/olsr-repositories.h \
- src/core/model/high-precision.h \
- src/core/model/high-precision-128.h \
- src/core/model/high-precision-double.h
+EXCLUDE =
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
# directories that are symbolic links (a Unix filesystem feature) are excluded
@@ -635,7 +630,39 @@
# directories that contain example code fragments that are included (see
# the \include command).
-EXAMPLE_PATH =
+EXAMPLE_PATH = src/aodv/examples \
+ src/bridge/examples \
+ src/click/examples \
+ src/config-store/examples \
+ src/core/examples \
+ src/csma/examples \
+ src/csma-layout/examples \
+ src/dsdv/examples \
+ src/emu/examples \
+ src/energy/examples \
+ src/flow-monitor/examples \
+ src/internet/examples \
+ src/lte/examples \
+ src/mesh/examples \
+ src/mobility/examples \
+ src/mpi/examples \
+ src/netanim/examples \
+ src/network/examples \
+ src/nix-vector-routing/examples \
+ src/olsr/examples \
+ src/openflow/examples \
+ src/point-to-point/examples \
+ src/propagation/examples \
+ src/spectrum/examples \
+ src/tap-bridge/examples \
+ src/template/examples \
+ src/tools/examples \
+ src/topology-read/examples \
+ src/uan/examples \
+ src/virtual-net-device/examples \
+ src/visualizer/examples \
+ src/wifi/examples \
+ src/wimax/examples
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
--- a/examples/wireless/wifi-clear-channel-cmu.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/examples/wireless/wifi-clear-channel-cmu.cc Fri Dec 16 18:51:18 2011 +0100
@@ -150,6 +150,7 @@
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
Ptr<Socket> source = Socket::CreateSocket (c.Get (1), tid);
InetSocketAddress remote = InetSocketAddress (Ipv4Address ("255.255.255.255"), 80);
+ source->SetAllowBroadcast (true);
source->Connect (remote);
uint32_t packetSize = 1014;
uint32_t maxPacketCount = 200;
@@ -212,6 +213,7 @@
wifiPhy.Set ("EnergyDetectionThreshold", DoubleValue (-110.0) );
wifiPhy.Set ("CcaMode1Threshold", DoubleValue (-110.0) );
wifiPhy.Set ("TxPowerStart", DoubleValue (15.0) );
+ wifiPhy.Set ("TxPowerEnd", DoubleValue (15.0) );
wifiPhy.Set ("RxGain", DoubleValue (0) );
wifiPhy.Set ("RxNoiseFigure", DoubleValue (7) );
uint32_t pktsRecvd = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
Binary file src/aodv/test/tcp-chain-test-0-0.pcap has changed
Binary file src/aodv/test/tcp-chain-test-9-0.pcap has changed
--- a/src/applications/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/applications/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:51:18 2011 +0100
@@ -242,6 +242,14 @@
module.add_enum('', ['FRAME_FLAG_NONE', 'FRAME_FLAG_CFP', 'FRAME_FLAG_SHORT_PREAMBLE', 'FRAME_FLAG_WEP', 'FRAME_FLAG_FRAGMENTED', 'FRAME_FLAG_FCS_INCLUDED', 'FRAME_FLAG_DATA_PADDING', 'FRAME_FLAG_BAD_FCS', 'FRAME_FLAG_SHORT_GUARD'], outer_class=root_module['ns3::RadiotapHeader'], import_from_module='ns.network')
## radiotap-header.h (module 'network'): ns3::RadiotapHeader [enumeration]
module.add_enum('', ['CHANNEL_FLAG_NONE', 'CHANNEL_FLAG_TURBO', 'CHANNEL_FLAG_CCK', 'CHANNEL_FLAG_OFDM', 'CHANNEL_FLAG_SPECTRUM_2GHZ', 'CHANNEL_FLAG_SPECTRUM_5GHZ', 'CHANNEL_FLAG_PASSIVE', 'CHANNEL_FLAG_DYNAMIC', 'CHANNEL_FLAG_GFSK'], outer_class=root_module['ns3::RadiotapHeader'], import_from_module='ns.network')
+ ## red-queue.h (module 'network'): ns3::RedQueue [class]
+ module.add_class('RedQueue', import_from_module='ns.network', parent=root_module['ns3::Queue'])
+ ## red-queue.h (module 'network'): ns3::RedQueue [enumeration]
+ module.add_enum('', ['DTYPE_NONE', 'DTYPE_FORCED', 'DTYPE_UNFORCED'], outer_class=root_module['ns3::RedQueue'], import_from_module='ns.network')
+ ## red-queue.h (module 'network'): ns3::RedQueue::Mode [enumeration]
+ module.add_enum('Mode', ['ILLEGAL', 'PACKETS', 'BYTES'], outer_class=root_module['ns3::RedQueue'], import_from_module='ns.network')
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats [struct]
+ module.add_class('Stats', import_from_module='ns.network', outer_class=root_module['ns3::RedQueue'])
## seq-ts-header.h (module 'applications'): ns3::SeqTsHeader [class]
module.add_class('SeqTsHeader', parent=root_module['ns3::Header'])
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> > [class]
@@ -306,6 +314,10 @@
module.add_class('AttributeChecker', allow_subclassing=False, automatic_type_narrowing=True, import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
## attribute.h (module 'core'): ns3::AttributeValue [class]
module.add_class('AttributeValue', allow_subclassing=False, automatic_type_narrowing=True, import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::AttributeValue, ns3::empty, ns3::DefaultDeleter<ns3::AttributeValue> >'])
+ ## boolean.h (module 'core'): ns3::BooleanChecker [class]
+ module.add_class('BooleanChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
+ ## boolean.h (module 'core'): ns3::BooleanValue [class]
+ module.add_class('BooleanValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
## bulk-send-application.h (module 'applications'): ns3::BulkSendApplication [class]
module.add_class('BulkSendApplication', parent=root_module['ns3::Application'])
## callback.h (module 'core'): ns3::CallbackChecker [class]
@@ -585,6 +597,8 @@
register_Ns3PcapFileWrapper_methods(root_module, root_module['ns3::PcapFileWrapper'])
register_Ns3Queue_methods(root_module, root_module['ns3::Queue'])
register_Ns3RadiotapHeader_methods(root_module, root_module['ns3::RadiotapHeader'])
+ register_Ns3RedQueue_methods(root_module, root_module['ns3::RedQueue'])
+ register_Ns3RedQueueStats_methods(root_module, root_module['ns3::RedQueue::Stats'])
register_Ns3SeqTsHeader_methods(root_module, root_module['ns3::SeqTsHeader'])
register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >'])
register_Ns3SimpleRefCount__Ns3AttributeChecker_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeChecker__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
@@ -613,6 +627,8 @@
register_Ns3AttributeAccessor_methods(root_module, root_module['ns3::AttributeAccessor'])
register_Ns3AttributeChecker_methods(root_module, root_module['ns3::AttributeChecker'])
register_Ns3AttributeValue_methods(root_module, root_module['ns3::AttributeValue'])
+ register_Ns3BooleanChecker_methods(root_module, root_module['ns3::BooleanChecker'])
+ register_Ns3BooleanValue_methods(root_module, root_module['ns3::BooleanValue'])
register_Ns3BulkSendApplication_methods(root_module, root_module['ns3::BulkSendApplication'])
register_Ns3CallbackChecker_methods(root_module, root_module['ns3::CallbackChecker'])
register_Ns3CallbackImplBase_methods(root_module, root_module['ns3::CallbackImplBase'])
@@ -4504,6 +4520,70 @@
[param('uint64_t', 'tsft')])
return
+def register_Ns3RedQueue_methods(root_module, cls):
+ ## red-queue.h (module 'network'): ns3::RedQueue::RedQueue(ns3::RedQueue const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::RedQueue const &', 'arg0')])
+ ## red-queue.h (module 'network'): ns3::RedQueue::RedQueue() [constructor]
+ cls.add_constructor([])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Mode ns3::RedQueue::GetMode() [member function]
+ cls.add_method('GetMode',
+ 'ns3::RedQueue::Mode',
+ [])
+ ## red-queue.h (module 'network'): uint32_t ns3::RedQueue::GetQueueSize() [member function]
+ cls.add_method('GetQueueSize',
+ 'uint32_t',
+ [])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats ns3::RedQueue::GetStats() [member function]
+ cls.add_method('GetStats',
+ 'ns3::RedQueue::Stats',
+ [])
+ ## red-queue.h (module 'network'): static ns3::TypeId ns3::RedQueue::GetTypeId() [member function]
+ cls.add_method('GetTypeId',
+ 'ns3::TypeId',
+ [],
+ is_static=True)
+ ## red-queue.h (module 'network'): void ns3::RedQueue::SetMode(ns3::RedQueue::Mode mode) [member function]
+ cls.add_method('SetMode',
+ 'void',
+ [param('ns3::RedQueue::Mode', 'mode')])
+ ## red-queue.h (module 'network'): void ns3::RedQueue::SetQueueLimit(uint32_t lim) [member function]
+ cls.add_method('SetQueueLimit',
+ 'void',
+ [param('uint32_t', 'lim')])
+ ## red-queue.h (module 'network'): void ns3::RedQueue::SetTh(double minTh, double maxTh) [member function]
+ cls.add_method('SetTh',
+ 'void',
+ [param('double', 'minTh'), param('double', 'maxTh')])
+ ## red-queue.h (module 'network'): ns3::Ptr<ns3::Packet> ns3::RedQueue::DoDequeue() [member function]
+ cls.add_method('DoDequeue',
+ 'ns3::Ptr< ns3::Packet >',
+ [],
+ visibility='private', is_virtual=True)
+ ## red-queue.h (module 'network'): bool ns3::RedQueue::DoEnqueue(ns3::Ptr<ns3::Packet> p) [member function]
+ cls.add_method('DoEnqueue',
+ 'bool',
+ [param('ns3::Ptr< ns3::Packet >', 'p')],
+ visibility='private', is_virtual=True)
+ ## red-queue.h (module 'network'): ns3::Ptr<const ns3::Packet> ns3::RedQueue::DoPeek() const [member function]
+ cls.add_method('DoPeek',
+ 'ns3::Ptr< ns3::Packet const >',
+ [],
+ is_const=True, visibility='private', is_virtual=True)
+ return
+
+def register_Ns3RedQueueStats_methods(root_module, cls):
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::Stats() [constructor]
+ cls.add_constructor([])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::Stats(ns3::RedQueue::Stats const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::RedQueue::Stats const &', 'arg0')])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::forcedDrop [variable]
+ cls.add_instance_attribute('forcedDrop', 'uint32_t', is_const=False)
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::qLimDrop [variable]
+ cls.add_instance_attribute('qLimDrop', 'uint32_t', is_const=False)
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::unforcedDrop [variable]
+ cls.add_instance_attribute('unforcedDrop', 'uint32_t', is_const=False)
+ return
+
def register_Ns3SeqTsHeader_methods(root_module, cls):
## seq-ts-header.h (module 'applications'): ns3::SeqTsHeader::SeqTsHeader(ns3::SeqTsHeader const & arg0) [copy constructor]
cls.add_constructor([param('ns3::SeqTsHeader const &', 'arg0')])
@@ -5472,6 +5552,47 @@
is_pure_virtual=True, is_const=True, is_virtual=True)
return
+def register_Ns3BooleanChecker_methods(root_module, cls):
+ ## boolean.h (module 'core'): ns3::BooleanChecker::BooleanChecker() [constructor]
+ cls.add_constructor([])
+ ## boolean.h (module 'core'): ns3::BooleanChecker::BooleanChecker(ns3::BooleanChecker const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::BooleanChecker const &', 'arg0')])
+ return
+
+def register_Ns3BooleanValue_methods(root_module, cls):
+ cls.add_output_stream_operator()
+ ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue(ns3::BooleanValue const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::BooleanValue const &', 'arg0')])
+ ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue() [constructor]
+ cls.add_constructor([])
+ ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue(bool value) [constructor]
+ cls.add_constructor([param('bool', 'value')])
+ ## boolean.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::BooleanValue::Copy() const [member function]
+ cls.add_method('Copy',
+ 'ns3::Ptr< ns3::AttributeValue >',
+ [],
+ is_const=True, is_virtual=True)
+ ## boolean.h (module 'core'): bool ns3::BooleanValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+ cls.add_method('DeserializeFromString',
+ 'bool',
+ [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
+ is_virtual=True)
+ ## boolean.h (module 'core'): bool ns3::BooleanValue::Get() const [member function]
+ cls.add_method('Get',
+ 'bool',
+ [],
+ is_const=True)
+ ## boolean.h (module 'core'): std::string ns3::BooleanValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+ cls.add_method('SerializeToString',
+ 'std::string',
+ [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
+ is_const=True, is_virtual=True)
+ ## boolean.h (module 'core'): void ns3::BooleanValue::Set(bool value) [member function]
+ cls.add_method('Set',
+ 'void',
+ [param('bool', 'value')])
+ return
+
def register_Ns3BulkSendApplication_methods(root_module, cls):
## bulk-send-application.h (module 'applications'): ns3::BulkSendApplication::BulkSendApplication(ns3::BulkSendApplication const & arg0) [copy constructor]
cls.add_constructor([param('ns3::BulkSendApplication const &', 'arg0')])
--- a/src/applications/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/applications/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:51:18 2011 +0100
@@ -242,6 +242,14 @@
module.add_enum('', ['FRAME_FLAG_NONE', 'FRAME_FLAG_CFP', 'FRAME_FLAG_SHORT_PREAMBLE', 'FRAME_FLAG_WEP', 'FRAME_FLAG_FRAGMENTED', 'FRAME_FLAG_FCS_INCLUDED', 'FRAME_FLAG_DATA_PADDING', 'FRAME_FLAG_BAD_FCS', 'FRAME_FLAG_SHORT_GUARD'], outer_class=root_module['ns3::RadiotapHeader'], import_from_module='ns.network')
## radiotap-header.h (module 'network'): ns3::RadiotapHeader [enumeration]
module.add_enum('', ['CHANNEL_FLAG_NONE', 'CHANNEL_FLAG_TURBO', 'CHANNEL_FLAG_CCK', 'CHANNEL_FLAG_OFDM', 'CHANNEL_FLAG_SPECTRUM_2GHZ', 'CHANNEL_FLAG_SPECTRUM_5GHZ', 'CHANNEL_FLAG_PASSIVE', 'CHANNEL_FLAG_DYNAMIC', 'CHANNEL_FLAG_GFSK'], outer_class=root_module['ns3::RadiotapHeader'], import_from_module='ns.network')
+ ## red-queue.h (module 'network'): ns3::RedQueue [class]
+ module.add_class('RedQueue', import_from_module='ns.network', parent=root_module['ns3::Queue'])
+ ## red-queue.h (module 'network'): ns3::RedQueue [enumeration]
+ module.add_enum('', ['DTYPE_NONE', 'DTYPE_FORCED', 'DTYPE_UNFORCED'], outer_class=root_module['ns3::RedQueue'], import_from_module='ns.network')
+ ## red-queue.h (module 'network'): ns3::RedQueue::Mode [enumeration]
+ module.add_enum('Mode', ['ILLEGAL', 'PACKETS', 'BYTES'], outer_class=root_module['ns3::RedQueue'], import_from_module='ns.network')
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats [struct]
+ module.add_class('Stats', import_from_module='ns.network', outer_class=root_module['ns3::RedQueue'])
## seq-ts-header.h (module 'applications'): ns3::SeqTsHeader [class]
module.add_class('SeqTsHeader', parent=root_module['ns3::Header'])
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> > [class]
@@ -306,6 +314,10 @@
module.add_class('AttributeChecker', allow_subclassing=False, automatic_type_narrowing=True, import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
## attribute.h (module 'core'): ns3::AttributeValue [class]
module.add_class('AttributeValue', allow_subclassing=False, automatic_type_narrowing=True, import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::AttributeValue, ns3::empty, ns3::DefaultDeleter<ns3::AttributeValue> >'])
+ ## boolean.h (module 'core'): ns3::BooleanChecker [class]
+ module.add_class('BooleanChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
+ ## boolean.h (module 'core'): ns3::BooleanValue [class]
+ module.add_class('BooleanValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
## bulk-send-application.h (module 'applications'): ns3::BulkSendApplication [class]
module.add_class('BulkSendApplication', parent=root_module['ns3::Application'])
## callback.h (module 'core'): ns3::CallbackChecker [class]
@@ -585,6 +597,8 @@
register_Ns3PcapFileWrapper_methods(root_module, root_module['ns3::PcapFileWrapper'])
register_Ns3Queue_methods(root_module, root_module['ns3::Queue'])
register_Ns3RadiotapHeader_methods(root_module, root_module['ns3::RadiotapHeader'])
+ register_Ns3RedQueue_methods(root_module, root_module['ns3::RedQueue'])
+ register_Ns3RedQueueStats_methods(root_module, root_module['ns3::RedQueue::Stats'])
register_Ns3SeqTsHeader_methods(root_module, root_module['ns3::SeqTsHeader'])
register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >'])
register_Ns3SimpleRefCount__Ns3AttributeChecker_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeChecker__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
@@ -613,6 +627,8 @@
register_Ns3AttributeAccessor_methods(root_module, root_module['ns3::AttributeAccessor'])
register_Ns3AttributeChecker_methods(root_module, root_module['ns3::AttributeChecker'])
register_Ns3AttributeValue_methods(root_module, root_module['ns3::AttributeValue'])
+ register_Ns3BooleanChecker_methods(root_module, root_module['ns3::BooleanChecker'])
+ register_Ns3BooleanValue_methods(root_module, root_module['ns3::BooleanValue'])
register_Ns3BulkSendApplication_methods(root_module, root_module['ns3::BulkSendApplication'])
register_Ns3CallbackChecker_methods(root_module, root_module['ns3::CallbackChecker'])
register_Ns3CallbackImplBase_methods(root_module, root_module['ns3::CallbackImplBase'])
@@ -4504,6 +4520,70 @@
[param('uint64_t', 'tsft')])
return
+def register_Ns3RedQueue_methods(root_module, cls):
+ ## red-queue.h (module 'network'): ns3::RedQueue::RedQueue(ns3::RedQueue const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::RedQueue const &', 'arg0')])
+ ## red-queue.h (module 'network'): ns3::RedQueue::RedQueue() [constructor]
+ cls.add_constructor([])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Mode ns3::RedQueue::GetMode() [member function]
+ cls.add_method('GetMode',
+ 'ns3::RedQueue::Mode',
+ [])
+ ## red-queue.h (module 'network'): uint32_t ns3::RedQueue::GetQueueSize() [member function]
+ cls.add_method('GetQueueSize',
+ 'uint32_t',
+ [])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats ns3::RedQueue::GetStats() [member function]
+ cls.add_method('GetStats',
+ 'ns3::RedQueue::Stats',
+ [])
+ ## red-queue.h (module 'network'): static ns3::TypeId ns3::RedQueue::GetTypeId() [member function]
+ cls.add_method('GetTypeId',
+ 'ns3::TypeId',
+ [],
+ is_static=True)
+ ## red-queue.h (module 'network'): void ns3::RedQueue::SetMode(ns3::RedQueue::Mode mode) [member function]
+ cls.add_method('SetMode',
+ 'void',
+ [param('ns3::RedQueue::Mode', 'mode')])
+ ## red-queue.h (module 'network'): void ns3::RedQueue::SetQueueLimit(uint32_t lim) [member function]
+ cls.add_method('SetQueueLimit',
+ 'void',
+ [param('uint32_t', 'lim')])
+ ## red-queue.h (module 'network'): void ns3::RedQueue::SetTh(double minTh, double maxTh) [member function]
+ cls.add_method('SetTh',
+ 'void',
+ [param('double', 'minTh'), param('double', 'maxTh')])
+ ## red-queue.h (module 'network'): ns3::Ptr<ns3::Packet> ns3::RedQueue::DoDequeue() [member function]
+ cls.add_method('DoDequeue',
+ 'ns3::Ptr< ns3::Packet >',
+ [],
+ visibility='private', is_virtual=True)
+ ## red-queue.h (module 'network'): bool ns3::RedQueue::DoEnqueue(ns3::Ptr<ns3::Packet> p) [member function]
+ cls.add_method('DoEnqueue',
+ 'bool',
+ [param('ns3::Ptr< ns3::Packet >', 'p')],
+ visibility='private', is_virtual=True)
+ ## red-queue.h (module 'network'): ns3::Ptr<const ns3::Packet> ns3::RedQueue::DoPeek() const [member function]
+ cls.add_method('DoPeek',
+ 'ns3::Ptr< ns3::Packet const >',
+ [],
+ is_const=True, visibility='private', is_virtual=True)
+ return
+
+def register_Ns3RedQueueStats_methods(root_module, cls):
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::Stats() [constructor]
+ cls.add_constructor([])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::Stats(ns3::RedQueue::Stats const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::RedQueue::Stats const &', 'arg0')])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::forcedDrop [variable]
+ cls.add_instance_attribute('forcedDrop', 'uint32_t', is_const=False)
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::qLimDrop [variable]
+ cls.add_instance_attribute('qLimDrop', 'uint32_t', is_const=False)
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::unforcedDrop [variable]
+ cls.add_instance_attribute('unforcedDrop', 'uint32_t', is_const=False)
+ return
+
def register_Ns3SeqTsHeader_methods(root_module, cls):
## seq-ts-header.h (module 'applications'): ns3::SeqTsHeader::SeqTsHeader(ns3::SeqTsHeader const & arg0) [copy constructor]
cls.add_constructor([param('ns3::SeqTsHeader const &', 'arg0')])
@@ -5472,6 +5552,47 @@
is_pure_virtual=True, is_const=True, is_virtual=True)
return
+def register_Ns3BooleanChecker_methods(root_module, cls):
+ ## boolean.h (module 'core'): ns3::BooleanChecker::BooleanChecker() [constructor]
+ cls.add_constructor([])
+ ## boolean.h (module 'core'): ns3::BooleanChecker::BooleanChecker(ns3::BooleanChecker const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::BooleanChecker const &', 'arg0')])
+ return
+
+def register_Ns3BooleanValue_methods(root_module, cls):
+ cls.add_output_stream_operator()
+ ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue(ns3::BooleanValue const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::BooleanValue const &', 'arg0')])
+ ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue() [constructor]
+ cls.add_constructor([])
+ ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue(bool value) [constructor]
+ cls.add_constructor([param('bool', 'value')])
+ ## boolean.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::BooleanValue::Copy() const [member function]
+ cls.add_method('Copy',
+ 'ns3::Ptr< ns3::AttributeValue >',
+ [],
+ is_const=True, is_virtual=True)
+ ## boolean.h (module 'core'): bool ns3::BooleanValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+ cls.add_method('DeserializeFromString',
+ 'bool',
+ [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
+ is_virtual=True)
+ ## boolean.h (module 'core'): bool ns3::BooleanValue::Get() const [member function]
+ cls.add_method('Get',
+ 'bool',
+ [],
+ is_const=True)
+ ## boolean.h (module 'core'): std::string ns3::BooleanValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+ cls.add_method('SerializeToString',
+ 'std::string',
+ [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
+ is_const=True, is_virtual=True)
+ ## boolean.h (module 'core'): void ns3::BooleanValue::Set(bool value) [member function]
+ cls.add_method('Set',
+ 'void',
+ [param('bool', 'value')])
+ return
+
def register_Ns3BulkSendApplication_methods(root_module, cls):
## bulk-send-application.h (module 'applications'): ns3::BulkSendApplication::BulkSendApplication(ns3::BulkSendApplication const & arg0) [copy constructor]
cls.add_constructor([param('ns3::BulkSendApplication const &', 'arg0')])
--- a/src/click/wscript Fri Dec 16 18:50:05 2011 +0100
+++ b/src/click/wscript Fri Dec 16 18:51:18 2011 +0100
@@ -104,8 +104,8 @@
]
if bld.env['NSCLICK'] and bld.env['DL']:
- module.use = 'NSCLICK DL'
- module_test.use = 'NSCLICK DL'
+ module.use.extend(['NSCLICK', 'DL'])
+ module_test.use.extend(['NSCLICK', 'DL'])
headers = bld.new_task_gen(features=['ns3header'])
headers.module = 'click'
--- a/src/core/model/command-line.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/core/model/command-line.h Fri Dec 16 18:51:18 2011 +0100
@@ -37,9 +37,15 @@
* CommandLine::AddValue but the most important functionality
* provided by this class is that it can be used to set the
* 'initial value' of every attribute in the system with the
- * '\--TypeIdName::AttributeName=value' syntax and it can be used
- * to set the value of every GlobalValue in the system with
- * the \--GlobalValueName=value syntax.
+ * \verbatim
+ * --TypeIdName::AttributeName=value
+ * \endverbatim
+ * syntax and it can be used to set the value of every GlobalValue
+ * in the system with the
+ * \verbatim
+ * --GlobalValueName=value
+ * \endverbatim
+ * syntax.
*/
class CommandLine
{
--- a/src/core/model/names.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/core/model/names.cc Fri Dec 16 18:51:18 2011 +0100
@@ -463,8 +463,8 @@
NameNode *node = &m_root;
//
- // The string <remaining> is now composed entirely of path segments in the
- // /Names name space and we have eaten the leading slash. e.g.,
+ // The string <remaining> is now composed entirely of path segments in
+ // the /Names name space and we have eaten the leading slash. e.g.,
// remaining = "ClientNode/eth0"
//
// The start of the search is always at the root of the name space.
--- a/src/core/model/nstime.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/core/model/nstime.h Fri Dec 16 18:51:18 2011 +0100
@@ -359,6 +359,7 @@
}
/**
* \param timeUnit the unit of the value to return
+ * \return int64_t time value
*
* Convert the input time into an integer value according to the requested
* time unit.
@@ -390,6 +391,7 @@
}
/**
* \param timeUnit the unit of the value to return
+ * \return double time value
*
* Convert the input time into a floating point value according to the requested
* time unit.
--- a/src/core/model/test.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/core/model/test.h Fri Dec 16 18:51:18 2011 +0100
@@ -937,7 +937,7 @@
{
public:
/**
- * \enum TestType
+ * \enum Type
* \brief Type of test.
*/
enum Type {
--- a/src/dsdv/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/dsdv/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:51:18 2011 +0100
@@ -5303,10 +5303,10 @@
cls.add_constructor([param('ns3::dsdv::RoutingTable const &', 'arg0')])
## dsdv-rtable.h (module 'dsdv'): ns3::dsdv::RoutingTable::RoutingTable() [constructor]
cls.add_constructor([])
- ## dsdv-rtable.h (module 'dsdv'): bool ns3::dsdv::RoutingTable::AddIpv4Event(ns3::Ipv4Address arg0, ns3::EventId arg1) [member function]
+ ## dsdv-rtable.h (module 'dsdv'): bool ns3::dsdv::RoutingTable::AddIpv4Event(ns3::Ipv4Address address, ns3::EventId id) [member function]
cls.add_method('AddIpv4Event',
'bool',
- [param('ns3::Ipv4Address', 'arg0'), param('ns3::EventId', 'arg1')])
+ [param('ns3::Ipv4Address', 'address'), param('ns3::EventId', 'id')])
## dsdv-rtable.h (module 'dsdv'): bool ns3::dsdv::RoutingTable::AddRoute(ns3::dsdv::RoutingTableEntry & r) [member function]
cls.add_method('AddRoute',
'bool',
--- a/src/dsdv/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/dsdv/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:51:18 2011 +0100
@@ -5303,10 +5303,10 @@
cls.add_constructor([param('ns3::dsdv::RoutingTable const &', 'arg0')])
## dsdv-rtable.h (module 'dsdv'): ns3::dsdv::RoutingTable::RoutingTable() [constructor]
cls.add_constructor([])
- ## dsdv-rtable.h (module 'dsdv'): bool ns3::dsdv::RoutingTable::AddIpv4Event(ns3::Ipv4Address arg0, ns3::EventId arg1) [member function]
+ ## dsdv-rtable.h (module 'dsdv'): bool ns3::dsdv::RoutingTable::AddIpv4Event(ns3::Ipv4Address address, ns3::EventId id) [member function]
cls.add_method('AddIpv4Event',
'bool',
- [param('ns3::Ipv4Address', 'arg0'), param('ns3::EventId', 'arg1')])
+ [param('ns3::Ipv4Address', 'address'), param('ns3::EventId', 'id')])
## dsdv-rtable.h (module 'dsdv'): bool ns3::dsdv::RoutingTable::AddRoute(ns3::dsdv::RoutingTableEntry & r) [member function]
cls.add_method('AddRoute',
'bool',
--- a/src/dsdv/model/dsdv-packet-queue.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/dsdv/model/dsdv-packet-queue.h Fri Dec 16 18:51:18 2011 +0100
@@ -47,7 +47,7 @@
public:
typedef Ipv4RoutingProtocol::UnicastForwardCallback UnicastForwardCallback;
typedef Ipv4RoutingProtocol::ErrorCallback ErrorCallback;
- // / c-tor
+ /// c-tor
QueueEntry (Ptr<const Packet> pa = 0, Ipv4Header const & h = Ipv4Header (),
UnicastForwardCallback ucb = UnicastForwardCallback (),
ErrorCallback ecb = ErrorCallback ())
@@ -67,7 +67,7 @@
{
return ((m_packet == o.m_packet) && (m_header.GetDestination () == o.m_header.GetDestination ()) && (m_expire == o.m_expire));
}
- // /\name Fields
+ ///\name Fields
// \{
UnicastForwardCallback GetUnicastForwardCallback () const
{
@@ -111,15 +111,15 @@
}
// \}
private:
- // / Data packet
+ /// Data packet
Ptr<const Packet> m_packet;
- // / IP header
+ /// IP header
Ipv4Header m_header;
- // / Unicast forward callback
+ /// Unicast forward callback
UnicastForwardCallback m_ucb;
- // / Error callback
+ /// Error callback
ErrorCallback m_ecb;
- // / Expire time for queue entry
+ /// Expire time for queue entry
Time m_expire;
};
/**
@@ -133,24 +133,24 @@
class PacketQueue
{
public:
- // / Default c-tor
+ /// Default c-tor
PacketQueue ()
{
}
- // / Push entry in queue, if there is no entry with the same packet and destination address in queue.
+ /// Push entry in queue, if there is no entry with the same packet and destination address in queue.
bool Enqueue (QueueEntry & entry);
- // / Return first found (the earliest) entry for given destination
+ /// Return first found (the earliest) entry for given destination
bool Dequeue (Ipv4Address dst, QueueEntry & entry);
- // / Remove all packets with destination IP address dst
+ /// Remove all packets with destination IP address dst
void DropPacketWithDst (Ipv4Address dst);
- // / Finds whether a packet with destination dst exists in the queue
+ /// Finds whether a packet with destination dst exists in the queue
bool Find (Ipv4Address dst);
- // / Get count of packets with destination dst in the queue
+ /// Get count of packets with destination dst in the queue
uint32_t
GetCountForPacketsWithDst (Ipv4Address dst);
- // / Number of entries
+ /// Number of entries
uint32_t GetSize ();
- // /\name Fields
+ ///\name Fields
// \{
uint32_t GetMaxQueueLen () const
{
@@ -180,15 +180,15 @@
private:
std::vector<QueueEntry> m_queue;
- // / Remove all expired entries
+ /// Remove all expired entries
void Purge ();
- // / Notify that packet is dropped from queue by timeout
+ /// Notify that packet is dropped from queue by timeout
void Drop (QueueEntry en, std::string reason);
- // / The maximum number of packets that we allow a routing protocol to buffer.
+ /// The maximum number of packets that we allow a routing protocol to buffer.
uint32_t m_maxLen;
- // / The maximum number of packets that we allow per destination to buffer.
+ /// The maximum number of packets that we allow per destination to buffer.
uint32_t m_maxLenPerDst;
- // / The maximum period of time that a routing protocol is allowed to buffer a packet for, seconds.
+ /// The maximum period of time that a routing protocol is allowed to buffer a packet for, seconds.
Time m_queueTimeout;
static bool IsEqual (QueueEntry en, const Ipv4Address dst)
{
--- a/src/dsdv/model/dsdv-packet.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/dsdv/model/dsdv-packet.h Fri Dec 16 18:51:18 2011 +0100
@@ -98,9 +98,9 @@
return m_dstSeqNo;
}
private:
- Ipv4Address m_dst; // /< Destination IP Address
- uint32_t m_hopCount; // /< Number of Hops
- uint32_t m_dstSeqNo; // /< Destination Sequence Number
+ Ipv4Address m_dst; ///< Destination IP Address
+ uint32_t m_hopCount; ///< Number of Hops
+ uint32_t m_dstSeqNo; ///< Destination Sequence Number
};
static inline std::ostream & operator<< (std::ostream& os, const DsdvHeader & packet)
{
--- a/src/dsdv/model/dsdv-routing-protocol.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/dsdv/model/dsdv-routing-protocol.cc Fri Dec 16 18:51:18 2011 +0100
@@ -47,13 +47,13 @@
namespace dsdv {
NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
-// / UDP Port for DSDV control traffic
+/// UDP Port for DSDV control traffic
const uint32_t RoutingProtocol::DSDV_PORT = 269;
-// / Tag used by DSDV implementation
+/// Tag used by DSDV implementation
struct DeferredRouteOutputTag : public Tag
{
- // / Positive if output device is fixed in RouteOutput
+ /// Positive if output device is fixed in RouteOutput
int32_t oif;
DeferredRouteOutputTag (int32_t o = -1)
--- a/src/dsdv/model/dsdv-routing-protocol.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/dsdv/model/dsdv-routing-protocol.h Fri Dec 16 18:51:18 2011 +0100
@@ -56,14 +56,14 @@
GetTypeId (void);
static const uint32_t DSDV_PORT;
- // / c-tor
+ /// c-tor
RoutingProtocol ();
virtual
~RoutingProtocol ();
virtual void
DoDispose ();
- // /\name From Ipv4RoutingProtocol
+ ///\name From Ipv4RoutingProtocol
// \{
Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
bool RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev, UnicastForwardCallback ucb,
@@ -75,7 +75,7 @@
virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
virtual void SetIpv4 (Ptr<Ipv4> ipv4);
// \}
- // /\name Methods to handle protocol parameters
+ ///\name Methods to handle protocol parameters
// \{
void SetEnableBufferFlag (bool f);
bool GetEnableBufferFlag () const;
@@ -86,64 +86,63 @@
// \}
private:
- // /\name Protocol parameters.
+ ///\name Protocol parameters.
// \{
- // / \{Holdtimes is the multiplicative factor of PeriodicUpdateInterval for which the node waits since the last update
- // / before flushing a route from the routing table. If PeriodicUpdateInterval is 8s and Holdtimes is 3, the node
- // / waits for 24s since the last update to flush this route from its routing table. \}
+ /// Holdtimes is the multiplicative factor of PeriodicUpdateInterval for which the node waits since the last update
+ /// before flushing a route from the routing table. If PeriodicUpdateInterval is 8s and Holdtimes is 3, the node
+ /// waits for 24s since the last update to flush this route from its routing table.
uint32_t Holdtimes;
- // / \{PeriodicUpdateInterval specifies the periodic time interval between which the a node broadcasts
- // / its entire routing table.\}
+ /// PeriodicUpdateInterval specifies the periodic time interval between which the a node broadcasts
+ /// its entire routing table.
Time m_periodicUpdateInterval;
- // /\{ SettlingTime specifies the time for which a node waits before propagating an update.
- // / It waits for this time interval in hope of receiving an update with a better metric.
- // /\}
+ /// SettlingTime specifies the time for which a node waits before propagating an update.
+ /// It waits for this time interval in hope of receiving an update with a better metric.
Time m_settlingTime;
- // /Nodes IP address
+ /// Nodes IP address
Ipv4Address m_mainAddress;
- // / IP protocol
+ /// IP protocol
Ptr<Ipv4> m_ipv4;
- // / Raw socket per each IP interface, map socket -> iface address (IP + mask)
+ /// Raw socket per each IP interface, map socket -> iface address (IP + mask)
std::map<Ptr<Socket>, Ipv4InterfaceAddress> m_socketAddresses;
- // / Loopback device used to defer route requests until a route is found
+ /// Loopback device used to defer route requests until a route is found
Ptr<NetDevice> m_lo;
- // / Main Routing table for the node
+ /// Main Routing table for the node
RoutingTable m_routingTable;
- // / Advertised Routing table for the node
+ /// Advertised Routing table for the node
RoutingTable m_advRoutingTable;
- // / The maximum number of packets that we allow a routing protocol to buffer.
+ /// The maximum number of packets that we allow a routing protocol to buffer.
uint32_t m_maxQueueLen;
- // / The maximum number of packets that we allow per destination to buffer.
+ /// The maximum number of packets that we allow per destination to buffer.
uint32_t m_maxQueuedPacketsPerDst;
- // /< The maximum period of time that a routing protocol is allowed to buffer a packet for.
+ /// The maximum period of time that a routing protocol is allowed to buffer a packet for.
Time m_maxQueueTime;
- // / A "drop front on full" queue used by the routing layer to buffer packets to which it does not have a route.
+ /// A "drop front on full" queue used by the routing layer to buffer packets to which it does not have a route.
PacketQueue m_queue;
- // / Flag that is used to enable or disable buffering
+ /// Flag that is used to enable or disable buffering
bool EnableBuffering;
- // / Flag that is used to enable or disable Weighted Settling Time
+ /// Flag that is used to enable or disable Weighted Settling Time
bool EnableWST;
- // / This is the wighted factor to determine the weighted settling time
+ /// This is the wighted factor to determine the weighted settling time
double m_weightedFactor;
- // / This is a flag to enable route aggregation. Route aggregation will aggregate all routes for
- // / 'RouteAggregationTime' from the time an update is received by a node and sends them as a single update .
+ /// This is a flag to enable route aggregation. Route aggregation will aggregate all routes for
+ /// 'RouteAggregationTime' from the time an update is received by a node and sends them as a single update .
bool EnableRouteAggregation;
- // / Parameter that holds the route aggregation time interval
+ /// Parameter that holds the route aggregation time interval
Time m_routeAggregationTime;
- // / Unicast callback for own packets
+ /// Unicast callback for own packets
UnicastForwardCallback m_scb;
- // / Error callback for own packets
+ /// Error callback for own packets
ErrorCallback m_ecb;
- // /\}
+ // \}
private:
- // / Start protocol operation
+ /// Start protocol operation
void
Start ();
- // / Queue packet untill we find a route
+ /// Queue packet untill we find a route
void
DeferredRouteOutput (Ptr<const Packet> p, const Ipv4Header & header, UnicastForwardCallback ucb, ErrorCallback ecb);
- // / Look for any queued packets to send them out
+ /// Look for any queued packets to send them out
void
LookForQueuedPackets (void);
/**
@@ -153,18 +152,18 @@
*/
void
SendPacketFromQueue (Ipv4Address dst, Ptr<Ipv4Route> route);
- // / Find socket with local interface address iface
+ /// Find socket with local interface address iface
Ptr<Socket>
FindSocketWithInterfaceAddress (Ipv4InterfaceAddress iface) const;
- // /\name Receive dsdv control packets
+ ///\name Receive dsdv control packets
// \{
- // / Receive and process dsdv control packet
+ /// Receive and process dsdv control packet
void
RecvDsdv (Ptr<Socket> socket);
// \}
void
Send (Ptr<Ipv4Route>, Ptr<const Packet>, const Ipv4Header &);
- // / Create loopback route for given header
+ /// Create loopback route for given header
Ptr<Ipv4Route>
LoopbackRoute (const Ipv4Header & header, Ptr<NetDevice> oif) const;
/**
@@ -174,20 +173,20 @@
*/
Time
GetSettlingTime (Ipv4Address dst);
- // / Sends trigger update from a node
+ /// Sends trigger update from a node
void
SendTriggeredUpdate ();
- // / Broadcasts the entire routing table for every PeriodicUpdateInterval
+ /// Broadcasts the entire routing table for every PeriodicUpdateInterval
void
SendPeriodicUpdate ();
void
MergeTriggerPeriodicUpdates ();
- // / Notify that packet is dropped for some reason
+ /// Notify that packet is dropped for some reason
void
Drop (Ptr<const Packet>, const Ipv4Header &, Socket::SocketErrno);
- // / Timer to trigger periodic updates from a node
+ /// Timer to trigger periodic updates from a node
Timer m_periodicUpdateTimer;
- // / Timer used by the trigger updates in case of Weighted Settling Time is used
+ /// Timer used by the trigger updates in case of Weighted Settling Time is used
Timer m_triggeredExpireTimer;
};
--- a/src/dsdv/model/dsdv-rtable.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/dsdv/model/dsdv-rtable.h Fri Dec 16 18:51:18 2011 +0100
@@ -56,7 +56,7 @@
class RoutingTableEntry
{
public:
- // / c-tor
+ /// c-tor
RoutingTableEntry (Ptr<NetDevice> dev = 0, Ipv4Address dst = Ipv4Address (), u_int32_t m_seqNo = 0,
Ipv4InterfaceAddress iface = Ipv4InterfaceAddress (), u_int32_t hops = 0, Ipv4Address nextHop = Ipv4Address (),
Time lifetime = Simulator::Now (), Time SettlingTime = Simulator::Now (), bool changedEntries = false);
@@ -180,11 +180,11 @@
Print (Ptr<OutputStreamWrapper> stream) const;
private:
- // /\name Fields
+ ///\name Fields
// \{
- // / Destination Sequence Number
+ /// Destination Sequence Number
uint32_t m_seqNo;
- // / Hop Count (number of hops needed to reach destination)
+ /// Hop Count (number of hops needed to reach destination)
uint32_t m_hops;
/**
* \brief Expiration or deletion time of the route
@@ -200,16 +200,16 @@
* - output device
*/
Ptr<Ipv4Route> m_ipv4Route;
- // / Output interface address
+ /// Output interface address
Ipv4InterfaceAddress m_iface;
- // / Routing flags: valid, invalid or in search
+ /// Routing flags: valid, invalid or in search
RouteFlags m_flag;
- // / Time for which the node retains an update with changed metric before broadcasting it.
- // / A node does that in hope of receiving a better update.
+ /// Time for which the node retains an update with changed metric before broadcasting it.
+ /// A node does that in hope of receiving a better update.
Time m_settlingTime;
- // / Flag to show if any of the routing table entries were changed with the routing update.
+ /// Flag to show if any of the routing table entries were changed with the routing update.
uint32_t m_entriesChanged;
- // \}
+ //\}
};
/**
@@ -219,7 +219,7 @@
class RoutingTable
{
public:
- // / c-tor
+ /// c-tor
RoutingTable ();
/**
* Add routing table entry if it doesn't yet exist in routing table
@@ -247,14 +247,14 @@
LookupRoute (Ipv4Address id, RoutingTableEntry & rt, bool forRouteInput);
/**
* Updating the routing Table with routing table entry rt
- * \param routing table entry rt
+ * \param rt routing table entry
* \return true on success
*/
bool
Update (RoutingTableEntry & rt);
/**
* Lookup list of addresses for which nxtHp is the next Hop address
- * \param nexthop's address for which we want the list of destinations
+ * \param nxtHp nexthop's address for which we want the list of destinations
* \param dstList is the list that will hold all these destination addresses
*/
void
@@ -265,35 +265,35 @@
*/
void
GetListOfAllRoutes (std::map<Ipv4Address, RoutingTableEntry> & allRoutes);
- // / Delete all route from interface with address iface
+ /// Delete all route from interface with address iface
void
DeleteAllRoutesFromInterface (Ipv4InterfaceAddress iface);
- // / Delete all entries from routing table
+ /// Delete all entries from routing table
void
Clear ()
{
m_ipv4AddressEntry.clear ();
}
- // / Delete all outdated entries if Lifetime is expired
+ /// Delete all outdated entries if Lifetime is expired
void
Purge (std::map<Ipv4Address, RoutingTableEntry> & removedAddresses);
- // / Print routing table
+ /// Print routing table
void
Print (Ptr<OutputStreamWrapper> stream) const;
- // / Provides the number of routes present in that nodes routing table.
+ /// Provides the number of routes present in that nodes routing table.
uint32_t
RoutingTableSize ();
/**
* Add an event for a destination address so that the update to for that destination is sent
* after the event is completed.
- * \param destination address for which this event is running.
- * \param unique eventid that was generated.
+ * \param address destination address for which this event is running.
+ * \param id unique eventid that was generated.
*/
bool
- AddIpv4Event (Ipv4Address, EventId);
+ AddIpv4Event (Ipv4Address address, EventId id);
/**
* Clear up the entry from the map after the event is completed
- * \param destination address for which this event is running.
+ * \param address destination address for which this event is running.
* \return true on success
*/
bool
@@ -301,7 +301,7 @@
/**
* Force delete an update waiting for settling time to complete as a better update to
* same destination was received.
- * \param destination address for which this event is running.
+ * \param address destination address for which this event is running.
* \return true on success
*/
bool
@@ -309,19 +309,19 @@
/**
* Force delete an update waiting for settling time to complete as a better update to
* same destination was received.
- * \param destination address for which this event is running.
+ * \param address destination address for which this event is running.
* \return true on finding out that an event is already running for that destination address.
*/
bool
ForceDeleteIpv4Event (Ipv4Address address);
/**
* Get the EcentId associated with that address.
- * \param destination address for which this event is running.
+ * \param address destination address for which this event is running.
* \return EventId on finding out an event is associated else return NULL.
*/
EventId
GetEventId (Ipv4Address address);
- // /\name Handle life time of invalid route
+ ///\name Handle life time of invalid route
// \{
Time Getholddowntime () const
{
@@ -334,13 +334,13 @@
// \}
private:
- // /\name Fields
+ ///\name Fields
// \{
- // / an entry in the routing table.
+ /// an entry in the routing table.
std::map<Ipv4Address, RoutingTableEntry> m_ipv4AddressEntry;
- // / an entry in the event table.
+ /// an entry in the event table.
std::map<Ipv4Address, EventId> m_ipv4Events;
- // /
+ ///
Time m_holddownTime;
// \}
};
--- a/src/internet/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:51:18 2011 +0100
@@ -132,6 +132,8 @@
module.add_class('Ipv6Address', import_from_module='ns.network')
## ipv6-address.h (module 'network'): ns3::Ipv6Address [class]
root_module['ns3::Ipv6Address'].implicitly_converts_to(root_module['ns3::Address'])
+ ## ipv6-address-generator.h (module 'internet'): ns3::Ipv6AddressGenerator [class]
+ module.add_class('Ipv6AddressGenerator')
## ipv6-address-helper.h (module 'internet'): ns3::Ipv6AddressHelper [class]
module.add_class('Ipv6AddressHelper')
## ipv6-interface-address.h (module 'internet'): ns3::Ipv6InterfaceAddress [class]
@@ -411,7 +413,7 @@
## tcp-header.h (module 'internet'): ns3::TcpHeader [class]
module.add_class('TcpHeader', parent=root_module['ns3::Header'])
## tcp-header.h (module 'internet'): ns3::TcpHeader::Flags_t [enumeration]
- module.add_enum('Flags_t', ['NONE', 'FIN', 'SYN', 'RST', 'PSH', 'ACK', 'URG'], outer_class=root_module['ns3::TcpHeader'])
+ module.add_enum('Flags_t', ['NONE', 'FIN', 'SYN', 'RST', 'PSH', 'ACK', 'URG', 'ECE', 'CWR'], outer_class=root_module['ns3::TcpHeader'])
## tcp-socket.h (module 'internet'): ns3::TcpSocket [class]
module.add_class('TcpSocket', parent=root_module['ns3::Socket'])
## tcp-socket-factory.h (module 'internet'): ns3::TcpSocketFactory [class]
@@ -662,6 +664,7 @@
register_Ns3Ipv4RoutingTableEntry_methods(root_module, root_module['ns3::Ipv4RoutingTableEntry'])
register_Ns3Ipv4StaticRoutingHelper_methods(root_module, root_module['ns3::Ipv4StaticRoutingHelper'])
register_Ns3Ipv6Address_methods(root_module, root_module['ns3::Ipv6Address'])
+ register_Ns3Ipv6AddressGenerator_methods(root_module, root_module['ns3::Ipv6AddressGenerator'])
register_Ns3Ipv6AddressHelper_methods(root_module, root_module['ns3::Ipv6AddressHelper'])
register_Ns3Ipv6InterfaceAddress_methods(root_module, root_module['ns3::Ipv6InterfaceAddress'])
register_Ns3Ipv6InterfaceContainer_methods(root_module, root_module['ns3::Ipv6InterfaceContainer'])
@@ -2748,6 +2751,58 @@
[param('uint8_t *', 'address')])
return
+def register_Ns3Ipv6AddressGenerator_methods(root_module, cls):
+ ## ipv6-address-generator.h (module 'internet'): ns3::Ipv6AddressGenerator::Ipv6AddressGenerator() [constructor]
+ cls.add_constructor([])
+ ## ipv6-address-generator.h (module 'internet'): ns3::Ipv6AddressGenerator::Ipv6AddressGenerator(ns3::Ipv6AddressGenerator const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Ipv6AddressGenerator const &', 'arg0')])
+ ## ipv6-address-generator.h (module 'internet'): static bool ns3::Ipv6AddressGenerator::AddAllocated(ns3::Ipv6Address const addr) [member function]
+ cls.add_method('AddAllocated',
+ 'bool',
+ [param('ns3::Ipv6Address const', 'addr')],
+ is_static=True)
+ ## ipv6-address-generator.h (module 'internet'): static ns3::Ipv6Address ns3::Ipv6AddressGenerator::GetAddress(ns3::Ipv6Prefix const prefix) [member function]
+ cls.add_method('GetAddress',
+ 'ns3::Ipv6Address',
+ [param('ns3::Ipv6Prefix const', 'prefix')],
+ is_static=True)
+ ## ipv6-address-generator.h (module 'internet'): static ns3::Ipv6Address ns3::Ipv6AddressGenerator::GetNetwork(ns3::Ipv6Prefix const prefix) [member function]
+ cls.add_method('GetNetwork',
+ 'ns3::Ipv6Address',
+ [param('ns3::Ipv6Prefix const', 'prefix')],
+ is_static=True)
+ ## ipv6-address-generator.h (module 'internet'): static void ns3::Ipv6AddressGenerator::Init(ns3::Ipv6Address const net, ns3::Ipv6Prefix const prefix, ns3::Ipv6Address const interfaceId="::1") [member function]
+ cls.add_method('Init',
+ 'void',
+ [param('ns3::Ipv6Address const', 'net'), param('ns3::Ipv6Prefix const', 'prefix'), param('ns3::Ipv6Address const', 'interfaceId', default_value='"::1"')],
+ is_static=True)
+ ## ipv6-address-generator.h (module 'internet'): static void ns3::Ipv6AddressGenerator::InitAddress(ns3::Ipv6Address const interfaceId, ns3::Ipv6Prefix const prefix) [member function]
+ cls.add_method('InitAddress',
+ 'void',
+ [param('ns3::Ipv6Address const', 'interfaceId'), param('ns3::Ipv6Prefix const', 'prefix')],
+ is_static=True)
+ ## ipv6-address-generator.h (module 'internet'): static ns3::Ipv6Address ns3::Ipv6AddressGenerator::NextAddress(ns3::Ipv6Prefix const prefix) [member function]
+ cls.add_method('NextAddress',
+ 'ns3::Ipv6Address',
+ [param('ns3::Ipv6Prefix const', 'prefix')],
+ is_static=True)
+ ## ipv6-address-generator.h (module 'internet'): static ns3::Ipv6Address ns3::Ipv6AddressGenerator::NextNetwork(ns3::Ipv6Prefix const prefix) [member function]
+ cls.add_method('NextNetwork',
+ 'ns3::Ipv6Address',
+ [param('ns3::Ipv6Prefix const', 'prefix')],
+ is_static=True)
+ ## ipv6-address-generator.h (module 'internet'): static void ns3::Ipv6AddressGenerator::Reset() [member function]
+ cls.add_method('Reset',
+ 'void',
+ [],
+ is_static=True)
+ ## ipv6-address-generator.h (module 'internet'): static void ns3::Ipv6AddressGenerator::TestMode() [member function]
+ cls.add_method('TestMode',
+ 'void',
+ [],
+ is_static=True)
+ return
+
def register_Ns3Ipv6AddressHelper_methods(root_module, cls):
## ipv6-address-helper.h (module 'internet'): ns3::Ipv6AddressHelper::Ipv6AddressHelper(ns3::Ipv6AddressHelper const & arg0) [copy constructor]
cls.add_constructor([param('ns3::Ipv6AddressHelper const &', 'arg0')])
@@ -7814,6 +7869,11 @@
'uint32_t',
[],
is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
+ ## tcp-socket.h (module 'internet'): bool ns3::TcpSocket::GetTcpNoDelay() const [member function]
+ cls.add_method('GetTcpNoDelay',
+ 'bool',
+ [],
+ is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
## tcp-socket.h (module 'internet'): void ns3::TcpSocket::SetConnCount(uint32_t count) [member function]
cls.add_method('SetConnCount',
'void',
@@ -7864,6 +7924,11 @@
'void',
[param('uint32_t', 'size')],
is_pure_virtual=True, visibility='private', is_virtual=True)
+ ## tcp-socket.h (module 'internet'): void ns3::TcpSocket::SetTcpNoDelay(bool noDelay) [member function]
+ cls.add_method('SetTcpNoDelay',
+ 'void',
+ [param('bool', 'noDelay')],
+ is_pure_virtual=True, visibility='private', is_virtual=True)
return
def register_Ns3TcpSocketFactory_methods(root_module, cls):
--- a/src/internet/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:51:18 2011 +0100
@@ -132,6 +132,8 @@
module.add_class('Ipv6Address', import_from_module='ns.network')
## ipv6-address.h (module 'network'): ns3::Ipv6Address [class]
root_module['ns3::Ipv6Address'].implicitly_converts_to(root_module['ns3::Address'])
+ ## ipv6-address-generator.h (module 'internet'): ns3::Ipv6AddressGenerator [class]
+ module.add_class('Ipv6AddressGenerator')
## ipv6-address-helper.h (module 'internet'): ns3::Ipv6AddressHelper [class]
module.add_class('Ipv6AddressHelper')
## ipv6-interface-address.h (module 'internet'): ns3::Ipv6InterfaceAddress [class]
@@ -411,7 +413,7 @@
## tcp-header.h (module 'internet'): ns3::TcpHeader [class]
module.add_class('TcpHeader', parent=root_module['ns3::Header'])
## tcp-header.h (module 'internet'): ns3::TcpHeader::Flags_t [enumeration]
- module.add_enum('Flags_t', ['NONE', 'FIN', 'SYN', 'RST', 'PSH', 'ACK', 'URG'], outer_class=root_module['ns3::TcpHeader'])
+ module.add_enum('Flags_t', ['NONE', 'FIN', 'SYN', 'RST', 'PSH', 'ACK', 'URG', 'ECE', 'CWR'], outer_class=root_module['ns3::TcpHeader'])
## tcp-socket.h (module 'internet'): ns3::TcpSocket [class]
module.add_class('TcpSocket', parent=root_module['ns3::Socket'])
## tcp-socket-factory.h (module 'internet'): ns3::TcpSocketFactory [class]
@@ -662,6 +664,7 @@
register_Ns3Ipv4RoutingTableEntry_methods(root_module, root_module['ns3::Ipv4RoutingTableEntry'])
register_Ns3Ipv4StaticRoutingHelper_methods(root_module, root_module['ns3::Ipv4StaticRoutingHelper'])
register_Ns3Ipv6Address_methods(root_module, root_module['ns3::Ipv6Address'])
+ register_Ns3Ipv6AddressGenerator_methods(root_module, root_module['ns3::Ipv6AddressGenerator'])
register_Ns3Ipv6AddressHelper_methods(root_module, root_module['ns3::Ipv6AddressHelper'])
register_Ns3Ipv6InterfaceAddress_methods(root_module, root_module['ns3::Ipv6InterfaceAddress'])
register_Ns3Ipv6InterfaceContainer_methods(root_module, root_module['ns3::Ipv6InterfaceContainer'])
@@ -2748,6 +2751,58 @@
[param('uint8_t *', 'address')])
return
+def register_Ns3Ipv6AddressGenerator_methods(root_module, cls):
+ ## ipv6-address-generator.h (module 'internet'): ns3::Ipv6AddressGenerator::Ipv6AddressGenerator() [constructor]
+ cls.add_constructor([])
+ ## ipv6-address-generator.h (module 'internet'): ns3::Ipv6AddressGenerator::Ipv6AddressGenerator(ns3::Ipv6AddressGenerator const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Ipv6AddressGenerator const &', 'arg0')])
+ ## ipv6-address-generator.h (module 'internet'): static bool ns3::Ipv6AddressGenerator::AddAllocated(ns3::Ipv6Address const addr) [member function]
+ cls.add_method('AddAllocated',
+ 'bool',
+ [param('ns3::Ipv6Address const', 'addr')],
+ is_static=True)
+ ## ipv6-address-generator.h (module 'internet'): static ns3::Ipv6Address ns3::Ipv6AddressGenerator::GetAddress(ns3::Ipv6Prefix const prefix) [member function]
+ cls.add_method('GetAddress',
+ 'ns3::Ipv6Address',
+ [param('ns3::Ipv6Prefix const', 'prefix')],
+ is_static=True)
+ ## ipv6-address-generator.h (module 'internet'): static ns3::Ipv6Address ns3::Ipv6AddressGenerator::GetNetwork(ns3::Ipv6Prefix const prefix) [member function]
+ cls.add_method('GetNetwork',
+ 'ns3::Ipv6Address',
+ [param('ns3::Ipv6Prefix const', 'prefix')],
+ is_static=True)
+ ## ipv6-address-generator.h (module 'internet'): static void ns3::Ipv6AddressGenerator::Init(ns3::Ipv6Address const net, ns3::Ipv6Prefix const prefix, ns3::Ipv6Address const interfaceId="::1") [member function]
+ cls.add_method('Init',
+ 'void',
+ [param('ns3::Ipv6Address const', 'net'), param('ns3::Ipv6Prefix const', 'prefix'), param('ns3::Ipv6Address const', 'interfaceId', default_value='"::1"')],
+ is_static=True)
+ ## ipv6-address-generator.h (module 'internet'): static void ns3::Ipv6AddressGenerator::InitAddress(ns3::Ipv6Address const interfaceId, ns3::Ipv6Prefix const prefix) [member function]
+ cls.add_method('InitAddress',
+ 'void',
+ [param('ns3::Ipv6Address const', 'interfaceId'), param('ns3::Ipv6Prefix const', 'prefix')],
+ is_static=True)
+ ## ipv6-address-generator.h (module 'internet'): static ns3::Ipv6Address ns3::Ipv6AddressGenerator::NextAddress(ns3::Ipv6Prefix const prefix) [member function]
+ cls.add_method('NextAddress',
+ 'ns3::Ipv6Address',
+ [param('ns3::Ipv6Prefix const', 'prefix')],
+ is_static=True)
+ ## ipv6-address-generator.h (module 'internet'): static ns3::Ipv6Address ns3::Ipv6AddressGenerator::NextNetwork(ns3::Ipv6Prefix const prefix) [member function]
+ cls.add_method('NextNetwork',
+ 'ns3::Ipv6Address',
+ [param('ns3::Ipv6Prefix const', 'prefix')],
+ is_static=True)
+ ## ipv6-address-generator.h (module 'internet'): static void ns3::Ipv6AddressGenerator::Reset() [member function]
+ cls.add_method('Reset',
+ 'void',
+ [],
+ is_static=True)
+ ## ipv6-address-generator.h (module 'internet'): static void ns3::Ipv6AddressGenerator::TestMode() [member function]
+ cls.add_method('TestMode',
+ 'void',
+ [],
+ is_static=True)
+ return
+
def register_Ns3Ipv6AddressHelper_methods(root_module, cls):
## ipv6-address-helper.h (module 'internet'): ns3::Ipv6AddressHelper::Ipv6AddressHelper(ns3::Ipv6AddressHelper const & arg0) [copy constructor]
cls.add_constructor([param('ns3::Ipv6AddressHelper const &', 'arg0')])
@@ -7814,6 +7869,11 @@
'uint32_t',
[],
is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
+ ## tcp-socket.h (module 'internet'): bool ns3::TcpSocket::GetTcpNoDelay() const [member function]
+ cls.add_method('GetTcpNoDelay',
+ 'bool',
+ [],
+ is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
## tcp-socket.h (module 'internet'): void ns3::TcpSocket::SetConnCount(uint32_t count) [member function]
cls.add_method('SetConnCount',
'void',
@@ -7864,6 +7924,11 @@
'void',
[param('uint32_t', 'size')],
is_pure_virtual=True, visibility='private', is_virtual=True)
+ ## tcp-socket.h (module 'internet'): void ns3::TcpSocket::SetTcpNoDelay(bool noDelay) [member function]
+ cls.add_method('SetTcpNoDelay',
+ 'void',
+ [param('bool', 'noDelay')],
+ is_pure_virtual=True, visibility='private', is_virtual=True)
return
def register_Ns3TcpSocketFactory_methods(root_module, cls):
--- a/src/internet/helper/internet-stack-helper.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/helper/internet-stack-helper.cc Fri Dec 16 18:51:18 2011 +0100
@@ -623,6 +623,40 @@
}
static void
+Ipv4L3ProtocolTxSinkWithoutContext (
+ Ptr<OutputStreamWrapper> stream,
+ Ptr<const Packet> packet,
+ Ptr<Ipv4> ipv4,
+ uint32_t interface)
+{
+ InterfacePairIpv4 pair = std::make_pair (ipv4, interface);
+ if (g_interfaceStreamMapIpv4.find (pair) == g_interfaceStreamMapIpv4.end ())
+ {
+ NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+ return;
+ }
+
+ *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << *packet << std::endl;
+}
+
+static void
+Ipv4L3ProtocolRxSinkWithoutContext (
+ Ptr<OutputStreamWrapper> stream,
+ Ptr<const Packet> packet,
+ Ptr<Ipv4> ipv4,
+ uint32_t interface)
+{
+ InterfacePairIpv4 pair = std::make_pair (ipv4, interface);
+ if (g_interfaceStreamMapIpv4.find (pair) == g_interfaceStreamMapIpv4.end ())
+ {
+ NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+ return;
+ }
+
+ *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << *packet << std::endl;
+}
+
+static void
Ipv4L3ProtocolDropSinkWithContext (
Ptr<OutputStreamWrapper> stream,
std::string context,
@@ -655,6 +689,52 @@
#endif
}
+static void
+Ipv4L3ProtocolTxSinkWithContext (
+ Ptr<OutputStreamWrapper> stream,
+ std::string context,
+ Ptr<const Packet> packet,
+ Ptr<Ipv4> ipv4,
+ uint32_t interface)
+{
+ InterfacePairIpv4 pair = std::make_pair (ipv4, interface);
+ if (g_interfaceStreamMapIpv4.find (pair) == g_interfaceStreamMapIpv4.end ())
+ {
+ NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+ return;
+ }
+
+#ifdef INTERFACE_CONTEXT
+ *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << context << "(" << interface << ") "
+ << *packet << std::endl;
+#else
+ *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << context << " " << *packet << std::endl;
+#endif
+}
+
+static void
+Ipv4L3ProtocolRxSinkWithContext (
+ Ptr<OutputStreamWrapper> stream,
+ std::string context,
+ Ptr<const Packet> packet,
+ Ptr<Ipv4> ipv4,
+ uint32_t interface)
+{
+ InterfacePairIpv4 pair = std::make_pair (ipv4, interface);
+ if (g_interfaceStreamMapIpv4.find (pair) == g_interfaceStreamMapIpv4.end ())
+ {
+ NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+ return;
+ }
+
+#ifdef INTERFACE_CONTEXT
+ *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << context << "(" << interface << ") "
+ << *packet << std::endl;
+#else
+ *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << context << " " << *packet << std::endl;
+#endif
+}
+
bool
InternetStackHelper::AsciiHooked (Ptr<Ipv4> ipv4)
{
@@ -744,8 +824,16 @@
Ptr<Ipv4L3Protocol> ipv4L3Protocol = ipv4->GetObject<Ipv4L3Protocol> ();
bool __attribute__ ((unused)) result = ipv4L3Protocol->TraceConnectWithoutContext ("Drop",
MakeBoundCallback (&Ipv4L3ProtocolDropSinkWithoutContext, theStream));
- NS_ASSERT_MSG (result == true, "InternetStackHelper::EanableAsciiIpv4Internal(): "
+ NS_ASSERT_MSG (result == true, "InternetStackHelper::EnableAsciiIpv4Internal(): "
"Unable to connect ipv4L3Protocol \"Drop\"");
+ result = ipv4L3Protocol->TraceConnectWithoutContext ("Tx",
+ MakeBoundCallback (&Ipv4L3ProtocolTxSinkWithoutContext, theStream));
+ NS_ASSERT_MSG (result == true, "InternetStackHelper::EnableAsciiIpv4Internal(): "
+ "Unable to connect ipv4L3Protocol \"Tx\"");
+ result = ipv4L3Protocol->TraceConnectWithoutContext ("Rx",
+ MakeBoundCallback (&Ipv4L3ProtocolRxSinkWithoutContext, theStream));
+ NS_ASSERT_MSG (result == true, "InternetStackHelper::EnableAsciiIpv4Internal(): "
+ "Unable to connect ipv4L3Protocol \"Rx\"");
}
g_interfaceStreamMapIpv4[std::make_pair (ipv4, interface)] = theStream;
@@ -785,6 +873,12 @@
oss.str ("");
oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv4L3Protocol/Drop";
Config::Connect (oss.str (), MakeBoundCallback (&Ipv4L3ProtocolDropSinkWithContext, stream));
+ oss.str ("");
+ oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv4L3Protocol/Tx";
+ Config::Connect (oss.str (), MakeBoundCallback (&Ipv4L3ProtocolTxSinkWithContext, stream));
+ oss.str ("");
+ oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv4L3Protocol/Rx";
+ Config::Connect (oss.str (), MakeBoundCallback (&Ipv4L3ProtocolRxSinkWithContext, stream));
}
g_interfaceStreamMapIpv4[std::make_pair (ipv4, interface)] = stream;
@@ -818,6 +912,40 @@
}
static void
+Ipv6L3ProtocolTxSinkWithoutContext (
+ Ptr<OutputStreamWrapper> stream,
+ Ptr<const Packet> packet,
+ Ptr<Ipv6> ipv6,
+ uint32_t interface)
+{
+ InterfacePairIpv6 pair = std::make_pair (ipv6, interface);
+ if (g_interfaceStreamMapIpv6.find (pair) == g_interfaceStreamMapIpv6.end ())
+ {
+ NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+ return;
+ }
+
+ *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << *packet << std::endl;
+}
+
+static void
+Ipv6L3ProtocolRxSinkWithoutContext (
+ Ptr<OutputStreamWrapper> stream,
+ Ptr<const Packet> packet,
+ Ptr<Ipv6> ipv6,
+ uint32_t interface)
+{
+ InterfacePairIpv6 pair = std::make_pair (ipv6, interface);
+ if (g_interfaceStreamMapIpv6.find (pair) == g_interfaceStreamMapIpv6.end ())
+ {
+ NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+ return;
+ }
+
+ *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << *packet << std::endl;
+}
+
+static void
Ipv6L3ProtocolDropSinkWithContext (
Ptr<OutputStreamWrapper> stream,
std::string context,
@@ -850,6 +978,52 @@
#endif
}
+static void
+Ipv6L3ProtocolTxSinkWithContext (
+ Ptr<OutputStreamWrapper> stream,
+ std::string context,
+ Ptr<const Packet> packet,
+ Ptr<Ipv6> ipv6,
+ uint32_t interface)
+{
+ InterfacePairIpv6 pair = std::make_pair (ipv6, interface);
+ if (g_interfaceStreamMapIpv6.find (pair) == g_interfaceStreamMapIpv6.end ())
+ {
+ NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+ return;
+ }
+
+#ifdef INTERFACE_CONTEXT
+ *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << context << "(" << interface << ") "
+ << *packet << std::endl;
+#else
+ *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << context << " " << *packet << std::endl;
+#endif
+}
+
+static void
+Ipv6L3ProtocolRxSinkWithContext (
+ Ptr<OutputStreamWrapper> stream,
+ std::string context,
+ Ptr<const Packet> packet,
+ Ptr<Ipv6> ipv6,
+ uint32_t interface)
+{
+ InterfacePairIpv6 pair = std::make_pair (ipv6, interface);
+ if (g_interfaceStreamMapIpv6.find (pair) == g_interfaceStreamMapIpv6.end ())
+ {
+ NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+ return;
+ }
+
+#ifdef INTERFACE_CONTEXT
+ *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << context << "(" << interface << ") "
+ << *packet << std::endl;
+#else
+ *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << context << " " << *packet << std::endl;
+#endif
+}
+
bool
InternetStackHelper::AsciiHooked (Ptr<Ipv6> ipv6)
{
@@ -933,6 +1107,14 @@
MakeBoundCallback (&Ipv6L3ProtocolDropSinkWithoutContext, theStream));
NS_ASSERT_MSG (result == true, "InternetStackHelper::EnableAsciiIpv6Internal(): "
"Unable to connect ipv6L3Protocol \"Drop\"");
+ result = ipv6L3Protocol->TraceConnectWithoutContext ("Tx",
+ MakeBoundCallback (&Ipv6L3ProtocolTxSinkWithoutContext, theStream));
+ NS_ASSERT_MSG (result == true, "InternetStackHelper::EnableAsciiIpv6Internal(): "
+ "Unable to connect ipv6L3Protocol \"Tx\"");
+ result = ipv6L3Protocol->TraceConnectWithoutContext ("Rx",
+ MakeBoundCallback (&Ipv6L3ProtocolRxSinkWithoutContext, theStream));
+ NS_ASSERT_MSG (result == true, "InternetStackHelper::EnableAsciiIpv6Internal(): "
+ "Unable to connect ipv6L3Protocol \"Rx\"");
}
g_interfaceStreamMapIpv6[std::make_pair (ipv6, interface)] = theStream;
@@ -956,8 +1138,15 @@
Ptr<Node> node = ipv6->GetObject<Node> ();
std::ostringstream oss;
+ oss.str ("");
oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv6L3Protocol/Drop";
Config::Connect (oss.str (), MakeBoundCallback (&Ipv6L3ProtocolDropSinkWithContext, stream));
+ oss.str ("");
+ oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv6L3Protocol/Tx";
+ Config::Connect (oss.str (), MakeBoundCallback (&Ipv6L3ProtocolTxSinkWithContext, stream));
+ oss.str ("");
+ oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv6L3Protocol/Rx";
+ Config::Connect (oss.str (), MakeBoundCallback (&Ipv6L3ProtocolRxSinkWithContext, stream));
}
g_interfaceStreamMapIpv6[std::make_pair (ipv6, interface)] = stream;
--- a/src/internet/helper/internet-stack-helper.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/helper/internet-stack-helper.h Fri Dec 16 18:51:18 2011 +0100
@@ -209,12 +209,12 @@
bool explicitFilename);
/**
- * @brief Enable pcap output the indicated Ipv4 and interface pair.
+ * @brief Enable pcap output the indicated Ipv6 and interface pair.
* @internal
*
* @param prefix Filename prefix to use for pcap files.
- * @param ipv4 Ptr to the Ipv4 interface on which you want to enable tracing.
- * @param interface Interface ID on the Ipv4 on which you want to enable tracing.
+ * @param ipv6 Ptr to the Ipv6 interface on which you want to enable tracing.
+ * @param interface Interface ID on the Ipv6 on which you want to enable tracing.
*/
virtual void EnablePcapIpv6Internal (std::string prefix,
Ptr<Ipv6> ipv6,
@@ -222,14 +222,14 @@
bool explicitFilename);
/**
- * @brief Enable ascii trace output on the indicated Ipv4 and interface pair.
+ * @brief Enable ascii trace output on the indicated Ipv6 and interface pair.
* @internal
*
* @param stream An OutputStreamWrapper representing an existing file to use
* when writing trace data.
* @param prefix Filename prefix to use for ascii trace files.
- * @param ipv4 Ptr to the Ipv4 interface on which you want to enable tracing.
- * @param interface Interface ID on the Ipv4 on which you want to enable tracing.
+ * @param ipv6 Ptr to the Ipv6 interface on which you want to enable tracing.
+ * @param interface Interface ID on the Ipv6 on which you want to enable tracing.
*/
virtual void EnableAsciiIpv6Internal (Ptr<OutputStreamWrapper> stream,
std::string prefix,
--- a/src/internet/model/ipv4-header.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/ipv4-header.h Fri Dec 16 18:51:18 2011 +0100
@@ -111,7 +111,7 @@
};
/**
* \brief Set ECN Field
- * \param ECN Type
+ * \param ecn ECN Type
*/
void SetEcn (EcnType ecn);
/**
--- a/src/internet/model/ipv4-l3-protocol.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/ipv4-l3-protocol.cc Fri Dec 16 18:51:18 2011 +0100
@@ -1135,8 +1135,16 @@
uint16_t offset = 0;
bool moreFragment = true;
+ uint16_t originalOffset = 0;
+ bool alreadyFragmented = false;
uint32_t currentFragmentablePartSize = 0;
+ if (!ipv4Header.IsLastFragment())
+ {
+ alreadyFragmented = true;
+ originalOffset = ipv4Header.GetFragmentOffset();
+ }
+
// IPv4 fragments are all 8 bytes aligned but the last.
// The IP payload size is:
// floor( ( outIfaceMtu - ipv4Header.GetSerializedSize() ) /8 ) *8
@@ -1158,14 +1166,21 @@
{
moreFragment = false;
currentFragmentablePartSize = p->GetSize () - offset;
- fragmentHeader.SetLastFragment ();
+ if (alreadyFragmented)
+ {
+ fragmentHeader.SetMoreFragments ();
+ }
+ else
+ {
+ fragmentHeader.SetLastFragment ();
+ }
}
NS_LOG_LOGIC ("Fragment creation - " << offset << ", " << currentFragmentablePartSize );
Ptr<Packet> fragment = p->CreateFragment (offset, currentFragmentablePartSize);
NS_LOG_LOGIC ("Fragment created - " << offset << ", " << fragment->GetSize () );
- fragmentHeader.SetFragmentOffset (offset);
+ fragmentHeader.SetFragmentOffset (offset+originalOffset);
fragmentHeader.SetPayloadSize (currentFragmentablePartSize);
if (Node::ChecksumEnabled ())
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet/model/ipv6-address-generator.cc Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,604 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 University of Washington
+ * Copyright (c) 2011 Atishay Jain
+ *
+ * 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
+ */
+
+#include <list>
+#include "ns3/abort.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/simulation-singleton.h"
+#include "ipv6-address-generator.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6AddressGenerator");
+
+namespace ns3 {
+
+class Ipv6AddressGeneratorImpl
+{
+public:
+ Ipv6AddressGeneratorImpl ();
+ virtual ~Ipv6AddressGeneratorImpl ();
+
+ void Init (const Ipv6Address net, const Ipv6Prefix prefix,
+ const Ipv6Address interfaceId);
+
+ Ipv6Address GetNetwork (const Ipv6Prefix prefix) const;
+ Ipv6Address NextNetwork (const Ipv6Prefix prefix);
+
+ void InitAddress (const Ipv6Address interfaceId, const Ipv6Prefix prefix);
+ Ipv6Address GetAddress (const Ipv6Prefix prefix) const;
+ Ipv6Address NextAddress (const Ipv6Prefix prefix);
+
+ void Reset (void);
+ bool AddAllocated (const Ipv6Address addr);
+
+ void TestMode (void);
+private:
+ static const uint32_t N_BITS = 128;
+ static const uint32_t MOST_SIGNIFICANT_BIT = 0x80;
+
+ uint32_t PrefixToIndex (Ipv6Prefix prefix) const;
+
+ class NetworkState
+ {
+public:
+ uint8_t prefix[16];
+ uint32_t shift;
+ uint8_t network[16];
+ uint8_t addr[16];
+ uint8_t addrMax[16];
+ };
+
+ NetworkState m_netTable[N_BITS];
+
+ class Entry
+ {
+public:
+ uint8_t addrLow[16];
+ uint8_t addrHigh[16];
+ };
+
+ std::list<Entry> m_entries;
+ Ipv6Address m_base;
+ bool m_test;
+};
+
+Ipv6AddressGeneratorImpl::Ipv6AddressGeneratorImpl ()
+ : m_entries (),
+ m_base ("::1"),
+ m_test (false)
+{
+ NS_LOG_FUNCTION (this);
+ Reset ();
+}
+
+void
+Ipv6AddressGeneratorImpl::Reset (void)
+{
+ NS_LOG_FUNCTION (this);
+
+ uint8_t prefix[16] = { 0};
+
+ for (uint32_t i = 0; i < N_BITS; ++i)
+ {
+ for (uint32_t j = 0; j < 16; ++j)
+ {
+ m_netTable[i].prefix[j] = prefix[j];
+ }
+ for (uint32_t j = 0; j < 15; ++j)
+ {
+ prefix[15 - j] >>= 1;
+ prefix[15 - j] |= (prefix[15 - j - 1] & 1);
+ }
+ prefix[0] |= MOST_SIGNIFICANT_BIT;
+ for (uint32_t j = 0; j < 15; ++j)
+ {
+ m_netTable[i].network[j] = 0;
+ }
+ m_netTable[i].network[15] = 1;
+ for (uint32_t j = 0; j < 15; ++j)
+ {
+ m_netTable[i].addr[j] = 0;
+ }
+ m_netTable[i].addr[15] = 1;
+ for (uint32_t j = 0; j < 16; ++j)
+ {
+ m_netTable[i].addrMax[j] = ~prefix[j];
+ }
+ m_netTable[i].shift = N_BITS - i;
+ }
+ m_entries.clear ();
+ m_base = Ipv6Address ("::1");
+ m_test = false;
+}
+
+Ipv6AddressGeneratorImpl::~Ipv6AddressGeneratorImpl ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+void
+Ipv6AddressGeneratorImpl::Init (
+ const Ipv6Address net,
+ const Ipv6Prefix prefix,
+ const Ipv6Address interfaceId)
+{
+ NS_LOG_FUNCTION (this << net << prefix << interfaceId);
+
+ m_base = interfaceId;
+ //
+ // We're going to be playing with the actual bits in the network and prefix so
+ // pull them out into ints.
+ //
+ uint8_t prefixBits[16];
+ prefix.GetBytes (prefixBits);
+ uint8_t netBits[16];
+ net.GetBytes (netBits);
+ uint8_t interfaceIdBits[16];
+ interfaceId.GetBytes (interfaceIdBits);
+ //
+ // Some quick reasonableness testing.
+ //
+ // Convert the network prefix into an index into the network number table.
+ // The network number comes in to us properly aligned for the prefix and so
+ // needs to be shifted right into the normalized position (lowest bit of the
+ // network number at bit zero of the int that holds it).
+ //
+ uint32_t index = PrefixToIndex (prefix);
+ uint32_t a = m_netTable[index].shift / 8;
+ uint32_t b = m_netTable[index].shift % 8;
+ for (int32_t j = 15 - a; j >= 0; j--)
+ {
+ m_netTable[index].network[j + a] = netBits[j];
+ }
+ for (uint32_t j = 0; j < a; j++)
+ {
+ m_netTable[index].network[j] = 0;
+ }
+ for (uint32_t j = 15; j >= a; j--)
+ {
+ m_netTable[index].network[j] = m_netTable[index].network[j] >> b;
+ m_netTable[index].network[j] |= m_netTable[index].network[j - 1] << (8 - b);
+ }
+ for (int32_t j = 0; j < 16; j++)
+ {
+ m_netTable[index].addr[j] = interfaceIdBits[j];
+ }
+ return;
+}
+
+Ipv6Address
+Ipv6AddressGeneratorImpl::GetNetwork (
+ const Ipv6Prefix prefix) const
+{
+ NS_LOG_FUNCTION (this);
+ uint8_t nw[16];
+ uint32_t index = PrefixToIndex (prefix);
+ uint32_t a = m_netTable[index].shift / 8;
+ uint32_t b = m_netTable[index].shift % 8;
+ for (uint32_t j = 0; j < 16 - a; ++j)
+ {
+ nw[j] = m_netTable[index].network[j + a];
+ }
+ for (uint32_t j = 16 - a; j < 16; ++j)
+ {
+ nw[j] = 0;
+ }
+ for (uint32_t j = 0; j < 15; j++)
+ {
+ nw[j] = nw[j] << b;
+ nw[j] |= nw[j + 1] >> (8 - b);
+ }
+ nw[15] = nw[15] << b;
+
+ return Ipv6Address (nw);
+}
+
+Ipv6Address
+Ipv6AddressGeneratorImpl::NextNetwork (
+ const Ipv6Prefix prefix)
+{
+ NS_LOG_FUNCTION (this);
+
+ uint32_t index = PrefixToIndex (prefix);
+ // Reset the base to what was initialized
+ uint8_t interfaceIdBits[16];
+ m_base.GetBytes (interfaceIdBits);
+ for (int32_t j = 0; j < 16; j++)
+ {
+ m_netTable[index].addr[j] = interfaceIdBits[j];
+ }
+
+ for (int32_t j = 15; j >= 0; j--)
+ {
+ if (m_netTable[index].network[j] < 0xff)
+ {
+ ++m_netTable[index].network[j];
+ break;
+ }
+ else
+ {
+ ++m_netTable[index].network[j];
+ }
+ }
+
+ uint8_t nw[16];
+ uint32_t a = m_netTable[index].shift / 8;
+ uint32_t b = m_netTable[index].shift % 8;
+ for (uint32_t j = 0; j < 16 - a; ++j)
+ {
+ nw[j] = m_netTable[index].network[j + a];
+ }
+ for (uint32_t j = 16 - a; j < 16; ++j)
+ {
+ nw[j] = 0;
+ }
+ for (uint32_t j = 0; j < 15; j++)
+ {
+ nw[j] = nw[j] << b;
+ nw[j] |= nw[j + 1] >> (8 - b);
+ }
+ nw[15] = nw[15] << b;
+
+ return Ipv6Address (nw);
+
+}
+
+void
+Ipv6AddressGeneratorImpl::InitAddress (
+ const Ipv6Address interfaceId,
+ const Ipv6Prefix prefix)
+{
+ NS_LOG_FUNCTION (this);
+
+ uint32_t index = PrefixToIndex (prefix);
+ uint8_t interfaceIdBits[16];
+ interfaceId.GetBytes (interfaceIdBits);
+
+ for (uint32_t j = 0; j < 16; ++j)
+ {
+ m_netTable[index].addr[j] = interfaceIdBits[j];
+ }
+}
+
+Ipv6Address
+Ipv6AddressGeneratorImpl::GetAddress (const Ipv6Prefix prefix) const
+{
+ NS_LOG_FUNCTION (this);
+
+ uint32_t index = PrefixToIndex (prefix);
+
+ uint8_t nw[16];
+ uint32_t a = m_netTable[index].shift / 8;
+ uint32_t b = m_netTable[index].shift % 8;
+ for (uint32_t j = 0; j < 16 - a; ++j)
+ {
+ nw[j] = m_netTable[index].network[j + a];
+ }
+ for (uint32_t j = 16 - a; j < 16; ++j)
+ {
+ nw[j] = 0;
+ }
+ for (uint32_t j = 0; j < 15; j++)
+ {
+ nw[j] = nw[j] << b;
+ nw[j] |= nw[j + 1] >> (8 - b);
+ }
+ nw[15] = nw[15] << b;
+ for (uint32_t j = 0; j < 16; j++)
+ {
+ nw[j] |= m_netTable[index].addr[j];
+ }
+
+ return Ipv6Address (nw);
+}
+
+Ipv6Address
+Ipv6AddressGeneratorImpl::NextAddress (const Ipv6Prefix prefix)
+{
+ NS_LOG_FUNCTION (this);
+
+ uint32_t index = PrefixToIndex (prefix);
+
+ uint8_t ad[16];
+ uint32_t a = m_netTable[index].shift / 8;
+ uint32_t b = m_netTable[index].shift % 8;
+ for (uint32_t j = 0; j < 16 - a; ++j)
+ {
+ ad[j] = m_netTable[index].network[j + a];
+ }
+ for (uint32_t j = 16 - a; j < 16; ++j)
+ {
+ ad[j] = 0;
+ }
+ for (uint32_t j = 0; j < 15; j++)
+ {
+ ad[j] = ad[j] << b;
+ ad[j] |= ad[j + 1] >> (8 - b);
+ }
+ ad[15] = ad[15] << b;
+ for (uint32_t j = 0; j < 16; j++)
+ {
+ ad[j] |= m_netTable[index].addr[j];
+ }
+ Ipv6Address addr = Ipv6Address (ad);
+
+ for (int32_t j = 15; j >= 0; j--)
+ {
+ if (m_netTable[index].addr[j] < 0xff)
+ {
+ ++m_netTable[index].addr[j];
+ break;
+ }
+ else
+ {
+ ++m_netTable[index].addr[j];
+ }
+ }
+
+ //
+ // Make a note that we've allocated this address -- used for address collision
+ // detection.
+ //
+ AddAllocated (addr);
+ return addr;
+}
+
+bool
+Ipv6AddressGeneratorImpl::AddAllocated (const Ipv6Address address)
+{
+ NS_LOG_FUNCTION (this << address);
+
+ uint8_t addr[16];
+ address.GetBytes (addr);
+
+ std::list<Entry>::iterator i;
+
+ for (i = m_entries.begin (); i != m_entries.end (); ++i)
+ {
+ NS_LOG_LOGIC ("examine entry: " << Ipv6Address ((*i).addrLow) <<
+ " to " << Ipv6Address ((*i).addrHigh));
+ //
+ // First things first. Is there an address collision -- that is, does the
+ // new address fall in a previously allocated block of addresses.
+ //
+ if (!(Ipv6Address (addr) < Ipv6Address ((*i).addrLow))
+ && ((Ipv6Address (addr) < Ipv6Address ((*i).addrHigh))
+ || (Ipv6Address (addr) == Ipv6Address ((*i).addrHigh))))
+ {
+ NS_LOG_LOGIC ("Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address (addr));
+ if (!m_test)
+ {
+ NS_FATAL_ERROR ("Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address (addr));
+ }
+ return false;
+ }
+ //
+ // If the new address is less than the lowest address in the current
+ // block and can't be merged into to the current block, then insert it
+ // as a new block before the current block.
+ //
+ uint8_t taddr[16];
+ for (uint32_t j = 0; j < 16; j++)
+ {
+ taddr[j] = (*i).addrLow[j];
+ }
+ taddr[15] -= 1;
+ if (Ipv6Address (addr) < Ipv6Address (taddr))
+ {
+ break;
+ }
+ //
+ // If the new address fits at the end of the block, look ahead to the next
+ // block and make sure it's not a collision there. If we won't overlap,
+ // then just extend the current block by one address. We expect that
+ // completely filled network ranges will be a fairly rare occurrence,
+ // so we don't worry about collapsing address range blocks.
+ //
+ for (uint32_t j = 0; j < 16; j++)
+ {
+ taddr[j] = (*i).addrLow[j];
+ }
+ taddr[15] += 1;
+ if (Ipv6Address (addr) == Ipv6Address (taddr))
+ {
+ std::list<Entry>::iterator j = i;
+ ++j;
+
+ if (j != m_entries.end ())
+ {
+ if (Ipv6Address (addr) == Ipv6Address ((*j).addrLow))
+ {
+ NS_LOG_LOGIC ("Ipv6AddressGeneratorImpl::Add(): "
+ "Address Collision: " << Ipv6Address (addr));
+ if (!m_test)
+ {
+ NS_FATAL_ERROR ("Ipv6AddressGeneratorImpl::Add(): Address Collision: " << Ipv6Address (addr));
+ }
+ return false;
+ }
+ }
+
+ NS_LOG_LOGIC ("New addrHigh = " << Ipv6Address (addr));
+ for (uint32_t j = 0; j < 16; j++)
+ {
+ (*i).addrHigh[j] = addr[j];
+ }
+ return true;
+ }
+ //
+ // If we get here, we know that the next lower block of addresses
+ // couldn't have been extended to include this new address since the
+ // code immediately above would have been executed and that next lower
+ // block extended upward. So we know it's safe to extend the current
+ // block down to includ the new address.
+ //
+ for (uint32_t j = 0; j < 16; j++)
+ {
+ taddr[j] = (*i).addrLow[j];
+ }
+ taddr[15] -= 1;
+ if ((Ipv6Address (addr) == Ipv6Address (taddr)))
+ {
+ NS_LOG_LOGIC ("New addrLow = " << Ipv6Address (addr));
+ for (uint32_t j = 0; j < 16; j++)
+ {
+ (*i).addrLow[j] = addr[j];
+ }
+ return true;
+ }
+ }
+
+ Entry entry;
+ for (uint32_t j = 0; j < 16; j++)
+ {
+ entry.addrLow[j] = entry.addrHigh[j] = addr[j];
+ }
+ m_entries.insert (i, entry);
+ return true;
+}
+
+void
+Ipv6AddressGeneratorImpl::TestMode (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_test = true;
+}
+
+uint32_t
+Ipv6AddressGeneratorImpl::PrefixToIndex (Ipv6Prefix prefix) const
+{
+ //
+ // We've been given a prefix that has a higher order bit set for each bit of
+ // the network number. In order to translate this prefix into an index,
+ // we just need to count the number of zero bits in the prefix. We do this
+ // in a loop in which we shift the prefix right until we find the first
+ // nonzero bit. This tells us the number of zero bits, and from this we
+ // infer the number of nonzero bits which is the number of bits in the prefix.
+ //
+ // We use the number of bits in the prefix as the number of bits in the
+ // network number and as the index into the network number state table.
+ //
+ uint8_t prefixBits[16];
+ prefix.GetBytes (prefixBits);
+
+ for (uint32_t i = 15; i >= 0; --i)
+ {
+ for (uint32_t j = 0; j < 8; ++j)
+ {
+ if (prefixBits[i] & 1)
+ {
+ uint32_t index = N_BITS - (15 - i) * 8 - j;
+ NS_ABORT_MSG_UNLESS (index > 0 && index < N_BITS, "Ip64AddressGenerator::PrefixToIndex(): Illegal Prefix");
+ return index;
+ }
+ prefixBits[i] >>= 1;
+ }
+ }
+ NS_ASSERT_MSG (false, "Ipv6AddressGenerator::PrefixToIndex(): Impossible");
+ return 0;
+}
+
+void
+Ipv6AddressGenerator::Init (
+ const Ipv6Address net,
+ const Ipv6Prefix prefix,
+ const Ipv6Address interfaceId)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+ ->Init (net, prefix, interfaceId);
+}
+
+Ipv6Address
+Ipv6AddressGenerator::NextNetwork (const Ipv6Prefix prefix)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+ ->NextNetwork (prefix);
+}
+
+Ipv6Address
+Ipv6AddressGenerator::GetNetwork (const Ipv6Prefix prefix)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+ ->GetNetwork (prefix);
+}
+
+void
+Ipv6AddressGenerator::InitAddress (
+ const Ipv6Address interfaceId,
+ const Ipv6Prefix prefix)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+ ->InitAddress (interfaceId, prefix);
+}
+
+Ipv6Address
+Ipv6AddressGenerator::GetAddress (const Ipv6Prefix prefix)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+ ->GetAddress (prefix);
+}
+
+Ipv6Address
+Ipv6AddressGenerator::NextAddress (const Ipv6Prefix prefix)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+ ->NextAddress (prefix);
+}
+
+void
+Ipv6AddressGenerator::Reset (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+ ->Reset ();
+}
+
+bool
+Ipv6AddressGenerator::AddAllocated (const Ipv6Address addr)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+ ->AddAllocated (addr);
+}
+
+void
+Ipv6AddressGenerator::TestMode (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ SimulationSingleton<Ipv6AddressGeneratorImpl>::Get ()
+ ->TestMode ();
+}
+
+} // namespace ns3
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet/model/ipv6-address-generator.h Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 University of Washington
+ * Copyright (c) 2011 Atishay Jain
+ *
+ * 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
+ */
+
+#ifndef IPV6_ADDRESS_GENERATOR_H
+#define IPV6_ADDRESS_GENERATOR_H
+
+#include "ns3/ipv6-address.h"
+
+namespace ns3 {
+
+/**
+ * \ingroup address
+ *
+ * \brief This generator assigns addresses sequentially from a provided
+ * network address; used in topology code. It also keeps track of all
+ * addresses assigned to perform duplicate detection.
+ *
+ * Global unicast IPv6 addresses based on RFC 4291 definition:
+ *
+ * | n bits | m bits | 128-n-m bits |
+ * +-------------------------+-----------+----------------------------+
+ * | global routing prefix | subnet ID | interface ID |
+ * +-------------------------+-----------+----------------------------+
+ *
+ * In this class, the first two quantities (n + m) are what is called the
+ * 'net', and the 'prefix' defines the length in bits of (n + m).
+ *
+ * The way this is expected to be used is that, after initializing the
+ * network and interfaceId to a number, a user can call NextAddress ()
+ * repeatedly to obtain new interface IDs with the current network (for
+ * multiple addresses on the link) and can call NextNetwork () to increment
+ * the subnet ID.
+ *
+ * The interface ID is often an EUI-64 address derived from the MAC address,
+ * but can also be a pseudo-random value (RFC 3041). This implementation
+ * does not generate EUI-64-based interface IDs.
+ */
+class Ipv6AddressGenerator
+{
+public:
+ /**
+ * \brief Initialise the base network and interfaceId for the generator
+ *
+ * The first call to NextAddress() or GetAddress() will return the
+ * value passed in.
+ *
+ * \param net The network for the base Ipv6Address
+ * \param prefix The prefix of the base Ipv6Address
+ * \param interfaceId The base interface ID used for initialization
+ */
+ static void Init (const Ipv6Address net, const Ipv6Prefix prefix,
+ const Ipv6Address interfaceId = "::1");
+
+ /**
+ * \brief Get the next network acoording to the given Ipv6Prefix
+ *
+ * This operation is a pre-increment, meaning that the internal state
+ * is changed before returning the new network address.
+ *
+ * This also resets the interface ID to the base interface ID that was
+ * used for initialization.
+ *
+ * \param prefix The Ipv6Prefix used to set the next network
+ */
+ static Ipv6Address NextNetwork (const Ipv6Prefix prefix);
+
+ /**
+ * \brief Get the current network of the given Ipv6Prefix
+ *
+ * Does not change the internal state; this just peeks at the current
+ * network
+ *
+ * \param prefix The Ipv6Prefix for the current network
+ */
+ static Ipv6Address GetNetwork (const Ipv6Prefix prefix);
+
+ /**
+ * \brief Set the interfaceId for the given Ipv6Prefix
+ *
+ * \param interfaceId The interfaceId to set for the current Ipv6Prefix
+ * \param prefix The Ipv6Prefix whose address is to be set
+ */
+ static void InitAddress (const Ipv6Address interfaceId, const Ipv6Prefix prefix);
+
+ /**
+ * \brief Allocate the next Ipv6Address for the configured network and prefix
+ *
+ * This operation is a post-increment, meaning that the first address
+ * allocated will be the one that was initially configured.
+ * .
+ * \param prefix The Ipv6Prefix for the current network
+ */
+ static Ipv6Address NextAddress (const Ipv6Prefix prefix);
+
+ /**
+ * \brief Get the Ipv6Address that will be allocated upon NextAddress()
+ *
+ * Does not change the internal state; just is used to peek the next
+ * address that will be allocated upon NextAddress ()
+ *
+ * \param prefix The Ipv6Prefix for the current network
+ */
+ static Ipv6Address GetAddress (const Ipv6Prefix prefix);
+
+ /**
+ * \brief Reset the networks and Ipv6Address to zero
+ */
+ static void Reset (void);
+
+ /**
+ * \brief Add the Ipv6Address to the list of IPv6 entries
+ *
+ * Typically, this is used by external address allocators that want
+ * to make use of this class's ability to track duplicates. AddAllocated
+ * is always called internally for any address generated by NextAddress()
+ *
+ * \param addr The Ipv6Address to be added to the list of Ipv6 entries
+ */
+ static bool AddAllocated (const Ipv6Address addr);
+
+ /**
+ * \brief Used to turn off fatal errors and assertions, for testing
+ */
+ static void TestMode (void);
+};
+
+}; // namespace ns3
+
+#endif /* IPV6_ADDRESS_GENERATOR_H */
--- a/src/internet/model/nsc-tcp-socket-impl.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/nsc-tcp-socket-impl.cc Fri Dec 16 18:51:18 2011 +0100
@@ -85,6 +85,7 @@
: TcpSocket (sock), //copy the base class callbacks
m_delAckMaxCount (sock.m_delAckMaxCount),
m_delAckTimeout (sock.m_delAckTimeout),
+ m_noDelay (sock.m_noDelay),
m_endPoint (0),
m_node (sock.m_node),
m_tcp (sock.m_tcp),
@@ -136,7 +137,7 @@
* when DeAllocate is called, it will call into
* Ipv4EndPointDemux::Deallocate which triggers
* a delete of the associated endPoint which triggers
- * in turn a call to the method ::Destroy below
+ * in turn a call to the method NscTcpSocketImpl::Destroy below
* will will zero the m_endPoint field.
*/
NS_ASSERT (m_endPoint != 0);
@@ -797,6 +798,18 @@
return m_delAckMaxCount;
}
+void
+NscTcpSocketImpl::SetTcpNoDelay (bool noDelay)
+{
+ m_noDelay = noDelay;
+}
+
+bool
+NscTcpSocketImpl::GetTcpNoDelay (void) const
+{
+ return m_noDelay;
+}
+
void
NscTcpSocketImpl::SetPersistTimeout (Time timeout)
{
--- a/src/internet/model/nsc-tcp-socket-impl.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/nsc-tcp-socket-impl.h Fri Dec 16 18:51:18 2011 +0100
@@ -125,12 +125,15 @@
virtual Time GetDelAckTimeout (void) const;
virtual void SetDelAckMaxCount (uint32_t count);
virtual uint32_t GetDelAckMaxCount (void) const;
+ virtual void SetTcpNoDelay (bool noDelay);
+ virtual bool GetTcpNoDelay (void) const;
virtual void SetPersistTimeout (Time timeout);
virtual Time GetPersistTimeout (void) const;
enum Socket::SocketErrno GetNativeNs3Errno (int err) const;
uint32_t m_delAckMaxCount;
Time m_delAckTimeout;
+ bool m_noDelay;
Ipv4EndPoint *m_endPoint;
Ptr<Node> m_node;
--- a/src/internet/model/rtt-estimator.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/rtt-estimator.cc Fri Dec 16 18:51:18 2011 +0100
@@ -54,7 +54,7 @@
MakeTimeChecker ())
.AddAttribute ("MinRTO",
"Minimum retransmit timeout value",
- TimeValue (Seconds (0.2)),
+ TimeValue (Seconds (0.2)), // RFC2988 says min RTO=1 sec, but Linux uses 200ms. See http://www.postel.org/pipermail/end2end-interest/2004-November/004402.html
MakeTimeAccessor (&RttEstimator::SetMinRto,
&RttEstimator::GetMinRto),
MakeTimeChecker ())
--- a/src/internet/model/tcp-header.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-header.cc Fri Dec 16 18:51:18 2011 +0100
@@ -197,6 +197,14 @@
{
os<<" URG ";
}
+ if((m_flags & ECE) != 0)
+ {
+ os<<" ECE ";
+ }
+ if((m_flags & CWR) != 0)
+ {
+ os<<" CWR ";
+ }
os<<"]";
}
os<<" Seq="<<m_sequenceNumber<<" Ack="<<m_ackNumber<<" Win="<<m_windowSize;
--- a/src/internet/model/tcp-header.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-header.h Fri Dec 16 18:51:18 2011 +0100
@@ -134,7 +134,7 @@
uint8_t protocol);
typedef enum { NONE = 0, FIN = 1, SYN = 2, RST = 4, PSH = 8, ACK = 16,
- URG = 32} Flags_t;
+ URG = 32, ECE = 64, CWR = 128} Flags_t;
static TypeId GetTypeId (void);
virtual TypeId GetInstanceTypeId (void) const;
--- a/src/internet/model/tcp-l4-protocol.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-l4-protocol.cc Fri Dec 16 18:51:18 2011 +0100
@@ -137,10 +137,6 @@
TcpL4Protocol::DoDispose (void)
{
NS_LOG_FUNCTION_NOARGS ();
- for (std::vector<Ptr<TcpSocketBase> >::iterator i = m_sockets.begin (); i != m_sockets.end (); i++)
- {
- *i = 0;
- }
m_sockets.clear ();
if (m_endPoints != 0)
@@ -167,7 +163,6 @@
socket->SetNode (m_node);
socket->SetTcp (this);
socket->SetRtt (rtt);
- m_sockets.push_back (socket);
return socket;
}
--- a/src/internet/model/tcp-newreno.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-newreno.cc Fri Dec 16 18:51:18 2011 +0100
@@ -40,6 +40,14 @@
static TypeId tid = TypeId ("ns3::TcpNewReno")
.SetParent<TcpSocketBase> ()
.AddConstructor<TcpNewReno> ()
+ .AddAttribute ("ReTxThreshold", "Threshold for fast retransmit",
+ UintegerValue (3),
+ MakeUintegerAccessor (&TcpNewReno::m_retxThresh),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("LimitedTransmit", "Enable limited transmit",
+ BooleanValue (false),
+ MakeBooleanAccessor (&TcpNewReno::m_limitedTx),
+ MakeBooleanChecker ())
.AddTraceSource ("CongestionWindow",
"The TCP connection's congestion window",
MakeTraceSourceAccessor (&TcpNewReno::m_cWnd))
@@ -47,7 +55,10 @@
return tid;
}
-TcpNewReno::TcpNewReno (void) : m_inFastRec (false)
+TcpNewReno::TcpNewReno (void)
+ : m_retxThresh (3), // mute valgrind, actual value set by the attribute system
+ m_inFastRec (false),
+ m_limitedTx (false) // mute valgrind, actual value set by the attribute system
{
NS_LOG_FUNCTION (this);
}
@@ -57,7 +68,9 @@
m_cWnd (sock.m_cWnd),
m_ssThresh (sock.m_ssThresh),
m_initialCWnd (sock.m_initialCWnd),
- m_inFastRec (false)
+ m_retxThresh (sock.m_retxThresh),
+ m_inFastRec (false),
+ m_limitedTx (sock.m_limitedTx)
{
NS_LOG_FUNCTION (this);
NS_LOG_LOGIC ("Invoked the copy constructor");
@@ -111,6 +124,7 @@
// Check for exit condition of fast recovery
if (m_inFastRec && seq < m_recover)
{ // Partial ACK, partial window deflation (RFC2582 sec.3 bullet #5 paragraph 3)
+ m_cWnd -= seq - m_txBuffer.HeadSequence ();
m_cWnd += m_segmentSize; // increase cwnd
NS_LOG_INFO ("Partial ACK in fast recovery: cwnd set to " << m_cWnd);
TcpSocketBase::NewAck (seq); // update m_nextTxSequence and send new data if allowed by window
@@ -148,7 +162,7 @@
TcpNewReno::DupAck (const TcpHeader& t, uint32_t count)
{
NS_LOG_FUNCTION (this << count);
- if (count == 3 && !m_inFastRec)
+ if (count == m_retxThresh && !m_inFastRec)
{ // triple duplicate ack triggers fast retransmit (RFC2582 sec.3 bullet #1)
m_ssThresh = std::max (2 * m_segmentSize, BytesInFlight () / 2);
m_cWnd = m_ssThresh + 3 * m_segmentSize;
@@ -163,6 +177,12 @@
m_cWnd += m_segmentSize;
NS_LOG_INFO ("Dupack in fast recovery mode. Increase cwnd to " << m_cWnd);
SendPendingData (m_connected);
+ }
+ else if (!m_inFastRec && m_limitedTx && m_txBuffer.SizeFromSequence (m_nextTxSequence) > 0)
+ { // RFC3042 Limited transmit: Send a new packet for each duplicated ACK before fast retransmit
+ NS_LOG_INFO ("Limited transmit");
+ uint32_t sz = SendDataPacket (m_nextTxSequence, m_segmentSize, true);
+ m_nextTxSequence += sz; // Advance next tx sequence
};
}
@@ -176,8 +196,8 @@
// If erroneous timeout in closed/timed-wait state, just return
if (m_state == CLOSED || m_state == TIME_WAIT) return;
- // If all data are received, just return
- if (m_txBuffer.HeadSequence () >= m_nextTxSequence) return;
+ // If all data are received (non-closing socket and nothing to send), just return
+ if (m_state <= ESTABLISHED && m_txBuffer.HeadSequence () >= m_highTxMark) return;
// According to RFC2581 sec.3.1, upon RTO, ssthresh is set to half of flight
// size and cwnd is set to 1*MSS, then the lost packet is retransmitted and
--- a/src/internet/model/tcp-newreno.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-newreno.h Fri Dec 16 18:51:18 2011 +0100
@@ -69,7 +69,9 @@
uint32_t m_ssThresh; //< Slow Start Threshold
uint32_t m_initialCWnd; //< Initial cWnd value
SequenceNumber32 m_recover; //< Previous highest Tx seqnum for fast recovery
+ uint32_t m_retxThresh; //< Fast Retransmit threshold
bool m_inFastRec; //< currently in fast recovery
+ bool m_limitedTx; //< perform limited transmit
};
} // namespace ns3
--- a/src/internet/model/tcp-reno.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-reno.cc Fri Dec 16 18:51:18 2011 +0100
@@ -40,6 +40,10 @@
static TypeId tid = TypeId ("ns3::TcpReno")
.SetParent<TcpSocketBase> ()
.AddConstructor<TcpReno> ()
+ .AddAttribute ("ReTxThreshold", "Threshold for fast retransmit",
+ UintegerValue (3),
+ MakeUintegerAccessor (&TcpReno::m_retxThresh),
+ MakeUintegerChecker<uint32_t> ())
.AddTraceSource ("CongestionWindow",
"The TCP connection's congestion window",
MakeTraceSourceAccessor (&TcpReno::m_cWnd))
@@ -47,7 +51,7 @@
return tid;
}
-TcpReno::TcpReno (void) : m_inFastRec (false)
+TcpReno::TcpReno (void) : m_retxThresh (3), m_inFastRec (false)
{
NS_LOG_FUNCTION (this);
}
@@ -57,6 +61,7 @@
m_cWnd (sock.m_cWnd),
m_ssThresh (sock.m_ssThresh),
m_initialCWnd (sock.m_initialCWnd),
+ m_retxThresh (sock.m_retxThresh),
m_inFastRec (false)
{
NS_LOG_FUNCTION (this);
@@ -141,7 +146,7 @@
TcpReno::DupAck (const TcpHeader& t, uint32_t count)
{
NS_LOG_FUNCTION (this << "t " << count);
- if (count == 3 && !m_inFastRec)
+ if (count == m_retxThresh && !m_inFastRec)
{ // triple duplicate ack triggers fast retransmit (RFC2581, sec.3.2)
m_ssThresh = std::max (2 * m_segmentSize, BytesInFlight () / 2);
m_cWnd = m_ssThresh + 3 * m_segmentSize;
@@ -166,8 +171,8 @@
// If erroneous timeout in closed/timed-wait state, just return
if (m_state == CLOSED || m_state == TIME_WAIT) return;
- // If all data are received, just return
- if (m_txBuffer.HeadSequence () >= m_nextTxSequence) return;
+ // If all data are received (non-closing socket and nothing to send), just return
+ if (m_state <= ESTABLISHED && m_txBuffer.HeadSequence () >= m_highTxMark) return;
// According to RFC2581 sec.3.1, upon RTO, ssthresh is set to half of flight
// size and cwnd is set to 1*MSS, then the lost packet is retransmitted and
--- a/src/internet/model/tcp-reno.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-reno.h Fri Dec 16 18:51:18 2011 +0100
@@ -70,6 +70,7 @@
TracedValue<uint32_t> m_cWnd; //< Congestion window
uint32_t m_ssThresh; //< Slow Start Threshold
uint32_t m_initialCWnd; //< Initial cWnd value
+ uint32_t m_retxThresh; //< Fast Retransmit threshold
bool m_inFastRec; //< currently in fast recovery
};
--- a/src/internet/model/tcp-rx-buffer.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-rx-buffer.cc Fri Dec 16 18:51:18 2011 +0100
@@ -102,7 +102,7 @@
m_nextRxSeq++;
}
-// Return the highest sequence number that this TcpRxBuffer can accept
+// Return the lowest sequence number that this TcpRxBuffer cannot accept
SequenceNumber32
TcpRxBuffer::MaxRxSequence (void) const
{
--- a/src/internet/model/tcp-socket-base.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-socket-base.cc Fri Dec 16 18:51:18 2011 +0100
@@ -1,5 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
+ * Copyright (c) 2007 Georgia Tech Research Corporation
* Copyright (c) 2010 Adrian Sai-wah Tam
*
* This program is free software; you can redistribute it and/or modify
@@ -33,6 +34,7 @@
#include "ns3/simulator.h"
#include "ns3/packet.h"
#include "ns3/uinteger.h"
+#include "ns3/double.h"
#include "ns3/trace-source-accessor.h"
#include "tcp-socket-base.h"
#include "tcp-l4-protocol.h"
@@ -58,6 +60,15 @@
// EnumValue (CLOSED),
// MakeEnumAccessor (&TcpSocketBase::m_state),
// MakeEnumChecker (CLOSED, "Closed"))
+ .AddAttribute ("MaxSegLifetime",
+ "Maximum segment lifetime in seconds, use for TIME_WAIT state transition to CLOSED state",
+ DoubleValue (120), /* RFC793 says MSL=2 minutes*/
+ MakeDoubleAccessor (&TcpSocketBase::m_msl),
+ MakeDoubleChecker<double> (0))
+ .AddAttribute ("MaxWindowSize", "Max size of advertised window",
+ UintegerValue (65535),
+ MakeUintegerAccessor (&TcpSocketBase::m_maxWinSize),
+ MakeUintegerChecker<uint16_t> ())
.AddTraceSource ("RTO",
"Retransmission timeout",
MakeTraceSourceAccessor (&TcpSocketBase::m_rto))
@@ -109,7 +120,8 @@
m_dupAckCount (sock.m_dupAckCount),
m_delAckCount (0),
m_delAckMaxCount (sock.m_delAckMaxCount),
- m_cnCount (sock.m_cnCount),
+ m_noDelay (sock.m_noDelay),
+ m_cnRetries (sock.m_cnRetries),
m_delAckTimeout (sock.m_delAckTimeout),
m_persistTimeout (sock.m_persistTimeout),
m_cnTimeout (sock.m_cnTimeout),
@@ -128,7 +140,9 @@
m_shutdownSend (sock.m_shutdownSend),
m_shutdownRecv (sock.m_shutdownRecv),
m_connected (sock.m_connected),
+ m_msl (sock.m_msl),
m_segmentSize (sock.m_segmentSize),
+ m_maxWinSize (sock.m_maxWinSize),
m_rWnd (sock.m_rWnd)
{
NS_LOG_FUNCTION (this);
@@ -224,6 +238,7 @@
m_errno = ERROR_ADDRNOTAVAIL;
return -1;
}
+ m_tcp->m_sockets.push_back (this);
return SetupCallback ();
}
@@ -243,39 +258,25 @@
if (ipv4 == Ipv4Address::GetAny () && port == 0)
{
m_endPoint = m_tcp->Allocate ();
- if (0 == m_endPoint)
- {
- m_errno = ERROR_ADDRNOTAVAIL;
- return -1;
- }
}
else if (ipv4 == Ipv4Address::GetAny () && port != 0)
{
m_endPoint = m_tcp->Allocate (port);
- if (0 == m_endPoint)
- {
- m_errno = ERROR_ADDRINUSE;
- return -1;
- }
}
else if (ipv4 != Ipv4Address::GetAny () && port == 0)
{
m_endPoint = m_tcp->Allocate (ipv4);
- if (0 == m_endPoint)
- {
- m_errno = ERROR_ADDRNOTAVAIL;
- return -1;
- }
}
else if (ipv4 != Ipv4Address::GetAny () && port != 0)
{
m_endPoint = m_tcp->Allocate (ipv4, port);
- if (0 == m_endPoint)
- {
- m_errno = ERROR_ADDRINUSE;
- return -1;
- }
}
+ if (0 == m_endPoint)
+ {
+ m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL;
+ return -1;
+ }
+ m_tcp->m_sockets.push_back (this);
NS_LOG_LOGIC ("TcpSocketBase " << this << " got an endpoint: " << m_endPoint);
return SetupCallback ();
@@ -307,6 +308,10 @@
return -1;
}
+ // Re-initialize parameters in case this socket is being reused after CLOSE
+ m_rtt->Reset ();
+ m_cnCount = m_cnRetries;
+
// DoConnect() will do state-checking and send a SYN packet
return DoConnect ();
}
@@ -437,14 +442,14 @@
// Null packet means no data to read, and an empty packet indicates EOF
if (packet != 0 && packet->GetSize () != 0)
{
- SocketAddressTag tag;
- bool found;
- found = packet->PeekPacketTag (tag);
- NS_ASSERT (found);
- //cast found to void , to suppress 'found' set but not used compiler warning
- //in optimized builds
- (void) found;
- fromAddress = tag.GetAddress ();
+ if (m_endPoint != 0)
+ {
+ fromAddress = InetSocketAddress (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPort ());
+ }
+ else
+ {
+ fromAddress = InetSocketAddress (Ipv4Address::GetZero (), 0);
+ }
}
return packet;
}
@@ -531,8 +536,8 @@
else if (m_state != TIME_WAIT)
{ // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, an connection
// exists. We send RST, tear down everything, and close this socket.
+ SendRST ();
CloseAndNotify ();
- SendRST ();
}
return 0;
}
@@ -561,8 +566,8 @@
case SYN_SENT:
case CLOSING:
// Send RST if application closes in SYN_SENT and CLOSING
+ SendRST ();
CloseAndNotify ();
- SendRST ();
break;
case LISTEN:
case LAST_ACK:
@@ -587,30 +592,31 @@
NS_LOG_FUNCTION (this);
if (!m_closeNotified) NotifyNormalClose ();
+ if (m_state != TIME_WAIT) DeallocateEndPoint ();
m_closeNotified = true;
NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSED");
+ CancelAllTimers ();
m_state = CLOSED;
- DeallocateEndPoint ();
}
-/** Tell if a sequence number is out side the range that my rx buffer can
+/** Tell if a sequence number range is out side the range that my rx buffer can
accpet */
bool
-TcpSocketBase::OutOfRange (SequenceNumber32 s) const
+TcpSocketBase::OutOfRange (SequenceNumber32 head, SequenceNumber32 tail) const
{
if (m_state == LISTEN || m_state == SYN_SENT || m_state == SYN_RCVD)
{ // Rx buffer in these states are not initialized.
return false;
}
- if (m_state == LAST_ACK || m_state == CLOSING)
+ if (m_state == LAST_ACK || m_state == CLOSING || m_state == CLOSE_WAIT)
{ // In LAST_ACK and CLOSING states, it only wait for an ACK and the
// sequence number must equals to m_rxBuffer.NextRxSequence ()
- return (m_rxBuffer.NextRxSequence () != s);
+ return (m_rxBuffer.NextRxSequence () != head);
};
// In all other cases, check if the sequence number is in range
- return (m_rxBuffer.MaxRxSequence () < s || m_rxBuffer.NextRxSequence () > s);
+ return (tail < m_rxBuffer.NextRxSequence () || m_rxBuffer.MaxRxSequence () <= head);
}
/** Function called by the L3 protocol when it received a packet to pass on to
@@ -620,6 +626,16 @@
TcpSocketBase::ForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port,
Ptr<Ipv4Interface> incomingInterface)
{
+ DoForwardUp (packet, header, port, incomingInterface);
+}
+
+/** The real function to handle the incoming packet from lower layers. This is
+ wrapped by ForwardUp() so that this function can be overloaded by daughter
+ classes. */
+void
+TcpSocketBase::DoForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port,
+ Ptr<Ipv4Interface> incomingInterface)
+{
NS_LOG_LOGIC ("Socket " << this << " forward up " <<
m_endPoint->GetPeerAddress () <<
":" << m_endPoint->GetPeerPort () <<
@@ -635,6 +651,7 @@
{
EstimateRtt (tcpHeader);
}
+ ReadOptions (tcpHeader);
// Update Rx window size, i.e. the flow control window
if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
@@ -644,13 +661,20 @@
}
m_rWnd = tcpHeader.GetWindowSize ();
- // Discard out of range packets
- if (OutOfRange (tcpHeader.GetSequenceNumber ()))
+ // Discard fully out of range data packets
+ if (packet->GetSize () &&
+ OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
{
NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
- " received packet of seq " << tcpHeader.GetSequenceNumber () <<
- " out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
- m_rxBuffer.MaxRxSequence () << "]");
+ " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
+ ":" << tcpHeader.GetSequenceNumber () + packet->GetSize() <<
+ ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
+ m_rxBuffer.MaxRxSequence () << ")");
+ // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
+ if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
+ {
+ SendEmptyPacket (TcpHeader::ACK);
+ }
return;
}
@@ -670,8 +694,16 @@
case CLOSED:
// Send RST if the incoming packet is not a RST
if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
- {
- SendRST ();
+ { // Since m_endPoint is not configured yet, we cannot use SendRST here
+ TcpHeader h;
+ h.SetFlags (TcpHeader::RST);
+ h.SetSequenceNumber (m_nextTxSequence);
+ h.SetAckNumber (m_rxBuffer.NextRxSequence ());
+ h.SetSourcePort (tcpHeader.GetDestinationPort ());
+ h.SetDestinationPort (tcpHeader.GetSourcePort ());
+ h.SetWindowSize (AdvertisedWindowSize ());
+ AddOptions (h);
+ m_tcp->SendPacket (Create<Packet> (), h, header.GetDestination (), header.GetSource (), m_boundnetdevice);
}
break;
case SYN_SENT:
@@ -733,12 +765,12 @@
}
else
{ // Received RST or the TCP flags is invalid, in either case, terminate this socket
- CloseAndNotify ();
if (tcpflags != TcpHeader::RST)
{ // this must be an invalid flag, send reset
NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
SendRST ();
}
+ CloseAndNotify ();
}
}
@@ -818,6 +850,7 @@
m_state = ESTABLISHED;
m_connected = true;
m_retxEvent.Cancel ();
+ m_delAckCount = m_delAckMaxCount;
ReceivedData (packet, tcpHeader);
Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this);
}
@@ -828,6 +861,7 @@
{ // Received SYN, move to SYN_RCVD state and respond with SYN+ACK
NS_LOG_INFO ("SYN_SENT -> SYN_RCVD");
m_state = SYN_RCVD;
+ m_cnCount = m_cnRetries;
m_rxBuffer.SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
}
@@ -842,21 +876,20 @@
m_highTxMark = ++m_nextTxSequence;
m_txBuffer.SetHeadSequence (m_nextTxSequence);
SendEmptyPacket (TcpHeader::ACK);
- if (GetTxAvailable () > 0)
- {
- NotifySend (GetTxAvailable ());
- }
SendPendingData (m_connected);
Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this);
+ // Always respond to first data packet to speed up the connection.
+ // Remove to get the behaviour of old NS-3 code.
+ m_delAckCount = m_delAckMaxCount;
}
else
{ // Other in-sequence input
- CloseAndNotify ();
if (tcpflags != TcpHeader::RST)
{ // When (1) rx of FIN+ACK; (2) rx of FIN; (3) rx of bad flags
- NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
+ NS_LOG_LOGIC ("Illegal flag " << std::hex << static_cast<uint32_t>(tcpflags) << std::dec << " received. Reset packet is sent.");
SendRST ();
}
+ CloseAndNotify ();
}
}
@@ -882,12 +915,18 @@
m_retxEvent.Cancel ();
m_highTxMark = ++m_nextTxSequence;
m_txBuffer.SetHeadSequence (m_nextTxSequence);
- m_endPoint->SetPeer (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPort ());
+ m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
+ InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
// Always respond to first data packet to speed up the connection.
// Remove to get the behaviour of old NS-3 code.
m_delAckCount = m_delAckMaxCount;
ReceivedAck (packet, tcpHeader);
NotifyNewConnectionCreated (this, fromAddress);
+ // As this connection is established, the socket is available to send data now
+ if (GetTxAvailable () > 0)
+ {
+ NotifySend (GetTxAvailable ());
+ }
}
else if (tcpflags == TcpHeader::SYN)
{ // Probably the peer lost my SYN+ACK
@@ -902,18 +941,21 @@
m_retxEvent.Cancel ();
m_highTxMark = ++m_nextTxSequence;
m_txBuffer.SetHeadSequence (m_nextTxSequence);
- m_endPoint->SetPeer (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPort ());
+ m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
+ InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
PeerClose (packet, tcpHeader);
}
}
else
{ // Other in-sequence input
- CloseAndNotify ();
if (tcpflags != TcpHeader::RST)
{ // When (1) rx of SYN+ACK; (2) rx of FIN; (3) rx of bad flags
NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
+ m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
+ InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
SendRST ();
}
+ CloseAndNotify ();
}
}
@@ -954,12 +996,12 @@
}
else
{ // This is a RST or bad flags
- CloseAndNotify ();
if (tcpflags != TcpHeader::RST)
{
NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
SendRST ();
}
+ CloseAndNotify ();
return;
}
@@ -973,18 +1015,12 @@
if (m_txBuffer.Size () == 0 &&
tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
{ // This ACK corresponds to the FIN sent
- NS_LOG_INFO ("CLOSING -> TIME_WAIT");
- m_state = TIME_WAIT;
- CancelAllTimers ();
+ TimeWait ();
}
}
else if (m_state == FIN_WAIT_2)
{
- NS_LOG_INFO ("FIN_WAIT_2 -> TIME_WAIT");
- m_state = TIME_WAIT;
- CancelAllTimers ();
- // TODO: In TIME_WAIT, we supposed to move to CLOSED after 2*MSL time
- // but this move is not yet implemeneted. Is this necessary?
+ TimeWait ();
};
SendEmptyPacket (TcpHeader::ACK);
if (!m_shutdownRecv) NotifyDataRecv ();
@@ -1004,17 +1040,12 @@
{
if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
{ // This ACK corresponds to the FIN sent
- NS_LOG_INFO ("CLOSING -> TIME_WAIT");
- m_state = TIME_WAIT;
- CancelAllTimers ();
- // TODO: In TIME_WAIT, we supposed to move to CLOSED after 2*MSL time
- // but this move is not yet implemeneted. Is this necessary?
+ TimeWait ();
}
}
else
{ // CLOSING state means simultaneous close, i.e. no one is sending data to
// anyone. If anything other than ACK is received, respond with a reset.
- CloseAndNotify ();
if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
{ // FIN from the peer as well. We can close immediately.
SendEmptyPacket (TcpHeader::ACK);
@@ -1024,6 +1055,7 @@
NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
SendRST ();
}
+ CloseAndNotify ();
}
}
@@ -1057,9 +1089,9 @@
}
else
{ // Received a SYN or SYN+ACK or bad flags
- CloseAndNotify ();
NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
SendRST ();
+ CloseAndNotify ();
}
}
@@ -1119,7 +1151,7 @@
// until all its existing data are pushed into the TCP socket, then call Close()
// explicitly.
NS_LOG_LOGIC ("TCP " << this << " calling NotifyNormalClose");
- if (!m_closeNotified) NotifyNormalClose ();
+ NotifyNormalClose ();
m_closeNotified = true;
}
if (m_shutdownSend)
@@ -1146,6 +1178,12 @@
NS_LOG_FUNCTION (this);
m_node = 0;
m_endPoint = 0;
+ std::vector<Ptr<TcpSocketBase> >::iterator it
+ = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
+ if (it != m_tcp->m_sockets.end ())
+ {
+ m_tcp->m_sockets.erase (it);
+ }
m_tcp = 0;
NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
(Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
@@ -1181,17 +1219,27 @@
header.SetSourcePort (m_endPoint->GetLocalPort ());
header.SetDestinationPort (m_endPoint->GetPeerPort ());
header.SetWindowSize (AdvertisedWindowSize ());
- m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (), m_endPoint->GetPeerAddress (), m_boundnetdevice);
+ AddOptions (header);
m_rto = m_rtt->RetransmitTimeout ();
bool hasSyn = flags & TcpHeader::SYN;
bool hasFin = flags & TcpHeader::FIN;
bool isAck = flags == TcpHeader::ACK;
if (hasSyn)
- { // Exponential backoff of connection time out
- m_rto = m_cnTimeout;
- m_cnTimeout = m_cnTimeout + m_cnTimeout;
- m_cnCount--;
+ {
+ if (m_cnCount == 0)
+ { // No more connection retries, give up
+ NS_LOG_LOGIC ("Connection failed.");
+ CloseAndNotify ();
+ return;
+ }
+ else
+ { // Exponential backoff of connection time out
+ int backoffCount = 0x1 << (m_cnRetries - m_cnCount);
+ m_rto = m_cnTimeout * backoffCount;
+ m_cnCount--;
+ }
}
+ m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (), m_endPoint->GetPeerAddress (), m_boundnetdevice);
if (flags & TcpHeader::ACK)
{ // If sending an ACK, cancel the delay ACK as well
m_delAckEvent.Cancel ();
@@ -1216,7 +1264,7 @@
DeallocateEndPoint ();
}
-/** Deallocate the end point the cancel all the timers */
+/** Deallocate the end point and cancel all the timers */
void
TcpSocketBase::DeallocateEndPoint (void)
{
@@ -1225,6 +1273,12 @@
m_endPoint->SetDestroyCallback (MakeNullCallback<void> ());
m_tcp->DeAllocate (m_endPoint);
m_endPoint = 0;
+ std::vector<Ptr<TcpSocketBase> >::iterator it
+ = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
+ if (it != m_tcp->m_sockets.end ())
+ {
+ m_tcp->m_sockets.erase (it);
+ }
CancelAllTimers ();
}
}
@@ -1272,10 +1326,12 @@
InetSocketAddress::ConvertFrom (toAddress).GetPort (),
InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
+ m_tcp->m_sockets.push_back (this);
// Change the cloned socket from LISTEN state to SYN_RCVD
NS_LOG_INFO ("LISTEN -> SYN_RCVD");
m_state = SYN_RCVD;
+ m_cnCount = m_cnRetries;
SetupCallback ();
// Set the sequence number and send SYN+ACK
m_rxBuffer.SetNextRxSequence (h.GetSequenceNumber () + SequenceNumber32 (1));
@@ -1287,10 +1343,73 @@
{ // Wrapper to protected function NotifyConnectionSucceeded() so that it can
// be called as a scheduled event
NotifyConnectionSucceeded ();
+ // The if-block below was moved from ProcessSynSent() to here because we need
+ // to invoke the NotifySend() only after NotifyConnectionSucceeded() to
+ // reflect the behaviour in the real world.
+ if (GetTxAvailable () > 0)
+ {
+ NotifySend (GetTxAvailable ());
+ }
}
-// Send as much pending data as possible according to the Tx window. Note that
-// this function did not implement the PSH flag
+/** Extract at most maxSize bytes from the TxBuffer at sequence seq, add the
+ TCP header, and send to TcpL4Protocol */
+uint32_t
+TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck)
+{
+ NS_LOG_FUNCTION (this << seq << maxSize << withAck);
+
+ Ptr<Packet> p = m_txBuffer.CopyFromSequence (maxSize, seq);
+ uint32_t sz = p->GetSize (); // Size of packet
+ uint8_t flags = withAck ? TcpHeader::ACK : 0;
+ uint32_t remainingData = m_txBuffer.SizeFromSequence (seq + SequenceNumber32 (sz));
+ if (m_closeOnEmpty && (remainingData == 0))
+ {
+ flags |= TcpHeader::FIN;
+ if (m_state == ESTABLISHED)
+ { // On active close: I am the first one to send FIN
+ NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
+ m_state = FIN_WAIT_1;
+ }
+ else if (m_state == CLOSE_WAIT)
+ { // On passive close: Peer sent me FIN already
+ NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
+ m_state = LAST_ACK;
+ }
+ }
+ TcpHeader header;
+ header.SetFlags (flags);
+ header.SetSequenceNumber (seq);
+ header.SetAckNumber (m_rxBuffer.NextRxSequence ());
+ header.SetSourcePort (m_endPoint->GetLocalPort ());
+ header.SetDestinationPort (m_endPoint->GetPeerPort ());
+ header.SetWindowSize (AdvertisedWindowSize ());
+ AddOptions (header);
+ if (m_retxEvent.IsExpired () )
+ { // Schedule retransmit
+ m_rto = m_rtt->RetransmitTimeout ();
+ NS_LOG_LOGIC (this << " SendDataPacket Schedule ReTxTimeout at time " <<
+ Simulator::Now ().GetSeconds () << " to expire at time " <<
+ (Simulator::Now () + m_rto.Get ()).GetSeconds () );
+ m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::ReTxTimeout, this);
+ }
+ NS_LOG_LOGIC ("Send packet via TcpL4Protocol with flags 0x" << std::hex << static_cast<uint32_t> (flags) << std::dec);
+ m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
+ m_endPoint->GetPeerAddress (), m_boundnetdevice);
+ m_rtt->SentSeq (seq, sz); // notify the RTT
+ // Notify the application of the data being sent unless this is a retransmit
+ if (seq == m_nextTxSequence)
+ {
+ Simulator::ScheduleNow (&TcpSocketBase::NotifyDataSent, this, sz);
+ }
+ // Update highTxMark
+ m_highTxMark = std::max (seq + sz, m_highTxMark.Get ());
+ return sz;
+}
+
+/** Send as much pending data as possible according to the Tx window. Note that
+ * this function did not implement the PSH flag
+ */
bool
TcpSocketBase::SendPendingData (bool withAck)
{
@@ -1324,57 +1443,18 @@
{
break; // No more
}
- uint32_t s = std::min (w, m_segmentSize); // Send no more than window
- Ptr<Packet> p = m_txBuffer.CopyFromSequence (s, m_nextTxSequence);
- NS_LOG_LOGIC ("TcpSocketBase " << this << " SendPendingData" <<
- " txseq " << m_nextTxSequence <<
- " s " << s << " datasize " << p->GetSize ());
- uint8_t flags = 0;
- uint32_t sz = p->GetSize (); // Size of packet
- uint32_t remainingData = m_txBuffer.SizeFromSequence (m_nextTxSequence + SequenceNumber32 (sz));
- if (m_closeOnEmpty && (remainingData == 0))
- {
- flags = TcpHeader::FIN;
- if (m_state == ESTABLISHED)
- { // On active close: I am the first one to send FIN
- NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
- m_state = FIN_WAIT_1;
- }
- else
- { // On passive close: Peer sent me FIN already
- NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
- m_state = LAST_ACK;
- }
- }
- if (withAck)
+ // Nagle's algorithm (RFC896): Hold off sending if there is unacked data
+ // in the buffer and the amount of data to send is less than one segment
+ if (!m_noDelay && UnAckDataCount () > 0 &&
+ m_txBuffer.SizeFromSequence (m_nextTxSequence) < m_segmentSize)
{
- flags |= TcpHeader::ACK;
+ NS_LOG_LOGIC ("Invoking Nagle's algorithm. Wait to send.");
+ break;
}
- TcpHeader header;
- header.SetFlags (flags);
- header.SetSequenceNumber (m_nextTxSequence);
- header.SetAckNumber (m_rxBuffer.NextRxSequence ());
- header.SetSourcePort (m_endPoint->GetLocalPort ());
- header.SetDestinationPort (m_endPoint->GetPeerPort ());
- header.SetWindowSize (AdvertisedWindowSize ());
- if (m_retxEvent.IsExpired () )
- { // Schedule retransmit
- m_rto = m_rtt->RetransmitTimeout ();
- NS_LOG_LOGIC (this << " SendPendingData Schedule ReTxTimeout at time " <<
- Simulator::Now ().GetSeconds () << " to expire at time " <<
- (Simulator::Now () + m_rto.Get ()).GetSeconds () );
- m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::ReTxTimeout, this);
- }
- NS_LOG_LOGIC ("Send packet via TcpL4Protocol with flags 0x" << std::hex << static_cast<uint32_t> (flags) << std::dec);
- m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
- m_endPoint->GetPeerAddress (), m_boundnetdevice);
- m_rtt->SentSeq (m_nextTxSequence, sz); // notify the RTT
- // Notify the application of the data being sent
- Simulator::ScheduleNow (&TcpSocketBase::NotifyDataSent, this, sz);
+ uint32_t s = std::min (w, m_segmentSize); // Send no more than window
+ uint32_t sz = SendDataPacket (m_nextTxSequence, s, withAck);
nPacketsSent++; // Count sent this loop
m_nextTxSequence += sz; // Advance next tx sequence
- // Update highTxMark
- m_highTxMark = std::max (m_nextTxSequence, m_highTxMark);
}
NS_LOG_LOGIC ("SendPendingData sent " << nPacketsSent << " packets");
return (nPacketsSent > 0);
@@ -1414,8 +1494,7 @@
uint16_t
TcpSocketBase::AdvertisedWindowSize ()
{
- uint32_t max = 0xffff;
- return std::min (m_rxBuffer.MaxBufferSize () - m_rxBuffer.Size (), max);
+ return std::min (m_rxBuffer.MaxBufferSize () - m_rxBuffer.Size (), (uint32_t)m_maxWinSize);
}
// Receipt of new packet, put into Rx buffer
@@ -1435,8 +1514,8 @@
return;
}
// Now send a new ACK packet acknowledging all received and delivered data
- if (tcpHeader.GetSequenceNumber () > expectedSeq)
- { // Out of sequence packet: Always ACK
+ if (m_rxBuffer.Size () > m_rxBuffer.Available () || m_rxBuffer.NextRxSequence () > expectedSeq + p->GetSize ())
+ { // A gap exists in the buffer, or we filled a gap: Always ACK
SendEmptyPacket (TcpHeader::ACK);
}
else
@@ -1451,6 +1530,7 @@
{
m_delAckEvent = Simulator::Schedule (m_delAckTimeout,
&TcpSocketBase::DelAckTimeout, this);
+ NS_LOG_LOGIC (this << " scheduled delayed ACK at " << (Simulator::Now () + Simulator::GetDelayLeft (m_delAckEvent)).GetSeconds ());
}
}
// Notify app to receive if necessary
@@ -1478,7 +1558,7 @@
// Use m_rtt for the estimation. Note, RTT of duplicated acknowledgement
// (which should be ignored) is handled by m_rtt. Once timestamp option
// is implemented, this function would be more elaborated.
- m_rtt->AckSeq (tcpHeader.GetAckNumber () );
+ m_lastRtt = m_rtt->AckSeq (tcpHeader.GetAckNumber () );
};
// Called by the ReceivedAck() when new ACK received and by ProcessSynRcvd()
@@ -1543,8 +1623,8 @@
NS_LOG_LOGIC (this << " ReTxTimeout Expired at time " << Simulator::Now ().GetSeconds ());
// If erroneous timeout in closed/timed-wait state, just return
if (m_state == CLOSED || m_state == TIME_WAIT) return;
- // If all data are received, just return
- if (m_state <= ESTABLISHED && m_txBuffer.HeadSequence () >= m_nextTxSequence) return;
+ // If all data are received (non-closing socket and nothing to send), just return
+ if (m_state <= ESTABLISHED && m_txBuffer.HeadSequence () >= m_highTxMark) return;
Retransmit ();
}
@@ -1587,6 +1667,7 @@
tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ());
tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
tcpHeader.SetWindowSize (AdvertisedWindowSize ());
+ AddOptions (tcpHeader);
m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
m_endPoint->GetPeerAddress (), m_boundnetdevice);
@@ -1609,7 +1690,6 @@
TcpSocketBase::DoRetransmit ()
{
NS_LOG_FUNCTION (this);
- uint8_t flags = TcpHeader::ACK;
// Retransmit SYN packet
if (m_state == SYN_SENT)
{
@@ -1632,35 +1712,12 @@
}
return;
}
- // Retransmit a data packet: Extract data
- Ptr<Packet> p = m_txBuffer.CopyFromSequence (m_segmentSize, m_txBuffer.HeadSequence ());
- // Close-on-Empty check
- if (m_closeOnEmpty && m_txBuffer.Size () == p->GetSize ())
- {
- flags |= TcpHeader::FIN;
- }
- // Reset transmission timeout
+ // Retransmit a data packet: Call SendDataPacket
NS_LOG_LOGIC ("TcpSocketBase " << this << " retxing seq " << m_txBuffer.HeadSequence ());
- if (m_retxEvent.IsExpired ())
- {
- m_rto = m_rtt->RetransmitTimeout ();
- NS_LOG_LOGIC (this << " Schedule ReTxTimeout at time " <<
- Simulator::Now ().GetSeconds () << " to expire at time " <<
- (Simulator::Now () + m_rto.Get ()).GetSeconds ());
- m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::ReTxTimeout, this);
- }
- m_rtt->SentSeq (m_txBuffer.HeadSequence (), p->GetSize ());
- // And send the packet
- TcpHeader tcpHeader;
- tcpHeader.SetSequenceNumber (m_txBuffer.HeadSequence ());
- tcpHeader.SetAckNumber (m_rxBuffer.NextRxSequence ());
- tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ());
- tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
- tcpHeader.SetFlags (flags);
- tcpHeader.SetWindowSize (AdvertisedWindowSize ());
+ uint32_t sz = SendDataPacket (m_txBuffer.HeadSequence (), m_segmentSize, true);
+ // In case of RTO, advance m_nextTxSequence
+ m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer.HeadSequence () + sz);
- m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
- m_endPoint->GetPeerAddress (), m_boundnetdevice);
}
void
@@ -1670,6 +1727,20 @@
m_persistEvent.Cancel ();
m_delAckEvent.Cancel ();
m_lastAckEvent.Cancel ();
+ m_timewaitEvent.Cancel ();
+}
+
+/** Move TCP to Time_Wait state and schedule a transition to Closed state */
+void
+TcpSocketBase::TimeWait ()
+{
+ NS_LOG_INFO (TcpStateName[m_state] << " -> TIME_WAIT");
+ m_state = TIME_WAIT;
+ CancelAllTimers ();
+ // Move from TIME_WAIT to CLOSED after 2*MSL. Max segment lifetime is 2 min
+ // according to RFC793, p.28
+ m_timewaitEvent = Simulator::Schedule (Seconds (2*m_msl),
+ &TcpSocketBase::CloseAndNotify, this);
}
/** Below are the attribute get/set functions */
@@ -1726,13 +1797,13 @@
void
TcpSocketBase::SetConnCount (uint32_t count)
{
- m_cnCount = count;
+ m_cnRetries = count;
}
uint32_t
TcpSocketBase::GetConnCount (void) const
{
- return m_cnCount;
+ return m_cnRetries;
}
void
@@ -1760,6 +1831,18 @@
}
void
+TcpSocketBase::SetTcpNoDelay (bool noDelay)
+{
+ m_noDelay = noDelay;
+}
+
+bool
+TcpSocketBase::GetTcpNoDelay (void) const
+{
+ return m_noDelay;
+}
+
+void
TcpSocketBase::SetPersistTimeout (Time timeout)
{
m_persistTimeout = timeout;
@@ -1779,9 +1862,21 @@
}
bool
-TcpSocketBase::GetAllowBroadcast () const
+TcpSocketBase::GetAllowBroadcast (void) const
{
return false;
}
+/** Placeholder function for future extension that reads more from the TCP header */
+void
+TcpSocketBase::ReadOptions (const TcpHeader&)
+{
+}
+
+/** Placeholder function for future extension that changes the TCP header */
+void
+TcpSocketBase::AddOptions (TcpHeader&)
+{
+}
+
} // namespace ns3
--- a/src/internet/model/tcp-socket-base.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-socket-base.h Fri Dec 16 18:51:18 2011 +0100
@@ -1,5 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
+ * Copyright (c) 2007 Georgia Tech Research Corporation
* Copyright (c) 2010 Adrian Sai-wah Tam
*
* This program is free software; you can redistribute it and/or modify
@@ -53,7 +54,7 @@
* functions where the sliding window mechanism is handled here. This class
* provides connection orientation and sliding window flow control. Part of
* this class is modified from the original NS-3 TCP socket implementation
- * (TcpSocketImpl) by Raj Bhattacharjea.
+ * (TcpSocketImpl) by Raj Bhattacharjea <raj.b@gatech.edu> of Georgia Tech.
*/
class TcpSocketBase : public TcpSocket
{
@@ -115,10 +116,12 @@
virtual Time GetDelAckTimeout (void) const;
virtual void SetDelAckMaxCount (uint32_t count);
virtual uint32_t GetDelAckMaxCount (void) const;
+ virtual void SetTcpNoDelay (bool noDelay);
+ virtual bool GetTcpNoDelay (void) const;
virtual void SetPersistTimeout (Time timeout);
virtual Time GetPersistTimeout (void) const;
virtual bool SetAllowBroadcast (bool allowBroadcast);
- virtual bool GetAllowBroadcast () const;
+ virtual bool GetAllowBroadcast (void) const;
// Helper functions: Connection set up
int SetupCallback (void); // Common part of the two Bind(), i.e. set callback and remembering local addr:port
@@ -128,11 +131,13 @@
void CompleteFork (Ptr<Packet>, const TcpHeader&, const Address& fromAddress, const Address& toAdress);
// Helper functions: Transfer operation
- void ForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port, Ptr<Ipv4Interface> incomingInterface); //Get a pkt from L3
+ void ForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port, Ptr<Ipv4Interface> incomingInterface);
+ virtual void DoForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port, Ptr<Ipv4Interface> incomingInterface); //Get a pkt from L3
bool SendPendingData (bool withAck = false); // Send as much as the window allows
+ uint32_t SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck); // Send a data packet
void SendEmptyPacket (uint8_t flags); // Send a empty packet that carries a flag, e.g. ACK
void SendRST (void); // Send reset and tear down this socket
- bool OutOfRange (SequenceNumber32 s) const; // Check if a sequence number is within rx window
+ bool OutOfRange (SequenceNumber32 head, SequenceNumber32 tail) const; // Check if a sequence number range is within the rx window
// Helper functions: Connection close
int DoClose (void); // Close a socket by sending RST, FIN, or FIN+ACK, depend on the current state
@@ -142,6 +147,7 @@
void PeerClose (Ptr<Packet>, const TcpHeader&); // Received a FIN from peer, notify rx buffer
void DoPeerClose (void); // FIN is in sequence, notify app and respond with a FIN
void CancelAllTimers (void); // Cancel all timer when endpoint is deleted
+ void TimeWait (void); // Move from CLOSING or FIN_WAIT_2 to TIME_WAIT state
// State transition functions
void ProcessEstablished (Ptr<Packet>, const TcpHeader&); // Received a packet upon ESTABLISHED state
@@ -172,6 +178,8 @@
virtual void LastAckTimeout (void); // Timeout at LAST_ACK, close the connection
virtual void PersistTimeout (void); // Send 1 byte probe to get an updated window size
virtual void DoRetransmit (void); // Retransmit the oldest packet
+ virtual void ReadOptions (const TcpHeader&); // Read option from incoming packets
+ virtual void AddOptions (TcpHeader&); // Add option to outgoing packets
protected:
// Counters and events
@@ -179,10 +187,13 @@
EventId m_lastAckEvent; //< Last ACK timeout event
EventId m_delAckEvent; //< Delayed ACK timeout event
EventId m_persistEvent; //< Persist event: Send 1 byte to probe for a non-zero Rx window
+ EventId m_timewaitEvent; //< TIME_WAIT expiration event: Move this socket to CLOSED state
uint32_t m_dupAckCount; //< Dupack counter
uint32_t m_delAckCount; //< Delayed ACK counter
uint32_t m_delAckMaxCount; //< Number of packet to fire an ACK before delay timeout
+ bool m_noDelay; //< Set to true to disable Nagle's algorithm
uint32_t m_cnCount; //< Count of remaining connection retries
+ uint32_t m_cnRetries; //< Number of connection retries before giving up
TracedValue<Time> m_rto; //< Retransmit timeout
TracedValue<Time> m_lastRtt; //< Last RTT sample collected
Time m_delAckTimeout; //< Time to delay an ACK
@@ -211,9 +222,11 @@
bool m_shutdownSend; //< Send no longer allowed
bool m_shutdownRecv; //< Receive no longer allowed
bool m_connected; //< Connection established
+ double m_msl; //< Max segment lifetime
// Window management
uint32_t m_segmentSize; //< Segment size
+ uint16_t m_maxWinSize; //< Maximum window size to advertise
TracedValue<uint32_t> m_rWnd; //< Flow control window at remote side
};
--- a/src/internet/model/tcp-socket.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-socket.cc Fri Dec 16 18:51:18 2011 +0100
@@ -22,6 +22,7 @@
#include "ns3/log.h"
#include "ns3/uinteger.h"
#include "ns3/double.h"
+#include "ns3/boolean.h"
#include "ns3/trace-source-accessor.h"
#include "ns3/nstime.h"
#include "tcp-socket.h"
@@ -93,6 +94,11 @@
MakeUintegerAccessor (&TcpSocket::GetDelAckMaxCount,
&TcpSocket::SetDelAckMaxCount),
MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("TcpNoDelay", "Set to true to disable Nagle's algorithm",
+ BooleanValue (true),
+ MakeBooleanAccessor (&TcpSocket::GetTcpNoDelay,
+ &TcpSocket::SetTcpNoDelay),
+ MakeBooleanChecker ())
.AddAttribute ("PersistTimeout",
"Persist timeout to probe for rx window",
TimeValue (Seconds (6)),
--- a/src/internet/model/tcp-socket.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-socket.h Fri Dec 16 18:51:18 2011 +0100
@@ -90,6 +90,8 @@
virtual Time GetDelAckTimeout (void) const = 0;
virtual void SetDelAckMaxCount (uint32_t count) = 0;
virtual uint32_t GetDelAckMaxCount (void) const = 0;
+ virtual void SetTcpNoDelay (bool noDelay) = 0;
+ virtual bool GetTcpNoDelay (void) const = 0;
virtual void SetPersistTimeout (Time timeout) = 0;
virtual Time GetPersistTimeout (void) const = 0;
--- a/src/internet/model/tcp-tahoe.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-tahoe.cc Fri Dec 16 18:51:18 2011 +0100
@@ -40,6 +40,10 @@
static TypeId tid = TypeId ("ns3::TcpTahoe")
.SetParent<TcpSocketBase> ()
.AddConstructor<TcpTahoe> ()
+ .AddAttribute ("ReTxThreshold", "Threshold for fast retransmit",
+ UintegerValue (3),
+ MakeUintegerAccessor (&TcpTahoe::m_retxThresh),
+ MakeUintegerChecker<uint32_t> ())
.AddTraceSource ("CongestionWindow",
"The TCP connection's congestion window",
MakeTraceSourceAccessor (&TcpTahoe::m_cWnd))
@@ -47,7 +51,7 @@
return tid;
}
-TcpTahoe::TcpTahoe (void) : m_initialCWnd (0)
+TcpTahoe::TcpTahoe (void) : m_initialCWnd (1), m_retxThresh (3)
{
NS_LOG_FUNCTION (this);
}
@@ -56,7 +60,8 @@
: TcpSocketBase (sock),
m_cWnd (sock.m_cWnd),
m_ssThresh (sock.m_ssThresh),
- m_initialCWnd (sock.m_initialCWnd)
+ m_initialCWnd (sock.m_initialCWnd),
+ m_retxThresh (sock.m_retxThresh)
{
NS_LOG_FUNCTION (this);
NS_LOG_LOGIC ("Invoked the copy constructor");
@@ -127,7 +132,7 @@
TcpTahoe::DupAck (const TcpHeader& t, uint32_t count)
{
NS_LOG_FUNCTION (this << "t " << count);
- if (count == 3)
+ if (count == m_retxThresh)
{ // triple duplicate ack triggers fast retransmit (RFC2001, sec.3)
NS_LOG_INFO ("Triple Dup Ack: old ssthresh " << m_ssThresh << " cwnd " << m_cWnd);
// fast retransmit in Tahoe means triggering RTO earlier. Tx is restarted
@@ -149,8 +154,8 @@
NS_LOG_LOGIC (this << " ReTxTimeout Expired at time " << Simulator::Now ().GetSeconds ());
// If erroneous timeout in closed/timed-wait state, just return
if (m_state == CLOSED || m_state == TIME_WAIT) return;
- // If all data are received, just return
- if (m_txBuffer.HeadSequence () >= m_nextTxSequence) return;
+ // If all data are received (non-closing socket and nothing to send), just return
+ if (m_state <= ESTABLISHED && m_txBuffer.HeadSequence () >= m_highTxMark) return;
m_ssThresh = std::max (static_cast<unsigned> (m_cWnd / 2), m_segmentSize * 2); // Half ssthresh
m_cWnd = m_segmentSize; // Set cwnd to 1 segSize (RFC2001, sec.2)
--- a/src/internet/model/tcp-tahoe.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/tcp-tahoe.h Fri Dec 16 18:51:18 2011 +0100
@@ -74,6 +74,7 @@
TracedValue<uint32_t> m_cWnd; //< Congestion window
uint32_t m_ssThresh; //< Slow Start Threshold
uint32_t m_initialCWnd; //< Initial cWnd value
+ uint32_t m_retxThresh; //< Fast Retransmit threshold
};
} // namespace ns3
--- a/src/internet/model/udp-socket-impl.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/model/udp-socket-impl.cc Fri Dec 16 18:51:18 2011 +0100
@@ -84,7 +84,7 @@
* when DeAllocate is called, it will call into
* Ipv4EndPointDemux::Deallocate which triggers
* a delete of the associated endPoint which triggers
- * in turn a call to the method ::Destroy below
+ * in turn a call to the method UdpSocketImpl::Destroy below
* will will zero the m_endPoint field.
*/
NS_ASSERT (m_endPoint != 0);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet/test/ipv6-address-generator-test-suite.cc Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,291 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 University of Washington
+ * Copyright (c) 2011 Atishay Jain
+ *
+ * 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
+ */
+
+#include "ns3/test.h"
+#include "ns3/ipv6-address-generator.h"
+#include "ns3/simulation-singleton.h"
+
+namespace ns3 {
+
+class NetworkNumber6AllocatorTestCase : public TestCase
+{
+public:
+ NetworkNumber6AllocatorTestCase ();
+ virtual void DoRun (void);
+ virtual void DoTeardown (void);
+};
+
+NetworkNumber6AllocatorTestCase::NetworkNumber6AllocatorTestCase ()
+ : TestCase ("Make sure the network number allocator is working on some of network prefixes.")
+{
+}
+void
+NetworkNumber6AllocatorTestCase::DoTeardown (void)
+{
+ Ipv6AddressGenerator::Reset ();
+}
+void
+NetworkNumber6AllocatorTestCase::DoRun (void)
+{
+ Ipv6Address network;
+
+ Ipv6AddressGenerator::Init (Ipv6Address ("1::0:0:0"), Ipv6Prefix ("FFFF::0"),
+ Ipv6Address ("::"));
+ network = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix ("FFFF::0"));
+ NS_TEST_EXPECT_MSG_EQ (network, Ipv6Address ("1::0:0:0"), "network should equal the initialized network for given prefix");
+ network = Ipv6AddressGenerator::NextNetwork (Ipv6Prefix ("FFFF::0"));
+ NS_TEST_EXPECT_MSG_EQ (network, Ipv6Address ("2::0:0:0"), "network should equal next network");
+
+ Ipv6AddressGenerator::Init (Ipv6Address ("0:1::0:0"),
+ Ipv6Prefix ("FFFF:FFFF::0"), Ipv6Address ("::"));
+ network = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix ("FFFF:FFFF::0"));
+ NS_TEST_EXPECT_MSG_EQ (network, Ipv6Address ("0:1::0"), "network should equal the initialized network for given prefix");
+ network = Ipv6AddressGenerator::NextNetwork (Ipv6Prefix ("FFFF:FFFF::0"));
+ NS_TEST_EXPECT_MSG_EQ (network, Ipv6Address ("0:2::0"), "network should equal next network");
+
+ Ipv6AddressGenerator::Init (Ipv6Address ("0:0:1::0"),
+ Ipv6Prefix ("FFFF:FFFF:FFFF::0"), Ipv6Address ("::0"));
+ network = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix ("FFFF:FFFF:FFFF::0"));
+ NS_TEST_EXPECT_MSG_EQ (network, Ipv6Address ("0:0:1::0"), "network should equal the initialized network for given prefix");
+ network = Ipv6AddressGenerator::NextNetwork (Ipv6Prefix ("FFFF:FFFF:FFFF::0"));
+ NS_TEST_EXPECT_MSG_EQ (network, Ipv6Address ("0:0:2::0"), "network should equal next network");
+
+}
+
+class AddressAllocator6TestCase : public TestCase
+{
+public:
+ AddressAllocator6TestCase ();
+private:
+ virtual void DoRun (void);
+ virtual void DoTeardown (void);
+};
+
+AddressAllocator6TestCase::AddressAllocator6TestCase ()
+ : TestCase ("Sanity check on allocation of addresses")
+{
+}
+
+void
+AddressAllocator6TestCase::DoRun (void)
+{
+ Ipv6Address address;
+
+ Ipv6AddressGenerator::Init (Ipv6Address ("2001::0"), Ipv6Prefix (64));
+ address = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix (64));
+ NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001::0"), "address should equal the initialized address for given prefix");
+ Ipv6AddressGenerator::NextNetwork (Ipv6Prefix (64));
+ address = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix (64));
+ NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001:0:0:1::0"), "address should equal the initialized address for given prefix");
+ address = Ipv6AddressGenerator::GetAddress (Ipv6Prefix (64));
+ NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001:0:0:1::1"), "address should equal the initialized address for given prefix");
+ address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (64));
+ NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001:0:0:1::1"), "address should equal the initialized address for given prefix");
+ address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (64));
+ NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001:0:0:1::2"), "address should equal the initialized address for given prefix");
+
+ Ipv6AddressGenerator::Init (Ipv6Address ("1::"), Ipv6Prefix ("FFFF::"),
+ Ipv6Address ("::3"));
+ address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (16));
+ NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("1::3"), "address should equal initialized address for given prefix");
+ address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (16));
+ NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("1::4"), "address should equal next address");
+
+}
+
+void
+AddressAllocator6TestCase::DoTeardown (void)
+{
+ Ipv6AddressGenerator::Reset ();
+ Simulator::Destroy ();
+}
+
+
+class NetworkAndAddress6TestCase : public TestCase
+{
+public:
+ NetworkAndAddress6TestCase ();
+ virtual void DoRun (void);
+ virtual void DoTeardown (void);
+};
+
+NetworkAndAddress6TestCase::NetworkAndAddress6TestCase ()
+ : TestCase ("Make sure Network and address allocation play together.")
+{
+}
+
+void
+NetworkAndAddress6TestCase::DoTeardown (void)
+{
+ Ipv6AddressGenerator::Reset ();
+ Simulator::Destroy ();
+}
+
+void
+NetworkAndAddress6TestCase::DoRun (void)
+{
+ Ipv6Address address;
+ Ipv6Address network;
+
+ Ipv6AddressGenerator::Init (Ipv6Address ("3::"), Ipv6Prefix ("FFFF::"),
+ Ipv6Address ("::3"));
+ address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (16));
+ NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("3::3"), "address should equal initialized address for given prefix");
+ address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (16));
+ NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("3::4"), "address should equal next address for given prefix");
+
+ network = Ipv6AddressGenerator::NextNetwork (Ipv6Prefix ("FFFF::"));
+ NS_TEST_EXPECT_MSG_EQ (network, Ipv6Address ("4::0"), "address should equal next address for given prefix");
+ address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (16));
+ NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("4::3"), "address should equal next address for given prefix");
+
+}
+
+class ExampleAddress6GeneratorTestCase : public TestCase
+{
+public:
+ ExampleAddress6GeneratorTestCase ();
+private:
+ virtual void DoRun (void);
+ virtual void DoTeardown (void);
+};
+
+ExampleAddress6GeneratorTestCase::ExampleAddress6GeneratorTestCase ()
+ : TestCase ("A typical real-world example")
+{
+}
+
+void
+ExampleAddress6GeneratorTestCase::DoTeardown (void)
+{
+ Ipv6AddressGenerator::Reset ();
+}
+
+void
+ExampleAddress6GeneratorTestCase::DoRun (void)
+{
+ Ipv6Address address;
+
+ Ipv6AddressGenerator::Init (Ipv6Address ("2001:0AB8::"),
+ Ipv6Prefix ("FFFF:FFFF:FFFF::0"), Ipv6Address ("::3"));
+ address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (48));
+ NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001:0AB8::0:3"), "address should equal initialized address for given prefix");
+ address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (48));
+ NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001:0AB8::0:4"), "address should equal next address for given prefix");
+ address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (48));
+ NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001:0AB8::0:5"), "address should equal next address for given prefix");
+ //
+ // Allocate the next network based on the prefix passed in, which should
+ // be 2001:0AB0:0001
+ //
+ Ipv6AddressGenerator::NextNetwork (Ipv6Prefix ("FFFF:FFFF:FFFF::0"));
+ //
+ // reset first address to be allocated back to ::0:3
+ //
+ Ipv6AddressGenerator::InitAddress (Ipv6Address ("::3"),
+ Ipv6Prefix (48));
+ //
+ // The first address we should get is the network and address ORed
+ //
+ address = Ipv6AddressGenerator::NextAddress (Ipv6Prefix (48));
+ NS_TEST_EXPECT_MSG_EQ (address, Ipv6Address ("2001:0AB8:1::3"), "address should equal initialized address for given prefix");
+}
+
+class AddressCollision6TestCase : public TestCase
+{
+public:
+ AddressCollision6TestCase ();
+private:
+ void DoRun (void);
+ void DoTeardown (void);
+};
+
+AddressCollision6TestCase::AddressCollision6TestCase ()
+ : TestCase ("Make sure that the address collision logic works.")
+{
+}
+
+void
+AddressCollision6TestCase::DoTeardown (void)
+{
+ Ipv6AddressGenerator::Reset ();
+ Simulator::Destroy ();
+}
+void
+AddressCollision6TestCase::DoRun (void)
+{
+ Ipv6AddressGenerator::AddAllocated ("0::0:5");
+ Ipv6AddressGenerator::AddAllocated ("0::0:10");
+ Ipv6AddressGenerator::AddAllocated ("0::0:15");
+ Ipv6AddressGenerator::AddAllocated ("0::0:20");
+
+ Ipv6AddressGenerator::AddAllocated ("0::0:4");
+ Ipv6AddressGenerator::AddAllocated ("0::0:3");
+ Ipv6AddressGenerator::AddAllocated ("0::0:2");
+ Ipv6AddressGenerator::AddAllocated ("0::0:1");
+
+ Ipv6AddressGenerator::AddAllocated ("0::0:6");
+ Ipv6AddressGenerator::AddAllocated ("0::0:7");
+ Ipv6AddressGenerator::AddAllocated ("0::0:8");
+ Ipv6AddressGenerator::AddAllocated ("0::0:9");
+
+ Ipv6AddressGenerator::AddAllocated ("0::0:11");
+ Ipv6AddressGenerator::AddAllocated ("0::0:12");
+ Ipv6AddressGenerator::AddAllocated ("0::0:13");
+ Ipv6AddressGenerator::AddAllocated ("0::0:14");
+
+ Ipv6AddressGenerator::AddAllocated ("0::0:19");
+ Ipv6AddressGenerator::AddAllocated ("0::0:18");
+ Ipv6AddressGenerator::AddAllocated ("0::0:17");
+ Ipv6AddressGenerator::AddAllocated ("0::0:16");
+
+ Ipv6AddressGenerator::TestMode ();
+ bool added = Ipv6AddressGenerator::AddAllocated ("0::0:21");
+ NS_TEST_EXPECT_MSG_EQ (added, true, "address should get allocated");
+
+ added = Ipv6AddressGenerator::AddAllocated ("0::0:4");
+ NS_TEST_EXPECT_MSG_EQ (added, false, "address should not get allocated");
+
+ added = Ipv6AddressGenerator::AddAllocated ("0::0:9");
+ NS_TEST_EXPECT_MSG_EQ (added, false, "address should not get allocated");
+
+ added = Ipv6AddressGenerator::AddAllocated ("0::0:16");
+ NS_TEST_EXPECT_MSG_EQ (added, false, "address should not get allocated");
+
+ added = Ipv6AddressGenerator::AddAllocated ("0::0:21");
+ NS_TEST_EXPECT_MSG_EQ (added, false, "address should not get allocated");
+}
+
+
+static class Ipv6AddressGeneratorTestSuite : public TestSuite
+{
+public:
+ Ipv6AddressGeneratorTestSuite ()
+ : TestSuite ("ipv6-address-generator")
+ {
+ AddTestCase (new NetworkNumber6AllocatorTestCase ());
+ AddTestCase (new AddressAllocator6TestCase ());
+ AddTestCase (new NetworkAndAddress6TestCase ());
+ AddTestCase (new ExampleAddress6GeneratorTestCase ());
+ AddTestCase (new AddressCollision6TestCase ());
+ }
+} g_ipv6AddressGeneratorTestSuite;
+
+} // namespace ns3
+
--- a/src/internet/wscript Fri Dec 16 18:50:05 2011 +0100
+++ b/src/internet/wscript Fri Dec 16 18:51:18 2011 +0100
@@ -183,6 +183,7 @@
'helper/ipv6-address-helper.cc',
'helper/ipv6-interface-container.cc',
'helper/ipv6-routing-helper.cc',
+ 'model/ipv6-address-generator.cc',
]
internet_test = bld.create_ns3_module_test_library('internet')
@@ -204,6 +205,7 @@
'test/ipv6-test.cc',
'test/tcp-test.cc',
'test/udp-test.cc',
+ 'test/ipv6-address-generator-test-suite.cc',
]
headers = bld.new_task_gen(features=['ns3header'])
@@ -276,6 +278,7 @@
'helper/ipv6-address-helper.h',
'helper/ipv6-interface-container.h',
'helper/ipv6-routing-helper.h',
+ 'model/ipv6-address-generator.h',
]
if bld.env['NSC_ENABLED']:
--- a/src/lte/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/lte/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:51:18 2011 +0100
@@ -3989,6 +3989,10 @@
cls.add_constructor([param('ns3::SpectrumInterference const &', 'arg0')])
## spectrum-interference.h (module 'spectrum'): ns3::SpectrumInterference::SpectrumInterference() [constructor]
cls.add_constructor([])
+ ## spectrum-interference.h (module 'spectrum'): void ns3::SpectrumInterference::AbortRx() [member function]
+ cls.add_method('AbortRx',
+ 'void',
+ [])
## spectrum-interference.h (module 'spectrum'): void ns3::SpectrumInterference::AddSignal(ns3::Ptr<ns3::SpectrumValue const> spd, ns3::Time const duration) [member function]
cls.add_method('AddSignal',
'void',
@@ -5661,6 +5665,11 @@
'ns3::Vector',
[],
is_const=True)
+ ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+ cls.add_method('GetRelativeSpeed',
+ 'double',
+ [param('ns3::Ptr< ns3::MobilityModel const >', 'other')],
+ is_const=True)
## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
cls.add_method('GetTypeId',
'ns3::TypeId',
--- a/src/lte/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/lte/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:51:18 2011 +0100
@@ -3989,6 +3989,10 @@
cls.add_constructor([param('ns3::SpectrumInterference const &', 'arg0')])
## spectrum-interference.h (module 'spectrum'): ns3::SpectrumInterference::SpectrumInterference() [constructor]
cls.add_constructor([])
+ ## spectrum-interference.h (module 'spectrum'): void ns3::SpectrumInterference::AbortRx() [member function]
+ cls.add_method('AbortRx',
+ 'void',
+ [])
## spectrum-interference.h (module 'spectrum'): void ns3::SpectrumInterference::AddSignal(ns3::Ptr<ns3::SpectrumValue const> spd, ns3::Time const duration) [member function]
cls.add_method('AddSignal',
'void',
@@ -5661,6 +5665,11 @@
'ns3::Vector',
[],
is_const=True)
+ ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+ cls.add_method('GetRelativeSpeed',
+ 'double',
+ [param('ns3::Ptr< ns3::MobilityModel const >', 'other')],
+ is_const=True)
## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
cls.add_method('GetTypeId',
'ns3::TypeId',
--- a/src/mesh/helper/mesh-stack-installer.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/helper/mesh-stack-installer.h Fri Dec 16 18:51:18 2011 +0100
@@ -28,7 +28,8 @@
*
* \brief Prototype for class, which helps to install MAC-layer
* routing stack to ns3::MeshPointDevice
- * \details You need to create a MeshPointDevice and attach all
+ *
+ * You need to create a MeshPointDevice and attach all
* interfaces to it, than call Install method
*/
class MeshStack : public Object
--- a/src/mesh/model/dot11s/airtime-metric.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/dot11s/airtime-metric.h Fri Dec 16 18:51:18 2011 +0100
@@ -26,16 +26,15 @@
/**
* \ingroup dot11s
*
- * \brief airtime link metric calculator
+ * \brief Airtime link metric calculator
*
- * \details Airtime link metric is defined in 11B.10 of 802.11s Draft D3.0 as:
+ * Airtime link metric is defined in 11B.10 of 802.11s Draft D3.0 as:
*
- * airtime = (O + Bt/r)* (1 + average retry counter), where
- *
- * o -- the PHY dependent channel access which includes frame headers, training sequences,
+ * airtime = (O + Bt/r)* (1 + average retry counter), where:
+ * - o -- the PHY dependent channel access which includes frame headers, training sequences,
* access protocol frames, etc.
- * bt -- the test packet length in bits (8192 by default),
- * r -- the current bitrate of the packet,
+ * - bt -- the test packet length in bits (8192 by default),
+ * - r -- the current bitrate of the packet,
*
* Final result is expressed in units of 0.01 Time Unit = 10.24 us (as required by 802.11s draft)
*/
--- a/src/mesh/model/dot11s/hwmp-protocol.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/dot11s/hwmp-protocol.cc Fri Dec 16 18:51:18 2011 +0100
@@ -565,18 +565,19 @@
std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
prep.GetOriginatorAddress ());
bool freshInfo (true);
+ uint32_t sequence = prep.GetDestinationSeqNumber ();
if (i != m_hwmpSeqnoMetricDatabase.end ())
{
- if ((int32_t)(i->second.first - prep.GetOriginatorSeqNumber ()) > 0)
+ if ((int32_t)(i->second.first - sequence) > 0)
{
return;
}
- if (i->second.first == prep.GetOriginatorSeqNumber ())
+ if (i->second.first == sequence)
{
freshInfo = false;
}
}
- m_hwmpSeqnoMetricDatabase[prep.GetOriginatorAddress ()] = std::make_pair (prep.GetOriginatorSeqNumber (), prep.GetMetric ());
+ m_hwmpSeqnoMetricDatabase[prep.GetOriginatorAddress ()] = std::make_pair (sequence, prep.GetMetric ());
//update routing info
//Now add a path to destination and add precursor to source
NS_LOG_DEBUG ("I am " << GetAddress () << ", received prep from " << prep.GetOriginatorAddress () << ", receiver was:" << from);
@@ -597,7 +598,7 @@
interface,
prep.GetMetric (),
MicroSeconds (prep.GetLifetime () * 1024),
- prep.GetOriginatorSeqNumber ());
+ sequence);
m_rtable->AddPrecursor (prep.GetDestinationAddress (), interface, from,
MicroSeconds (prep.GetLifetime () * 1024));
if (result.retransmitter != Mac48Address::GetBroadcast ())
@@ -618,7 +619,7 @@
interface,
metric,
MicroSeconds (prep.GetLifetime () * 1024),
- prep.GetOriginatorSeqNumber ());
+ sequence);
ReactivePathResolved (fromMp);
}
if (prep.GetDestinationAddress () == GetAddress ())
--- a/src/mesh/model/dot11s/hwmp-tag.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/dot11s/hwmp-tag.h Fri Dec 16 18:51:18 2011 +0100
@@ -34,7 +34,7 @@
* \brief Hwmp tag implements interaction between HWMP
* protocol and MeshWifiMac
*
- * \details Hwmp tag keeps the following:
+ * Hwmp tag keeps the following:
* 1. When packet is passed from Hwmp to 11sMAC:
* - retransmitter address,
* - TTL value,
--- a/src/mesh/model/dot11s/peer-link-frame.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/dot11s/peer-link-frame.h Fri Dec 16 18:51:18 2011 +0100
@@ -34,9 +34,9 @@
/**
* \ingroup dot11s
*
- * \brief 802.11s Peer link management frame:
- * \details included the following (see chapters 7.4.12.1-7.4.12.3 of
- * 802.11s):
+ * \brief 802.11s Peer link management frame
+ *
+ * Peer link management frame included the following (see chapters 7.4.12.1-7.4.12.3 of 802.11s):
* - Subtype field
* - Association ID field
* - Supported rates
--- a/src/mesh/model/dot11s/peer-link.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/dot11s/peer-link.h Fri Dec 16 18:51:18 2011 +0100
@@ -202,14 +202,14 @@
PeerLink& operator= (const PeerLink &);
PeerLink (const PeerLink &);
- ///The number of interface I am associated with
+ /// The number of interface I am associated with
uint32_t m_interface;
/// pointer to MAC plugin, which is responsible for peer management
Ptr<PeerManagementProtocolMac> m_macPlugin;
/// Peer address
Mac48Address m_peerAddress;
/// Mesh point address, equal to peer address in case of single
- //interface mesh point
+ /// interface mesh point
Mac48Address m_peerMeshPointAddress;
/// My ID of this link
uint16_t m_localLinkId;
@@ -253,7 +253,7 @@
EventId m_beaconLossTimer;
uint16_t m_maxBeaconLoss;
uint16_t m_maxPacketFail;
- //\}
+ // \}
/// How to report my status change
SignalStatusCallback m_linkStatusCallback;
};
--- a/src/mesh/model/dot11s/peer-management-protocol-mac.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/dot11s/peer-management-protocol-mac.h Fri Dec 16 18:51:18 2011 +0100
@@ -45,26 +45,30 @@
PeerManagementProtocolMac (uint32_t interface, Ptr<PeerManagementProtocol> protocol);
~PeerManagementProtocolMac ();
///\name Inherited from plugin abstract class
- ///\{
+ // \{
void SetParent (Ptr<MeshWifiInterfaceMac> parent);
bool Receive (Ptr<Packet> packet, const WifiMacHeader & header);
bool UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to);
void UpdateBeacon (MeshWifiBeacon & beacon) const;
- ///\}
- ///\name Statistics:
- ///\{
+ // \}
+ ///\name Statistics
+ // \{
void Report (std::ostream &) const;
void ResetStats ();
uint32_t GetLinkMetric (Mac48Address peerAddress);
- ///\}
+ // \}
private:
PeerManagementProtocolMac& operator= (const PeerManagementProtocolMac &);
PeerManagementProtocolMac (const PeerManagementProtocolMac &);
friend class PeerManagementProtocol;
friend class PeerLink;
- ///\name Create peer link management frames:
- ///\{
+ ///\name Create peer link management frames
+ // \{
+ /**
+ * \brief This structure keeps all fields in peer link management frame,
+ * which are not subclasses of WifiInformationElement
+ */
struct PlinkFrameStart
{
uint8_t subtype;
@@ -75,18 +79,13 @@
Ptr<Packet> CreatePeerLinkOpenFrame ();
Ptr<Packet> CreatePeerLinkConfirmFrame ();
Ptr<Packet> CreatePeerLinkCloseFrame ();
- /**
- * \brief This structure keeps all fields in peer link management frame,
- * which are not subclasses of WifiInformationElement
- */
- /// \name Parses the start of the frame, where there are no
- /// WifiInformationElements exist
+ /// Parses the start of the frame, where no WifiInformationElements exist
PlinkFrameStart ParsePlinkFrame (Ptr<const Packet> packet);
- ///\}
- ///// Closes link when a proper number of successive transmissions have failed
+ // \}
+ /// Closes link when a proper number of successive transmissions have failed
void TxError (WifiMacHeader const &hdr);
void TxOk (WifiMacHeader const &hdr);
- ///BCA functionallity:
+ /// BCA functionality
void SetBeaconShift (Time shift);
void SetPeerManagerProtcol (Ptr<PeerManagementProtocol> protocol);
void SendPeerLinkManagementFrame (
@@ -96,9 +95,10 @@
IePeerManagement peerElement,
IeConfiguration meshConfig
);
- ///\brief DUBUG only - to print established links
+ ///\brief debug only, used to print established links
Mac48Address GetAddress () const;
///\name Statistics
+ // \{
struct Statistics
{
uint16_t txOpen;
@@ -122,11 +122,11 @@
struct Statistics m_stats;
///\}
///\name Information about MAC and protocol:
- ///\{
+ // \{
Ptr<MeshWifiInterfaceMac> m_parent;
uint32_t m_ifIndex;
Ptr<PeerManagementProtocol> m_protocol;
- ///\}
+ // \}
};
} // namespace dot11s
--- a/src/mesh/model/dot11s/peer-management-protocol.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/dot11s/peer-management-protocol.cc Fri Dec 16 18:51:18 2011 +0100
@@ -164,7 +164,6 @@
{
//PM STATE Machine
//Check that a given beacon is not from our interface
- Simulator::Schedule (beaconInterval - TuToTime (m_maxBeaconShift + 1), &PeerManagementProtocol::DoShiftBeacon, this, interface);
for (PeerManagementProtocolMacMap::const_iterator i = m_plugins.begin (); i != m_plugins.end (); i++)
{
if (i->second->GetAddress () == peerAddress)
@@ -180,6 +179,10 @@
peerLink = InitiateLink (interface, peerAddress, Mac48Address::GetBroadcast ());
peerLink->MLMEActivePeerLinkOpen ();
}
+ else
+ {
+ return;
+ }
}
peerLink->SetBeaconInformation (Simulator::Now (), beaconInterval);
if (GetBeaconCollisionAvoidance ())
@@ -371,81 +374,93 @@
}
void
-PeerManagementProtocol::DoShiftBeacon (uint32_t interface)
+PeerManagementProtocol::CheckBeaconCollisions (uint32_t interface)
{
if (!GetBeaconCollisionAvoidance ())
{
return;
}
- // If beacon interval is equal to the neighbor's one and one o more beacons received
- // by my neighbor coincide with my beacon - apply random uniformly distributed shift from
- // [-m_maxBeaconShift, m_maxBeaconShift] except 0.
- UniformVariable beaconShift (-m_maxBeaconShift, m_maxBeaconShift);
PeerLinksMap::iterator iface = m_peerLinks.find (interface);
NS_ASSERT (iface != m_peerLinks.end ());
- PeerManagementProtocolMacMap::const_iterator plugin = m_plugins.find (interface);
- NS_ASSERT (plugin != m_plugins.end ());
- // cast plugin to void, to suppress 'plugin' set but not used, compiler warning
- // in optimized builds
- (void) plugin;
+ NS_ASSERT (m_plugins.find (interface) != m_plugins.end ());
+
std::map<uint32_t, Time>::const_iterator lastBeacon = m_lastBeacon.find (interface);
std::map<uint32_t, Time>::const_iterator beaconInterval = m_beaconInterval.find (interface);
if ((lastBeacon == m_lastBeacon.end ()) || (beaconInterval == m_beaconInterval.end ()))
{
return;
}
- if (TuToTime (m_maxBeaconShift) > m_beaconInterval[interface])
+ //my last beacon in 256 us units
+ uint16_t lastBeaconInTimeElement = (uint16_t) ((lastBeacon->second.GetMicroSeconds () >> 8) & 0xffff);
+
+ NS_ASSERT_MSG (TuToTime (m_maxBeaconShift) <= m_beaconInterval[interface], "Wrong beacon shift parameters");
+
+ if (iface->second.size () == 0)
{
- NS_FATAL_ERROR ("Wrong beacon shift parameters");
+ //I have no peers - may be our beacons are in collision
+ ShiftOwnBeacon (interface);
return;
}
+ //check whether all my peers receive my beacon and I'am not in collision with other beacons
+
for (PeerLinksOnInterface::iterator i = iface->second.begin (); i != iface->second.end (); i++)
{
- IeBeaconTiming::NeighboursTimingUnitsList neighbours;
- neighbours = (*i)->GetBeaconTimingElement ().GetNeighboursTimingElementsList ();
- //Going through all my timing elements and detecting future beacon collisions
- for (IeBeaconTiming::NeighboursTimingUnitsList::const_iterator j = neighbours.begin (); j
- != neighbours.end (); j++)
+ bool myBeaconExists = false;
+ IeBeaconTiming::NeighboursTimingUnitsList neighbors = (*i)->GetBeaconTimingElement ().GetNeighboursTimingElementsList ();
+ for (IeBeaconTiming::NeighboursTimingUnitsList::const_iterator j = neighbors.begin (); j != neighbors.end (); j++)
{
if ((*i)->GetPeerAid () == (*j)->GetAid ())
{
- // I am present at neighbour's list of neighbors
- continue;
- }
- //Beacon interval is stored in TU's
- if (((*j)->GetBeaconInterval ()) != TimeToTu (beaconInterval->second))
- {
+ // I am presented at neighbour's list of neighbors
+ myBeaconExists = true;
continue;
}
- //Timing element keeps beacon receiving times in 256us units, TU=1024us
- if ((int)((int)(*j)->GetLastBeacon () / 4 - (int)TimeToTu (lastBeacon->second)) % TimeToTu (
- beaconInterval->second)
- != 0)
+ if (
+ ((int16_t) ((*j)->GetLastBeacon () - lastBeaconInTimeElement) >= 0) &&
+ (((*j)->GetLastBeacon () - lastBeaconInTimeElement) % (4 * TimeToTu (beaconInterval->second)) == 0)
+ )
{
- continue;
+ ShiftOwnBeacon (interface);
+ return;
}
- int shift = 0;
- do
- {
- shift = (int) beaconShift.GetValue ();
- }
- while (shift == 0);
- PeerManagementProtocolMacMap::iterator plugin = m_plugins.find (interface);
- NS_ASSERT (plugin != m_plugins.end ());
- plugin->second->SetBeaconShift (TuToTime (shift));
+ }
+ if (!myBeaconExists)
+ {
+ // If I am not present in neighbor's beacon timing element, this may be caused by collisions with
+ ShiftOwnBeacon (interface);
return;
}
}
}
+
+void
+PeerManagementProtocol::ShiftOwnBeacon (uint32_t interface)
+{
+ // If beacon interval is equal to the neighbor's one and one o more beacons received
+ // by my neighbor coincide with my beacon - apply random uniformly distributed shift from
+ // [-m_maxBeaconShift, m_maxBeaconShift] except 0.
+ UniformVariable beaconShift (-m_maxBeaconShift, m_maxBeaconShift);
+ int shift = 0;
+ do
+ {
+ shift = (int) beaconShift.GetValue ();
+ }
+ while (shift == 0);
+ // Apply beacon shift parameters:
+ PeerManagementProtocolMacMap::iterator plugin = m_plugins.find (interface);
+ NS_ASSERT (plugin != m_plugins.end ());
+ plugin->second->SetBeaconShift (TuToTime (shift));
+}
+
Time
-PeerManagementProtocol::TuToTime (uint32_t x)
+PeerManagementProtocol::TuToTime (int x)
{
return MicroSeconds (x * 1024);
}
-uint32_t
+int
PeerManagementProtocol::TimeToTu (Time x)
{
- return (uint32_t)(x.GetMicroSeconds () / 1024);
+ return (int)(x.GetMicroSeconds () / 1024);
}
void
@@ -522,6 +537,7 @@
PeerManagementProtocol::NotifyBeaconSent (uint32_t interface, Time beaconInterval)
{
m_lastBeacon[interface] = Simulator::Now ();
+ Simulator::Schedule (beaconInterval - TuToTime (m_maxBeaconShift + 1), &PeerManagementProtocol::CheckBeaconCollisions,this, interface);
m_beaconInterval[interface] = beaconInterval;
}
PeerManagementProtocol::Statistics::Statistics (uint16_t t) :
--- a/src/mesh/model/dot11s/peer-management-protocol.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/dot11s/peer-management-protocol.h Fri Dec 16 18:51:18 2011 +0100
@@ -82,7 +82,7 @@
* \param beaconTiming beacon timing element (needed by BCA)
*/
void ReceiveBeacon (uint32_t interface, Mac48Address peerAddress, Time beaconInterval, Ptr<IeBeaconTiming> beaconTiming);
- //\}
+ // \}
/**
* \brief Methods that handle Peer link management frames
* interaction:
@@ -125,9 +125,9 @@
* \brief Checks if there is established link
*/
bool IsActiveLink (uint32_t interface, Mac48Address peerAddress);
- //\}
+ // \}
///\name Interface to other protocols (MLME)
- //\{
+ // \{
/// Set peer link status change callback
void SetPeerLinkStatusCallback (Callback<void, Mac48Address, Mac48Address, uint32_t, bool> cb);
/// Find active peer link by my interface and peer interface MAC
@@ -150,7 +150,8 @@
void Report (std::ostream &) const;
void ResetStats ();
private:
- /** \name Private structures
+ /**
+ * \name Private structures
* \{
*/
/// Keeps information about beacon of peer station: beacon interval, association ID, last time we have received a beacon
@@ -171,7 +172,7 @@
typedef std::map<uint32_t, BeaconsOnInterface> BeaconInfoMap;
///\brief this vector keeps pointers to MAC-plugins
typedef std::map<uint32_t, Ptr<PeerManagementProtocolMac> > PeerManagementProtocolMacMap;
- ///\}
+ // \}
private:
PeerManagementProtocol& operator= (const PeerManagementProtocol &);
PeerManagementProtocol (const PeerManagementProtocol &);
@@ -193,14 +194,15 @@
*/
void PeerLinkStatus (uint32_t interface, Mac48Address peerAddress, Mac48Address peerMeshPointAddres, PeerLink::PeerState ostate, PeerLink::PeerState nstate);
///\brief BCA
- void DoShiftBeacon (uint32_t interface);
+ void CheckBeaconCollisions (uint32_t interface);
+ void ShiftOwnBeacon (uint32_t interface);
/**
* \name Time<-->TU converters:
* \{
*/
- Time TuToTime (uint32_t x);
- uint32_t TimeToTu (Time x);
- ///\}
+ Time TuToTime (int x);
+ int TimeToTu (Time x);
+ // \}
/// Aux. method to register open links
void NotifyLinkOpen (Mac48Address peerMp, Mac48Address peerIface, Mac48Address myIface, uint32_t interface);
@@ -218,9 +220,9 @@
bool m_enableBca;
/// Beacon can be shifted at [-m_maxBeaconShift; +m_maxBeaconShift] TUs
uint16_t m_maxBeaconShift;
- ///Last beacon at each interface
+ /// Last beacon at each interface
std::map<uint32_t, Time> m_lastBeacon;
- ///Beacon interval at each interface
+ /// Beacon interval at each interface
std::map<uint32_t, Time> m_beaconInterval;
/**
@@ -248,7 +250,7 @@
LinkEventCallback m_linkCloseTraceSrc;
///\name Statistics:
- ///\{
+ // \{
struct Statistics {
uint16_t linksTotal;
uint16_t linksOpened;
@@ -258,7 +260,7 @@
void Print (std::ostream & os) const;
};
struct Statistics m_stats;
- ///\}
+ // \}
};
} // namespace dot11s
--- a/src/mesh/model/mesh-wifi-beacon.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/mesh-wifi-beacon.h Fri Dec 16 18:51:18 2011 +0100
@@ -58,7 +58,7 @@
* \param mpAddress is mesh point address
*/
WifiMacHeader CreateHeader (Mac48Address address, Mac48Address mpAddress);
- ///Returns a beacon interval of wifi beacon
+ /// Returns a beacon interval of wifi beacon
Time GetBeaconInterval () const;
/// Create frame = { beacon header + all information elements sorted by ElementId () }
Ptr<Packet> CreatePacket ();
--- a/src/mesh/model/mesh-wifi-interface-mac.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/mesh-wifi-interface-mac.cc Fri Dec 16 18:51:18 2011 +0100
@@ -379,7 +379,6 @@
NS_LOG_DEBUG (GetAddress () << " is sending beacon");
NS_ASSERT (!m_beaconSendEvent.IsRunning ());
- NS_ASSERT (Simulator::Now ().GetMicroSeconds () == GetTbtt ().GetMicroSeconds ()); // assert that beacon is just on time
// Form & send beacon
MeshWifiBeacon beacon (GetSsid (), GetSupportedRates (), m_beaconInterval.GetMicroSeconds ());
--- a/src/mesh/model/mesh-wifi-interface-mac.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mesh/model/mesh-wifi-interface-mac.h Fri Dec 16 18:51:18 2011 +0100
@@ -61,19 +61,19 @@
virtual ~MeshWifiInterfaceMac ();
///\name Inherited from WifiMac
- //\{
+ // \{
virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from);
virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
virtual bool SupportsSendFrom () const;
virtual void SetLinkUpCallback (Callback<void> linkUp);
- //\}
+ // \}
///\name Each mesh point interfaces must know the mesh point address
- //\{
+ // \{
void SetMeshPointAddress (Mac48Address);
Mac48Address GetMeshPointAddress () const;
- //\}
+ // \}
///\name Beacons
- //\{
+ // \{
/// Set maximum initial random delay before first beacon
void SetRandomStartDelay (Time interval);
/// Set interval between two successive beacons
@@ -94,13 +94,13 @@
* \attention User of ShiftTbtt () must take care to not shift it to the past.
*/
void ShiftTbtt (Time shift);
- //\}
+ // \}
///\name Plugins
- //\{
+ // \{
/// Install plugin. TODO return unique ID to allow unregister plugins
void InstallPlugin (Ptr<MeshWifiInterfaceMacPlugin> plugin);
- //\}
+ // \}
/** \name Channel switching
*
@@ -109,12 +109,12 @@
*
* Number of channels to use must be limited elsewhere.
*/
- //\{
+ // \{
/// Current channel Id
uint16_t GetFrequencyChannel () const;
/// Switch channel
void SwitchFrequencyChannel (uint16_t new_id);
- //\}
+ // \}
/// To be used by plugins sending management frames.
void SendManagementFrame (Ptr<Packet> frame, const WifiMacHeader& hdr);
@@ -122,11 +122,11 @@
bool CheckSupportedRates (SupportedRates rates) const;
/// \return list of supported bitrates
SupportedRates GetSupportedRates () const;
- ///\ name Metric Calculation routines:
- ///\{
+ ///\name Metric Calculation routines:
+ // \{
void SetLinkMetricCallback (Callback<uint32_t, Mac48Address, Ptr<MeshWifiInterfaceMac> > cb);
uint32_t GetLinkMetric (Mac48Address peerAddress);
- ///\}
+ // \}
///\brief Statistics:
void Report (std::ostream &) const;
void ResetStats ();
@@ -152,14 +152,14 @@
typedef std::vector<Ptr<MeshWifiInterfaceMacPlugin> > PluginList;
///\name Mesh timing intervals
- //\{
+ // \{
/// Beaconing interval.
Time m_beaconInterval;
/// Maximum delay before first beacon
Time m_randomStart;
/// Time for the next frame
Time m_tbtt;
- //\}
+ // \}
/// Mesh point address
Mac48Address m_mpAddress;
@@ -170,7 +170,7 @@
PluginList m_plugins;
Callback<uint32_t, Mac48Address, Ptr<MeshWifiInterfaceMac> > m_linkMetricCallback;
///\name Statistics:
- ///\{
+ // \{
struct Statistics
{
uint16_t recvBeacons;
@@ -183,7 +183,7 @@
Statistics ();
};
Statistics m_stats;
- ///\}
+ // \}
/// Current PHY standard: needed to configure metric
WifiPhyStandard m_standard;
};
Binary file src/mesh/test/dot11s/hwmp-proactive-regression-test-0-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-proactive-regression-test-1-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-proactive-regression-test-2-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-proactive-regression-test-3-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-proactive-regression-test-4-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-reactive-regression-test-0-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-reactive-regression-test-1-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-reactive-regression-test-2-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-reactive-regression-test-3-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-reactive-regression-test-4-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-reactive-regression-test-5-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-simplest-regression-test-0-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-simplest-regression-test-1-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-target-flags-regression-test-0-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-target-flags-regression-test-1-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-target-flags-regression-test-2-1.pcap has changed
Binary file src/mesh/test/dot11s/hwmp-target-flags-regression-test-3-1.pcap has changed
--- a/src/mobility/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mobility/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:51:18 2011 +0100
@@ -2933,6 +2933,11 @@
'ns3::Vector',
[],
is_const=True)
+ ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+ cls.add_method('GetRelativeSpeed',
+ 'double',
+ [param('ns3::Ptr< ns3::MobilityModel const >', 'other')],
+ is_const=True)
## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
cls.add_method('GetTypeId',
'ns3::TypeId',
--- a/src/mobility/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mobility/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:51:18 2011 +0100
@@ -2933,6 +2933,11 @@
'ns3::Vector',
[],
is_const=True)
+ ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+ cls.add_method('GetRelativeSpeed',
+ 'double',
+ [param('ns3::Ptr< ns3::MobilityModel const >', 'other')],
+ is_const=True)
## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
cls.add_method('GetTypeId',
'ns3::TypeId',
--- a/src/mobility/helper/ns2-mobility-helper.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mobility/helper/ns2-mobility-helper.cc Fri Dec 16 18:51:18 2011 +0100
@@ -23,7 +23,7 @@
* Brief description: Implementation of a ns2 movement trace file reader.
*
* This implementation is based on the ns2 movement documentation of ns2
- * as described in http://www.isi.edu/nsnam/ns/doc/node174.html
+ * as described in http://www.isi.edu/nsnam/ns/doc/node172.html
*
* Valid trace files use the following ns2 statements:
*
@@ -353,6 +353,10 @@
{
string x;
s >> x;
+ if (x.length () == 0)
+ {
+ continue;
+ }
ret.tokens.push_back (x);
int ii (0);
double d (0);
@@ -638,6 +642,10 @@
// first calculate the time; time = distance / speed
double time = sqrt (pow (xFinalPosition - retval.m_finalPosition.x, 2) + pow (yFinalPosition - retval.m_finalPosition.y, 2)) / speed;
NS_LOG_DEBUG ("at=" << at << " time=" << time);
+ if (time == 0)
+ {
+ return retval;
+ }
// now calculate the xSpeed = distance / time
double xSpeed = (xFinalPosition - retval.m_finalPosition.x) / time;
double ySpeed = (yFinalPosition - retval.m_finalPosition.y) / time; // & same with ySpeed
@@ -649,10 +657,7 @@
NS_LOG_DEBUG ("Calculated Speed: X=" << xSpeed << " Y=" << ySpeed << " Z=" << zSpeed);
// Set the Values
- if (time >= 0)
- {
- Simulator::Schedule (Seconds (at), &ConstantVelocityMobilityModel::SetVelocity, model, Vector (xSpeed, ySpeed, zSpeed));
- }
+ Simulator::Schedule (Seconds (at), &ConstantVelocityMobilityModel::SetVelocity, model, Vector (xSpeed, ySpeed, zSpeed));
retval.m_stopEvent = Simulator::Schedule (Seconds (at + time), &ConstantVelocityMobilityModel::SetVelocity, model, Vector (0, 0, 0));
retval.m_finalPosition.x += xSpeed * time;
retval.m_finalPosition.y += ySpeed * time;
--- a/src/mobility/helper/ns2-mobility-helper.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mobility/helper/ns2-mobility-helper.h Fri Dec 16 18:51:18 2011 +0100
@@ -37,7 +37,7 @@
* \brief Helper class which can read ns-2 movement files and configure nodes mobility.
*
* This implementation is based on the ns2 movement documentation of ns2
- * as described in http://www.isi.edu/nsnam/ns/doc/node174.html
+ * as described in http://www.isi.edu/nsnam/ns/doc/node172.html
*
* Valid trace files use the following ns2 statements:
\verbatim
--- a/src/mobility/model/waypoint-mobility-model.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mobility/model/waypoint-mobility-model.cc Fri Dec 16 18:51:18 2011 +0100
@@ -203,7 +203,7 @@
WaypointMobilityModel::EndMobility (void)
{
m_waypoints.clear ();
- m_current.time = Seconds (std::numeric_limits<double>::infinity ());
+ m_current.time = Time(std::numeric_limits<uint64_t>::infinity());
m_next.time = m_current.time;
m_first = true;
}
--- a/src/mobility/test/ns2-mobility-helper-test-suite.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/mobility/test/ns2-mobility-helper-test-suite.cc Fri Dec 16 18:51:18 2011 +0100
@@ -432,6 +432,24 @@
t->AddReferencePoint ("0", 6, Vector (0, 5, 0), Vector (0, -1, 0));
t->AddReferencePoint ("0", 16, Vector (0, -10, 0), Vector (0, 0, 0));
AddTestCase (t);
+ t = new Ns2MobilityHelperTest ("Bug 1059 testcase", Seconds (16));
+ t->SetTrace ("$node_(0) set X_ 10.0\r\n"
+ "$node_(0) set Y_ 0.0\r\n"
+ );
+ // id t position velocity
+ t->AddReferencePoint ("0", 0, Vector (10, 0, 0), Vector (0, 0, 0));
+ AddTestCase (t);
+ t = new Ns2MobilityHelperTest ("Bug 1301 testcase", Seconds (16));
+ t->SetTrace ("$node_(0) set X_ 10.0\n"
+ "$node_(0) set Y_ 0.0\n"
+ "$ns_ at 1.0 \"$node_(0) setdest 10 0 1\"\n"
+ );
+ // id t position velocity
+ // Moving to the current position must change nothing. No NaN
+ // speed must be.
+ t->AddReferencePoint ("0", 0, Vector (10, 0, 0), Vector (0, 0, 0));
+ AddTestCase (t);
+
}
} g_ns2TransmobilityHelperTestSuite;
--- a/src/netanim/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/netanim/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:51:18 2011 +0100
@@ -515,6 +515,15 @@
cls.add_constructor([param('std::string const', 'filename'), param('bool', 'usingXML', default_value='true')])
## animation-interface.h (module 'netanim'): ns3::AnimationInterface::AnimationInterface(uint16_t port, bool usingXML=true) [constructor]
cls.add_constructor([param('uint16_t', 'port'), param('bool', 'usingXML', default_value='true')])
+ ## animation-interface.h (module 'netanim'): static bool ns3::AnimationInterface::IsInitialized() [member function]
+ cls.add_method('IsInitialized',
+ 'bool',
+ [],
+ is_static=True)
+ ## animation-interface.h (module 'netanim'): bool ns3::AnimationInterface::IsStarted() [member function]
+ cls.add_method('IsStarted',
+ 'bool',
+ [])
## animation-interface.h (module 'netanim'): void ns3::AnimationInterface::ResetAnimWriteCallback() [member function]
cls.add_method('ResetAnimWriteCallback',
'void',
@@ -3220,6 +3229,11 @@
'ns3::Vector',
[],
is_const=True)
+ ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+ cls.add_method('GetRelativeSpeed',
+ 'double',
+ [param('ns3::Ptr< ns3::MobilityModel const >', 'other')],
+ is_const=True)
## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
cls.add_method('GetTypeId',
'ns3::TypeId',
--- a/src/netanim/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/netanim/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:51:18 2011 +0100
@@ -515,6 +515,15 @@
cls.add_constructor([param('std::string const', 'filename'), param('bool', 'usingXML', default_value='true')])
## animation-interface.h (module 'netanim'): ns3::AnimationInterface::AnimationInterface(uint16_t port, bool usingXML=true) [constructor]
cls.add_constructor([param('uint16_t', 'port'), param('bool', 'usingXML', default_value='true')])
+ ## animation-interface.h (module 'netanim'): static bool ns3::AnimationInterface::IsInitialized() [member function]
+ cls.add_method('IsInitialized',
+ 'bool',
+ [],
+ is_static=True)
+ ## animation-interface.h (module 'netanim'): bool ns3::AnimationInterface::IsStarted() [member function]
+ cls.add_method('IsStarted',
+ 'bool',
+ [])
## animation-interface.h (module 'netanim'): void ns3::AnimationInterface::ResetAnimWriteCallback() [member function]
cls.add_method('ResetAnimWriteCallback',
'void',
@@ -3220,6 +3229,11 @@
'ns3::Vector',
[],
is_const=True)
+ ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+ cls.add_method('GetRelativeSpeed',
+ 'double',
+ [param('ns3::Ptr< ns3::MobilityModel const >', 'other')],
+ is_const=True)
## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
cls.add_method('GetTypeId',
'ns3::TypeId',
--- a/src/netanim/model/animation-interface.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/netanim/model/animation-interface.cc Fri Dec 16 18:51:18 2011 +0100
@@ -51,14 +51,18 @@
NS_LOG_COMPONENT_DEFINE ("AnimationInterface");
+#define PURGE_INTERVAL 5
+static bool initialized = false;
+
namespace ns3 {
AnimationInterface::AnimationInterface ()
: m_fHandle (STDOUT_FILENO), m_xml (false), mobilitypollinterval (Seconds(0.25)),
usingSockets (false), mport (0), outputfilename (""),
OutputFileSet (false), ServerPortSet (false), gAnimUid (0),randomPosition (true),
- m_writeCallback (0)
+ m_writeCallback (0), m_started (false)
{
+ initialized = true;
StartAnimation ();
}
@@ -66,8 +70,9 @@
: m_fHandle (STDOUT_FILENO), m_xml (usingXML), mobilitypollinterval (Seconds(0.25)),
usingSockets (false), mport (0), outputfilename (fn),
OutputFileSet (false), ServerPortSet (false), gAnimUid (0), randomPosition (true),
- m_writeCallback (0)
+ m_writeCallback (0), m_started (false)
{
+ initialized = true;
StartAnimation ();
}
@@ -75,8 +80,9 @@
: m_fHandle (STDOUT_FILENO), m_xml (usingXML), mobilitypollinterval (Seconds(0.25)),
usingSockets (true), mport (port), outputfilename (""),
OutputFileSet (false), ServerPortSet (false), gAnimUid (0), randomPosition (true),
- m_writeCallback (0)
+ m_writeCallback (0), m_started (false)
{
+ initialized = true;
StartAnimation ();
}
@@ -116,6 +122,17 @@
return true;
}
+bool AnimationInterface::IsInitialized ()
+{
+ return initialized;
+}
+
+bool AnimationInterface::IsStarted ()
+{
+ return m_started;
+
+}
+
void AnimationInterface::SetAnimWriteCallback (AnimWriteCallback cb)
{
m_writeCallback = cb;
@@ -226,8 +243,90 @@
return nodeLocation[n->GetId ()];
}
+void AnimationInterface::PurgePendingWifi ()
+{
+ if (pendingWifiPackets.empty ())
+ return;
+ std::vector <uint64_t> purgeList;
+ for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingWifiPackets.begin ();
+ i != pendingWifiPackets.end ();
+ ++i)
+ {
+
+ AnimPacketInfo pktInfo = i->second;
+ double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
+ if (delta > PURGE_INTERVAL)
+ {
+ purgeList.push_back (i->first);
+ }
+ }
+
+ for (std::vector <uint64_t>::iterator i = purgeList.begin ();
+ i != purgeList.end ();
+ ++i)
+ {
+ pendingWifiPackets.erase (*i);
+ }
+
+}
+
+void AnimationInterface::PurgePendingWimax ()
+{
+ if (pendingWimaxPackets.empty ())
+ return;
+ std::vector <uint64_t> purgeList;
+ for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingWimaxPackets.begin ();
+ i != pendingWimaxPackets.end ();
+ ++i)
+ {
+
+ AnimPacketInfo pktInfo = i->second;
+ double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
+ if (delta > PURGE_INTERVAL)
+ {
+ purgeList.push_back (i->first);
+ }
+ }
+
+ for (std::vector <uint64_t>::iterator i = purgeList.begin ();
+ i != purgeList.end ();
+ ++i)
+ {
+ pendingWimaxPackets.erase (*i);
+ }
+
+}
+
+void AnimationInterface::PurgePendingCsma ()
+{
+ if (pendingCsmaPackets.empty ())
+ return;
+ std::vector <uint64_t> purgeList;
+ for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingCsmaPackets.begin ();
+ i != pendingCsmaPackets.end ();
+ ++i)
+ {
+
+ AnimPacketInfo pktInfo = i->second;
+ double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
+ if (delta > PURGE_INTERVAL)
+ {
+ purgeList.push_back (i->first);
+ }
+ }
+
+ for (std::vector <uint64_t>::iterator i = purgeList.begin ();
+ i != purgeList.end ();
+ ++i)
+ {
+ pendingCsmaPackets.erase (*i);
+ }
+
+}
+
void AnimationInterface::StartAnimation ()
{
+ m_started = true;
if (usingSockets)
{
SetServerPort (mport);
@@ -259,7 +358,7 @@
std::ostringstream oss;
oss << GetXMLOpen_anim (0);
oss << GetPreamble ();
- oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY);
+ oss << GetXMLOpen_topology (topo_minX, topo_minY, topo_maxX, topo_maxY);
WriteN (m_fHandle, oss.str ());
}
NS_LOG_INFO ("Setting topology for "<<NodeList::GetNNodes ()<<" Nodes");
@@ -271,7 +370,7 @@
if (m_xml)
{
Vector v = GetPosition (n);
- oss << GetXMLOpenClose_node (0,n->GetId (),v.x,v.y);
+ oss << GetXMLOpenClose_node (0, n->GetId (), v.x, v.y);
WriteN (m_fHandle, oss.str ());
}
else
@@ -336,6 +435,11 @@
Simulator::Schedule (mobilitypollinterval, &AnimationInterface::MobilityAutoCheck, this);
}
+ ConnectCallbacks ();
+}
+
+void AnimationInterface::ConnectCallbacks ()
+{
// Connect the callbacks
Config::Connect ("/ChannelList/*/TxRxPointToPoint",
MakeCallback (&AnimationInterface::DevTxTrace, this));
@@ -365,11 +469,12 @@
MakeCallback (&AnimationInterface::CsmaMacRxTrace, this));
+}
-}
void AnimationInterface::StopAnimation ()
{
+ m_started = false;
NS_LOG_INFO ("Stopping Animation");
ResetAnimWriteCallback ();
if (m_fHandle > 0)
@@ -510,6 +615,8 @@
Ptr<NetDevice> tx, Ptr<NetDevice> rx,
Time txTime, Time rxTime)
{
+ if (!m_started)
+ return;
NS_ASSERT (tx);
NS_ASSERT (rx);
Time now = Simulator::Now ();
@@ -586,6 +693,8 @@
void AnimationInterface::WifiPhyTxBeginTrace (std::string context,
Ptr<const Packet> p)
{
+ if (!m_started)
+ return;
Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
NS_ASSERT (ndev);
Ptr <Node> n = ndev->GetNode ();
@@ -608,6 +717,8 @@
void AnimationInterface::WifiPhyTxDropTrace (std::string context,
Ptr<const Packet> p)
{
+ if (!m_started)
+ return;
Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
NS_ASSERT (ndev);
// Erase pending wifi
@@ -621,6 +732,8 @@
void AnimationInterface::WifiPhyRxBeginTrace (std::string context,
Ptr<const Packet> p)
{
+ if (!m_started)
+ return;
Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
NS_ASSERT (ndev);
uint64_t AnimUid = GetAnimUidFromPacket (p);
@@ -638,6 +751,8 @@
void AnimationInterface::WifiPhyRxEndTrace (std::string context,
Ptr<const Packet> p)
{
+ if (!m_started)
+ return;
Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
NS_ASSERT (ndev);
Ptr <Node> n = ndev->GetNode ();
@@ -656,6 +771,8 @@
void AnimationInterface::WifiMacRxTrace (std::string context,
Ptr<const Packet> p)
{
+ if (!m_started)
+ return;
Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
NS_ASSERT (ndev);
Ptr <Node> n = ndev->GetNode ();
@@ -673,7 +790,6 @@
{
NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete");
OutputWirelessPacket (pktInfo, pktrxInfo);
- pktInfo.RemoveRxInfo (ndev);
}
}
@@ -684,6 +800,8 @@
void AnimationInterface::WimaxTxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
{
+ if (!m_started)
+ return;
Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
NS_ASSERT (ndev);
Ptr <Node> n = ndev->GetNode ();
@@ -701,6 +819,8 @@
void AnimationInterface::WimaxRxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
{
+ if (!m_started)
+ return;
Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
NS_ASSERT (ndev);
Ptr <Node> n = ndev->GetNode ();
@@ -717,6 +837,8 @@
void AnimationInterface::CsmaPhyTxBeginTrace (std::string context, Ptr<const Packet> p)
{
+ if (!m_started)
+ return;
Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
NS_ASSERT (ndev);
Ptr <Node> n = ndev->GetNode ();
@@ -733,6 +855,8 @@
void AnimationInterface::CsmaPhyTxEndTrace (std::string context, Ptr<const Packet> p)
{
+ if (!m_started)
+ return;
Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
NS_ASSERT (ndev);
uint64_t AnimUid = GetAnimUidFromPacket (p);
@@ -749,6 +873,8 @@
void AnimationInterface::CsmaPhyRxEndTrace (std::string context, Ptr<const Packet> p)
{
+ if (!m_started)
+ return;
Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
NS_ASSERT (ndev);
Ptr <Node> n = ndev->GetNode ();
@@ -770,6 +896,8 @@
void AnimationInterface::CsmaMacRxTrace (std::string context,
Ptr<const Packet> p)
{
+ if (!m_started)
+ return;
NS_LOG_FUNCTION (this);
Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
NS_ASSERT (ndev);
@@ -788,7 +916,6 @@
{
NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete");
OutputCsmaPacket (pktInfo, pktrxInfo);
- pktInfo.RemoveRxInfo (ndev);
}
}
@@ -796,6 +923,8 @@
void AnimationInterface::MobilityCourseChangeTrace (Ptr <const MobilityModel> mobility)
{
+ if (!m_started)
+ return;
Ptr <Node> n = mobility->GetObject <Node> ();
NS_ASSERT (n);
Vector v ;
@@ -820,8 +949,8 @@
bool AnimationInterface::NodeHasMoved (Ptr <Node> n, Vector newLocation)
{
Vector oldLocation = GetPosition (n);
- if ((ceil(oldLocation.x) == ceil(newLocation.x)) &&
- (ceil(oldLocation.y) == ceil(newLocation.y)))
+ if ((ceil (oldLocation.x) == ceil (newLocation.x)) &&
+ (ceil (oldLocation.y) == ceil (newLocation.y)))
{
return false;
@@ -836,19 +965,22 @@
{
std::vector <Ptr <Node> > MovedNodes = RecalcTopoBounds ();
std::ostringstream oss;
- oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY);
+ oss << GetXMLOpen_topology (topo_minX, topo_minY, topo_maxX, topo_maxY);
for (uint32_t i = 0; i < MovedNodes.size (); i++)
{
Ptr <Node> n = MovedNodes [i];
NS_ASSERT (n);
Vector v = GetPosition (n);
- oss << GetXMLOpenClose_node (0,n->GetId (), v.x, v.y);
+ oss << GetXMLOpenClose_node (0, n->GetId (), v.x, v.y);
}
oss << GetXMLClose ("topology");
WriteN (m_fHandle, oss.str ());
WriteDummyPacket ();
if (!Simulator::IsFinished ())
{
+ PurgePendingWifi ();
+ PurgePendingWimax ();
+ PurgePendingCsma ();
Simulator::Schedule (mobilitypollinterval, &AnimationInterface::MobilityAutoCheck, this);
}
}
--- a/src/netanim/model/animation-interface.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/netanim/model/animation-interface.h Fri Dec 16 18:51:18 2011 +0100
@@ -99,6 +99,13 @@
AnimationInterface (uint16_t port, bool usingXML = true);
/**
+ * \brief Check if AnimationInterface is initialized
+ * \returns true if AnimationInterface was already initialized
+ *
+ */
+ static bool IsInitialized (void);
+
+ /**
* \brief Specify that animation commands are to be written
* to the specified output file.
*
@@ -203,6 +210,13 @@
*/
void SetConstantPosition (Ptr <Node> n, double x, double y, double z=0);
+ /**
+ * \brief Is AnimationInterface started
+ * \returns true if AnimationInterface was started
+ *
+ */
+ bool IsStarted (void);
+
private:
#ifndef WIN32
int m_fHandle; // File handle for output (-1 if none)
@@ -286,12 +300,19 @@
bool NodeHasMoved (Ptr <Node> n, Vector newLocation);
void AddMargin ();
+ void PurgePendingWifi ();
+ void PurgePendingWimax ();
+ void PurgePendingCsma ();
+
// Recalculate topology bounds
void RecalcTopoBounds (Vector v);
std::vector < Ptr <Node> > RecalcTopoBounds ();
bool randomPosition;
AnimWriteCallback m_writeCallback;
+ void ConnectCallbacks ();
+
+ bool m_started;
// Path helper
std::vector<std::string> GetElementsFromContext (std::string context);
--- a/src/network/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/network/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:51:18 2011 +0100
@@ -222,6 +222,14 @@
module.add_enum('', ['FRAME_FLAG_NONE', 'FRAME_FLAG_CFP', 'FRAME_FLAG_SHORT_PREAMBLE', 'FRAME_FLAG_WEP', 'FRAME_FLAG_FRAGMENTED', 'FRAME_FLAG_FCS_INCLUDED', 'FRAME_FLAG_DATA_PADDING', 'FRAME_FLAG_BAD_FCS', 'FRAME_FLAG_SHORT_GUARD'], outer_class=root_module['ns3::RadiotapHeader'])
## radiotap-header.h (module 'network'): ns3::RadiotapHeader [enumeration]
module.add_enum('', ['CHANNEL_FLAG_NONE', 'CHANNEL_FLAG_TURBO', 'CHANNEL_FLAG_CCK', 'CHANNEL_FLAG_OFDM', 'CHANNEL_FLAG_SPECTRUM_2GHZ', 'CHANNEL_FLAG_SPECTRUM_5GHZ', 'CHANNEL_FLAG_PASSIVE', 'CHANNEL_FLAG_DYNAMIC', 'CHANNEL_FLAG_GFSK'], outer_class=root_module['ns3::RadiotapHeader'])
+ ## red-queue.h (module 'network'): ns3::RedQueue [class]
+ module.add_class('RedQueue', parent=root_module['ns3::Queue'])
+ ## red-queue.h (module 'network'): ns3::RedQueue [enumeration]
+ module.add_enum('', ['DTYPE_NONE', 'DTYPE_FORCED', 'DTYPE_UNFORCED'], outer_class=root_module['ns3::RedQueue'])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Mode [enumeration]
+ module.add_enum('Mode', ['ILLEGAL', 'PACKETS', 'BYTES'], outer_class=root_module['ns3::RedQueue'])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats [struct]
+ module.add_class('Stats', outer_class=root_module['ns3::RedQueue'])
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> > [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::AttributeAccessor', 'ns3::empty', 'ns3::DefaultDeleter<ns3::AttributeAccessor>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> > [class]
@@ -280,6 +288,10 @@
module.add_class('AttributeChecker', allow_subclassing=False, automatic_type_narrowing=True, import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
## attribute.h (module 'core'): ns3::AttributeValue [class]
module.add_class('AttributeValue', allow_subclassing=False, automatic_type_narrowing=True, import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::AttributeValue, ns3::empty, ns3::DefaultDeleter<ns3::AttributeValue> >'])
+ ## boolean.h (module 'core'): ns3::BooleanChecker [class]
+ module.add_class('BooleanChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
+ ## boolean.h (module 'core'): ns3::BooleanValue [class]
+ module.add_class('BooleanValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
## callback.h (module 'core'): ns3::CallbackChecker [class]
module.add_class('CallbackChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
## callback.h (module 'core'): ns3::CallbackImplBase [class]
@@ -520,6 +532,8 @@
register_Ns3PcapFileWrapper_methods(root_module, root_module['ns3::PcapFileWrapper'])
register_Ns3Queue_methods(root_module, root_module['ns3::Queue'])
register_Ns3RadiotapHeader_methods(root_module, root_module['ns3::RadiotapHeader'])
+ register_Ns3RedQueue_methods(root_module, root_module['ns3::RedQueue'])
+ register_Ns3RedQueueStats_methods(root_module, root_module['ns3::RedQueue::Stats'])
register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >'])
register_Ns3SimpleRefCount__Ns3AttributeChecker_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeChecker__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
register_Ns3SimpleRefCount__Ns3AttributeValue_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeValue__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeValue, ns3::empty, ns3::DefaultDeleter<ns3::AttributeValue> >'])
@@ -545,6 +559,8 @@
register_Ns3AttributeAccessor_methods(root_module, root_module['ns3::AttributeAccessor'])
register_Ns3AttributeChecker_methods(root_module, root_module['ns3::AttributeChecker'])
register_Ns3AttributeValue_methods(root_module, root_module['ns3::AttributeValue'])
+ register_Ns3BooleanChecker_methods(root_module, root_module['ns3::BooleanChecker'])
+ register_Ns3BooleanValue_methods(root_module, root_module['ns3::BooleanValue'])
register_Ns3CallbackChecker_methods(root_module, root_module['ns3::CallbackChecker'])
register_Ns3CallbackImplBase_methods(root_module, root_module['ns3::CallbackImplBase'])
register_Ns3CallbackValue_methods(root_module, root_module['ns3::CallbackValue'])
@@ -4129,6 +4145,70 @@
[param('uint64_t', 'tsft')])
return
+def register_Ns3RedQueue_methods(root_module, cls):
+ ## red-queue.h (module 'network'): ns3::RedQueue::RedQueue(ns3::RedQueue const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::RedQueue const &', 'arg0')])
+ ## red-queue.h (module 'network'): ns3::RedQueue::RedQueue() [constructor]
+ cls.add_constructor([])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Mode ns3::RedQueue::GetMode() [member function]
+ cls.add_method('GetMode',
+ 'ns3::RedQueue::Mode',
+ [])
+ ## red-queue.h (module 'network'): uint32_t ns3::RedQueue::GetQueueSize() [member function]
+ cls.add_method('GetQueueSize',
+ 'uint32_t',
+ [])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats ns3::RedQueue::GetStats() [member function]
+ cls.add_method('GetStats',
+ 'ns3::RedQueue::Stats',
+ [])
+ ## red-queue.h (module 'network'): static ns3::TypeId ns3::RedQueue::GetTypeId() [member function]
+ cls.add_method('GetTypeId',
+ 'ns3::TypeId',
+ [],
+ is_static=True)
+ ## red-queue.h (module 'network'): void ns3::RedQueue::SetMode(ns3::RedQueue::Mode mode) [member function]
+ cls.add_method('SetMode',
+ 'void',
+ [param('ns3::RedQueue::Mode', 'mode')])
+ ## red-queue.h (module 'network'): void ns3::RedQueue::SetQueueLimit(uint32_t lim) [member function]
+ cls.add_method('SetQueueLimit',
+ 'void',
+ [param('uint32_t', 'lim')])
+ ## red-queue.h (module 'network'): void ns3::RedQueue::SetTh(double minTh, double maxTh) [member function]
+ cls.add_method('SetTh',
+ 'void',
+ [param('double', 'minTh'), param('double', 'maxTh')])
+ ## red-queue.h (module 'network'): ns3::Ptr<ns3::Packet> ns3::RedQueue::DoDequeue() [member function]
+ cls.add_method('DoDequeue',
+ 'ns3::Ptr< ns3::Packet >',
+ [],
+ visibility='private', is_virtual=True)
+ ## red-queue.h (module 'network'): bool ns3::RedQueue::DoEnqueue(ns3::Ptr<ns3::Packet> p) [member function]
+ cls.add_method('DoEnqueue',
+ 'bool',
+ [param('ns3::Ptr< ns3::Packet >', 'p')],
+ visibility='private', is_virtual=True)
+ ## red-queue.h (module 'network'): ns3::Ptr<const ns3::Packet> ns3::RedQueue::DoPeek() const [member function]
+ cls.add_method('DoPeek',
+ 'ns3::Ptr< ns3::Packet const >',
+ [],
+ is_const=True, visibility='private', is_virtual=True)
+ return
+
+def register_Ns3RedQueueStats_methods(root_module, cls):
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::Stats() [constructor]
+ cls.add_constructor([])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::Stats(ns3::RedQueue::Stats const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::RedQueue::Stats const &', 'arg0')])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::forcedDrop [variable]
+ cls.add_instance_attribute('forcedDrop', 'uint32_t', is_const=False)
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::qLimDrop [variable]
+ cls.add_instance_attribute('qLimDrop', 'uint32_t', is_const=False)
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::unforcedDrop [variable]
+ cls.add_instance_attribute('unforcedDrop', 'uint32_t', is_const=False)
+ return
+
def register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, cls):
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >::SimpleRefCount() [constructor]
cls.add_constructor([])
@@ -5022,6 +5102,47 @@
is_pure_virtual=True, is_const=True, is_virtual=True)
return
+def register_Ns3BooleanChecker_methods(root_module, cls):
+ ## boolean.h (module 'core'): ns3::BooleanChecker::BooleanChecker() [constructor]
+ cls.add_constructor([])
+ ## boolean.h (module 'core'): ns3::BooleanChecker::BooleanChecker(ns3::BooleanChecker const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::BooleanChecker const &', 'arg0')])
+ return
+
+def register_Ns3BooleanValue_methods(root_module, cls):
+ cls.add_output_stream_operator()
+ ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue(ns3::BooleanValue const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::BooleanValue const &', 'arg0')])
+ ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue() [constructor]
+ cls.add_constructor([])
+ ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue(bool value) [constructor]
+ cls.add_constructor([param('bool', 'value')])
+ ## boolean.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::BooleanValue::Copy() const [member function]
+ cls.add_method('Copy',
+ 'ns3::Ptr< ns3::AttributeValue >',
+ [],
+ is_const=True, is_virtual=True)
+ ## boolean.h (module 'core'): bool ns3::BooleanValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+ cls.add_method('DeserializeFromString',
+ 'bool',
+ [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
+ is_virtual=True)
+ ## boolean.h (module 'core'): bool ns3::BooleanValue::Get() const [member function]
+ cls.add_method('Get',
+ 'bool',
+ [],
+ is_const=True)
+ ## boolean.h (module 'core'): std::string ns3::BooleanValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+ cls.add_method('SerializeToString',
+ 'std::string',
+ [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
+ is_const=True, is_virtual=True)
+ ## boolean.h (module 'core'): void ns3::BooleanValue::Set(bool value) [member function]
+ cls.add_method('Set',
+ 'void',
+ [param('bool', 'value')])
+ return
+
def register_Ns3CallbackChecker_methods(root_module, cls):
## callback.h (module 'core'): ns3::CallbackChecker::CallbackChecker() [constructor]
cls.add_constructor([])
--- a/src/network/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/network/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:51:18 2011 +0100
@@ -222,6 +222,14 @@
module.add_enum('', ['FRAME_FLAG_NONE', 'FRAME_FLAG_CFP', 'FRAME_FLAG_SHORT_PREAMBLE', 'FRAME_FLAG_WEP', 'FRAME_FLAG_FRAGMENTED', 'FRAME_FLAG_FCS_INCLUDED', 'FRAME_FLAG_DATA_PADDING', 'FRAME_FLAG_BAD_FCS', 'FRAME_FLAG_SHORT_GUARD'], outer_class=root_module['ns3::RadiotapHeader'])
## radiotap-header.h (module 'network'): ns3::RadiotapHeader [enumeration]
module.add_enum('', ['CHANNEL_FLAG_NONE', 'CHANNEL_FLAG_TURBO', 'CHANNEL_FLAG_CCK', 'CHANNEL_FLAG_OFDM', 'CHANNEL_FLAG_SPECTRUM_2GHZ', 'CHANNEL_FLAG_SPECTRUM_5GHZ', 'CHANNEL_FLAG_PASSIVE', 'CHANNEL_FLAG_DYNAMIC', 'CHANNEL_FLAG_GFSK'], outer_class=root_module['ns3::RadiotapHeader'])
+ ## red-queue.h (module 'network'): ns3::RedQueue [class]
+ module.add_class('RedQueue', parent=root_module['ns3::Queue'])
+ ## red-queue.h (module 'network'): ns3::RedQueue [enumeration]
+ module.add_enum('', ['DTYPE_NONE', 'DTYPE_FORCED', 'DTYPE_UNFORCED'], outer_class=root_module['ns3::RedQueue'])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Mode [enumeration]
+ module.add_enum('Mode', ['ILLEGAL', 'PACKETS', 'BYTES'], outer_class=root_module['ns3::RedQueue'])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats [struct]
+ module.add_class('Stats', outer_class=root_module['ns3::RedQueue'])
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> > [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::AttributeAccessor', 'ns3::empty', 'ns3::DefaultDeleter<ns3::AttributeAccessor>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> > [class]
@@ -280,6 +288,10 @@
module.add_class('AttributeChecker', allow_subclassing=False, automatic_type_narrowing=True, import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
## attribute.h (module 'core'): ns3::AttributeValue [class]
module.add_class('AttributeValue', allow_subclassing=False, automatic_type_narrowing=True, import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::AttributeValue, ns3::empty, ns3::DefaultDeleter<ns3::AttributeValue> >'])
+ ## boolean.h (module 'core'): ns3::BooleanChecker [class]
+ module.add_class('BooleanChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
+ ## boolean.h (module 'core'): ns3::BooleanValue [class]
+ module.add_class('BooleanValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
## callback.h (module 'core'): ns3::CallbackChecker [class]
module.add_class('CallbackChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
## callback.h (module 'core'): ns3::CallbackImplBase [class]
@@ -520,6 +532,8 @@
register_Ns3PcapFileWrapper_methods(root_module, root_module['ns3::PcapFileWrapper'])
register_Ns3Queue_methods(root_module, root_module['ns3::Queue'])
register_Ns3RadiotapHeader_methods(root_module, root_module['ns3::RadiotapHeader'])
+ register_Ns3RedQueue_methods(root_module, root_module['ns3::RedQueue'])
+ register_Ns3RedQueueStats_methods(root_module, root_module['ns3::RedQueue::Stats'])
register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >'])
register_Ns3SimpleRefCount__Ns3AttributeChecker_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeChecker__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
register_Ns3SimpleRefCount__Ns3AttributeValue_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeValue__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeValue, ns3::empty, ns3::DefaultDeleter<ns3::AttributeValue> >'])
@@ -545,6 +559,8 @@
register_Ns3AttributeAccessor_methods(root_module, root_module['ns3::AttributeAccessor'])
register_Ns3AttributeChecker_methods(root_module, root_module['ns3::AttributeChecker'])
register_Ns3AttributeValue_methods(root_module, root_module['ns3::AttributeValue'])
+ register_Ns3BooleanChecker_methods(root_module, root_module['ns3::BooleanChecker'])
+ register_Ns3BooleanValue_methods(root_module, root_module['ns3::BooleanValue'])
register_Ns3CallbackChecker_methods(root_module, root_module['ns3::CallbackChecker'])
register_Ns3CallbackImplBase_methods(root_module, root_module['ns3::CallbackImplBase'])
register_Ns3CallbackValue_methods(root_module, root_module['ns3::CallbackValue'])
@@ -4129,6 +4145,70 @@
[param('uint64_t', 'tsft')])
return
+def register_Ns3RedQueue_methods(root_module, cls):
+ ## red-queue.h (module 'network'): ns3::RedQueue::RedQueue(ns3::RedQueue const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::RedQueue const &', 'arg0')])
+ ## red-queue.h (module 'network'): ns3::RedQueue::RedQueue() [constructor]
+ cls.add_constructor([])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Mode ns3::RedQueue::GetMode() [member function]
+ cls.add_method('GetMode',
+ 'ns3::RedQueue::Mode',
+ [])
+ ## red-queue.h (module 'network'): uint32_t ns3::RedQueue::GetQueueSize() [member function]
+ cls.add_method('GetQueueSize',
+ 'uint32_t',
+ [])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats ns3::RedQueue::GetStats() [member function]
+ cls.add_method('GetStats',
+ 'ns3::RedQueue::Stats',
+ [])
+ ## red-queue.h (module 'network'): static ns3::TypeId ns3::RedQueue::GetTypeId() [member function]
+ cls.add_method('GetTypeId',
+ 'ns3::TypeId',
+ [],
+ is_static=True)
+ ## red-queue.h (module 'network'): void ns3::RedQueue::SetMode(ns3::RedQueue::Mode mode) [member function]
+ cls.add_method('SetMode',
+ 'void',
+ [param('ns3::RedQueue::Mode', 'mode')])
+ ## red-queue.h (module 'network'): void ns3::RedQueue::SetQueueLimit(uint32_t lim) [member function]
+ cls.add_method('SetQueueLimit',
+ 'void',
+ [param('uint32_t', 'lim')])
+ ## red-queue.h (module 'network'): void ns3::RedQueue::SetTh(double minTh, double maxTh) [member function]
+ cls.add_method('SetTh',
+ 'void',
+ [param('double', 'minTh'), param('double', 'maxTh')])
+ ## red-queue.h (module 'network'): ns3::Ptr<ns3::Packet> ns3::RedQueue::DoDequeue() [member function]
+ cls.add_method('DoDequeue',
+ 'ns3::Ptr< ns3::Packet >',
+ [],
+ visibility='private', is_virtual=True)
+ ## red-queue.h (module 'network'): bool ns3::RedQueue::DoEnqueue(ns3::Ptr<ns3::Packet> p) [member function]
+ cls.add_method('DoEnqueue',
+ 'bool',
+ [param('ns3::Ptr< ns3::Packet >', 'p')],
+ visibility='private', is_virtual=True)
+ ## red-queue.h (module 'network'): ns3::Ptr<const ns3::Packet> ns3::RedQueue::DoPeek() const [member function]
+ cls.add_method('DoPeek',
+ 'ns3::Ptr< ns3::Packet const >',
+ [],
+ is_const=True, visibility='private', is_virtual=True)
+ return
+
+def register_Ns3RedQueueStats_methods(root_module, cls):
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::Stats() [constructor]
+ cls.add_constructor([])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::Stats(ns3::RedQueue::Stats const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::RedQueue::Stats const &', 'arg0')])
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::forcedDrop [variable]
+ cls.add_instance_attribute('forcedDrop', 'uint32_t', is_const=False)
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::qLimDrop [variable]
+ cls.add_instance_attribute('qLimDrop', 'uint32_t', is_const=False)
+ ## red-queue.h (module 'network'): ns3::RedQueue::Stats::unforcedDrop [variable]
+ cls.add_instance_attribute('unforcedDrop', 'uint32_t', is_const=False)
+ return
+
def register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, cls):
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >::SimpleRefCount() [constructor]
cls.add_constructor([])
@@ -5022,6 +5102,47 @@
is_pure_virtual=True, is_const=True, is_virtual=True)
return
+def register_Ns3BooleanChecker_methods(root_module, cls):
+ ## boolean.h (module 'core'): ns3::BooleanChecker::BooleanChecker() [constructor]
+ cls.add_constructor([])
+ ## boolean.h (module 'core'): ns3::BooleanChecker::BooleanChecker(ns3::BooleanChecker const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::BooleanChecker const &', 'arg0')])
+ return
+
+def register_Ns3BooleanValue_methods(root_module, cls):
+ cls.add_output_stream_operator()
+ ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue(ns3::BooleanValue const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::BooleanValue const &', 'arg0')])
+ ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue() [constructor]
+ cls.add_constructor([])
+ ## boolean.h (module 'core'): ns3::BooleanValue::BooleanValue(bool value) [constructor]
+ cls.add_constructor([param('bool', 'value')])
+ ## boolean.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::BooleanValue::Copy() const [member function]
+ cls.add_method('Copy',
+ 'ns3::Ptr< ns3::AttributeValue >',
+ [],
+ is_const=True, is_virtual=True)
+ ## boolean.h (module 'core'): bool ns3::BooleanValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+ cls.add_method('DeserializeFromString',
+ 'bool',
+ [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
+ is_virtual=True)
+ ## boolean.h (module 'core'): bool ns3::BooleanValue::Get() const [member function]
+ cls.add_method('Get',
+ 'bool',
+ [],
+ is_const=True)
+ ## boolean.h (module 'core'): std::string ns3::BooleanValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+ cls.add_method('SerializeToString',
+ 'std::string',
+ [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
+ is_const=True, is_virtual=True)
+ ## boolean.h (module 'core'): void ns3::BooleanValue::Set(bool value) [member function]
+ cls.add_method('Set',
+ 'void',
+ [param('bool', 'value')])
+ return
+
def register_Ns3CallbackChecker_methods(root_module, cls):
## callback.h (module 'core'): ns3::CallbackChecker::CallbackChecker() [constructor]
cls.add_constructor([])
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network/examples/droptail_vs_red.cc Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,164 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: John Abraham <john.abraham@gatech.edu>
+ *
+ */
+
+
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/internet-module.h"
+#include "ns3/point-to-point-module.h"
+#include "ns3/applications-module.h"
+#include "ns3/point-to-point-layout-module.h"
+
+#include <iostream>
+#include <iomanip>
+#include <map>
+
+using namespace ns3;
+using namespace std;
+
+
+int main (int argc, char *argv[])
+{
+ uint32_t nLeaf = 5;
+ uint32_t maxPackets = 100;
+ uint32_t modeBytes = 0;
+ double minTh = 50;
+ double maxTh = 80;
+ uint32_t pktSize = 512;
+ std::string appDataRate = "10Mbps";
+ std::string queueType = "DropTail";
+ uint16_t port = 5001;
+ std::string bottleNeckLinkBw = "1Mbps";
+ std::string bottleNeckLinkDelay = "50ms";
+
+ CommandLine cmd;
+ cmd.AddValue ("nLeaf", "Number of left and right side leaf nodes", nLeaf);
+ cmd.AddValue ("maxPackets","Max Packets allowed in the queue", maxPackets);
+ cmd.AddValue ("queueType", "Set Queue type to DropTail or RED", queueType);
+ cmd.AddValue ("appPktSize", "Set OnOff App Packet Size", pktSize);
+ cmd.AddValue ("appDataRate", "Set OnOff App DataRate", appDataRate);
+ cmd.AddValue ("modeBytes", "Set Queue mode to Packets <0> or bytes <1>", modeBytes);
+
+ cmd.AddValue ("redMinTh", "RED queue minimum threshold", minTh);
+ cmd.AddValue ("redMaxTh", "RED queue maximum threshold", maxTh);
+ cmd.Parse (argc,argv);
+
+ if ((queueType != "RED") && (queueType != "DropTail"))
+ {
+ NS_ABORT_MSG ("Invalid queue type: Use --queueType=RED or --queueType=DropTail");
+ }
+
+ Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (pktSize));
+ Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue (appDataRate));
+
+
+ if (!modeBytes)
+ {
+ Config::SetDefault ("ns3::DropTailQueue::Mode", StringValue ("Packets"));
+ Config::SetDefault ("ns3::DropTailQueue::MaxPackets", UintegerValue (maxPackets));
+ Config::SetDefault ("ns3::RedQueue::Mode", StringValue ("Packets"));
+ Config::SetDefault ("ns3::RedQueue::QueueLimit", UintegerValue (maxPackets));
+ }
+ else
+ {
+ Config::SetDefault ("ns3::DropTailQueue::Mode", StringValue ("Bytes"));
+ Config::SetDefault ("ns3::DropTailQueue::MaxBytes", UintegerValue (maxPackets * pktSize));
+ Config::SetDefault ("ns3::RedQueue::Mode", StringValue ("Bytes"));
+ Config::SetDefault ("ns3::RedQueue::QueueLimit", UintegerValue (maxPackets * pktSize));
+ minTh *= pktSize;
+ maxTh *= pktSize;
+ }
+
+ // Create the point-to-point link helpers
+ PointToPointHelper bottleNeckLink;
+ bottleNeckLink.SetDeviceAttribute ("DataRate", StringValue (bottleNeckLinkBw));
+ bottleNeckLink.SetChannelAttribute ("Delay", StringValue (bottleNeckLinkDelay));
+ if (queueType == "RED")
+ {
+ bottleNeckLink.SetQueue ("ns3::RedQueue",
+ "MinTh", DoubleValue (minTh),
+ "MaxTh", DoubleValue (maxTh),
+ "LinkBandwidth", StringValue (bottleNeckLinkBw),
+ "LinkDelay", StringValue (bottleNeckLinkDelay));
+ }
+ PointToPointHelper pointToPointLeaf;
+ pointToPointLeaf.SetDeviceAttribute ("DataRate", StringValue ("10Mbps"));
+ pointToPointLeaf.SetChannelAttribute ("Delay", StringValue ("1ms"));
+
+ PointToPointDumbbellHelper d (nLeaf, pointToPointLeaf,
+ nLeaf, pointToPointLeaf,
+ bottleNeckLink);
+
+ // Install Stack
+ InternetStackHelper stack;
+ d.InstallStack (stack);
+
+ // Assign IP Addresses
+ d.AssignIpv4Addresses (Ipv4AddressHelper ("10.1.1.0", "255.255.255.0"),
+ Ipv4AddressHelper ("10.2.1.0", "255.255.255.0"),
+ Ipv4AddressHelper ("10.3.1.0", "255.255.255.0"));
+
+ // Install on/off app on all right side nodes
+ OnOffHelper clientHelper ("ns3::TcpSocketFactory", Address ());
+ clientHelper.SetAttribute ("OnTime", RandomVariableValue (UniformVariable (0, 1)));
+ clientHelper.SetAttribute ("OffTime", RandomVariableValue (UniformVariable (0, 1)));
+ Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
+ PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", sinkLocalAddress);
+ ApplicationContainer sinkApps;
+ for (uint32_t i = 0; i < d.LeftCount (); ++i)
+ {
+ sinkApps.Add (packetSinkHelper.Install (d.GetLeft (i)));
+ }
+ sinkApps.Start (Seconds (0.0));
+ sinkApps.Stop (Seconds (30.0));
+
+ ApplicationContainer clientApps;
+ for (uint32_t i = 0; i < d.RightCount (); ++i)
+ {
+ // Create an on/off app sending packets to the left side
+ AddressValue remoteAddress (InetSocketAddress (d.GetLeftIpv4Address (i), port));
+ clientHelper.SetAttribute ("Remote", remoteAddress);
+ clientApps.Add (clientHelper.Install (d.GetRight (i)));
+ }
+ clientApps.Start (Seconds (1.0)); // Start 1 second after sink
+ clientApps.Stop (Seconds (15.0)); // Stop before the sink
+
+ Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+
+ std::cout << "Running the simulation" << std::endl;
+ Simulator::Run ();
+
+ uint32_t totalRxBytesCounter = 0;
+ for (uint32_t i = 0; i < sinkApps.GetN (); i++)
+ {
+ Ptr <Application> app = sinkApps.Get (i);
+ Ptr <PacketSink> pktSink = DynamicCast <PacketSink> (app);
+ totalRxBytesCounter += pktSink->GetTotalRx ();
+ }
+ NS_LOG_UNCOND ("----------------------------\nQueue Type:"
+ << queueType
+ << "\nGoodput Bytes/sec:"
+ << totalRxBytesCounter/Simulator::Now ().GetSeconds ());
+ NS_LOG_UNCOND ("----------------------------");
+
+
+ std::cout << "Destroying the simulation" << std::endl;
+ Simulator::Destroy ();
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network/examples/red-tests.cc Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,482 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Marcos Talau <talau@users.sourceforge.net>
+ * Duy Nguyen <duy@soe.ucsc.edu>
+ *
+ */
+
+/**
+ * These validation tests are detailed in http://icir.org/floyd/papers/redsims.ps
+ *
+ * In this code the tests 1, 3, 4 and 5 refer to the tests corresponding to
+ * Figure 1, 3, 4, and 5 respectively from the document mentioned above.
+ */
+
+/** Network topology
+ *
+ * 10Mb/s, 2ms 10Mb/s, 4ms
+ * n0--------------| |---------------n4
+ * | 1.5Mbps/s, 20ms |
+ * n2------------------n3
+ * 10Mb/s, 3ms | | 10Mb/s, 5ms
+ * n1--------------| |---------------n5
+ *
+ *
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/internet-module.h"
+#include "ns3/flow-monitor-helper.h"
+#include "ns3/point-to-point-module.h"
+#include "ns3/applications-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("RedTests");
+
+uint32_t checkTimes;
+double avgQueueSize;
+
+// The times
+double global_start_time;
+double global_stop_time;
+double sink_start_time;
+double sink_stop_time;
+double client_start_time;
+double client_stop_time;
+
+NodeContainer n0n2;
+NodeContainer n1n2;
+NodeContainer n2n3;
+NodeContainer n3n4;
+NodeContainer n3n5;
+
+Ipv4InterfaceContainer i0i2;
+Ipv4InterfaceContainer i1i2;
+Ipv4InterfaceContainer i2i3;
+Ipv4InterfaceContainer i3i4;
+Ipv4InterfaceContainer i3i5;
+
+std::stringstream filePlotQueue;
+std::stringstream filePlotQueueAvg;
+
+void
+CheckQueueSize (Ptr<Queue> queue)
+{
+ uint32_t qSize = StaticCast<RedQueue> (queue)->GetQueueSize ();
+
+ avgQueueSize += qSize;
+ checkTimes++;
+
+ // check queue size every 1/100 of a second
+ Simulator::Schedule (Seconds (0.01), &CheckQueueSize, queue);
+
+ std::ofstream fPlotQueue (filePlotQueue.str ().c_str (), std::ios::out|std::ios::app);
+ fPlotQueue << Simulator::Now ().GetSeconds () << " " << qSize << std::endl;
+ fPlotQueue.close ();
+
+ std::ofstream fPlotQueueAvg (filePlotQueueAvg.str ().c_str (), std::ios::out|std::ios::app);
+ fPlotQueueAvg << Simulator::Now ().GetSeconds () << " " << avgQueueSize / checkTimes << std::endl;
+ fPlotQueueAvg.close ();
+}
+
+void
+BuildAppsTest (uint32_t test)
+{
+ if ( (test == 1) || (test == 3) )
+ {
+ // SINK is in the right side
+ uint16_t port = 50000;
+ Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
+ PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory", sinkLocalAddress);
+ ApplicationContainer sinkApp = sinkHelper.Install (n3n4.Get (1));
+ sinkApp.Start (Seconds (sink_start_time));
+ sinkApp.Stop (Seconds (sink_stop_time));
+
+ // Connection one
+ // Clients are in left side
+ /*
+ * Create the OnOff applications to send TCP to the server
+ * onoffhelper is a client that send data to TCP destination
+ */
+ OnOffHelper clientHelper1 ("ns3::TcpSocketFactory", Address ());
+ clientHelper1.SetAttribute
+ ("OnTime", RandomVariableValue (ConstantVariable (1)));
+ clientHelper1.SetAttribute
+ ("OffTime", RandomVariableValue (ConstantVariable (0)));
+ clientHelper1.SetAttribute
+ ("DataRate", DataRateValue (DataRate ("10Mb/s")));
+ clientHelper1.SetAttribute
+ ("PacketSize", UintegerValue (1000));
+
+ ApplicationContainer clientApps1;
+ AddressValue remoteAddress
+ (InetSocketAddress (i3i4.GetAddress (1), port));
+ clientHelper1.SetAttribute ("Remote", remoteAddress);
+ clientApps1.Add (clientHelper1.Install (n0n2.Get (0)));
+ clientApps1.Start (Seconds (client_start_time));
+ clientApps1.Stop (Seconds (client_stop_time));
+
+ // Connection two
+ OnOffHelper clientHelper2 ("ns3::TcpSocketFactory", Address ());
+ clientHelper2.SetAttribute
+ ("OnTime", RandomVariableValue (ConstantVariable (1)));
+ clientHelper2.SetAttribute
+ ("OffTime", RandomVariableValue (ConstantVariable (0)));
+ clientHelper2.SetAttribute
+ ("DataRate", DataRateValue (DataRate ("10Mb/s")));
+ clientHelper2.SetAttribute
+ ("PacketSize", UintegerValue (1000));
+
+ ApplicationContainer clientApps2;
+ clientHelper2.SetAttribute ("Remote", remoteAddress);
+ clientApps2.Add (clientHelper2.Install (n1n2.Get (0)));
+ clientApps2.Start (Seconds (3.0));
+ clientApps2.Stop (Seconds (client_stop_time));
+ }
+ else // 4 or 5
+ {
+ // SINKs
+ // #1
+ uint16_t port1 = 50001;
+ Address sinkLocalAddress1 (InetSocketAddress (Ipv4Address::GetAny (), port1));
+ PacketSinkHelper sinkHelper1 ("ns3::TcpSocketFactory", sinkLocalAddress1);
+ ApplicationContainer sinkApp1 = sinkHelper1.Install (n3n4.Get (1));
+ sinkApp1.Start (Seconds (sink_start_time));
+ sinkApp1.Stop (Seconds (sink_stop_time));
+ // #2
+ uint16_t port2 = 50002;
+ Address sinkLocalAddress2 (InetSocketAddress (Ipv4Address::GetAny (), port2));
+ PacketSinkHelper sinkHelper2 ("ns3::TcpSocketFactory", sinkLocalAddress2);
+ ApplicationContainer sinkApp2 = sinkHelper2.Install (n3n5.Get (1));
+ sinkApp2.Start (Seconds (sink_start_time));
+ sinkApp2.Stop (Seconds (sink_stop_time));
+ // #3
+ uint16_t port3 = 50003;
+ Address sinkLocalAddress3 (InetSocketAddress (Ipv4Address::GetAny (), port3));
+ PacketSinkHelper sinkHelper3 ("ns3::TcpSocketFactory", sinkLocalAddress3);
+ ApplicationContainer sinkApp3 = sinkHelper3.Install (n0n2.Get (0));
+ sinkApp3.Start (Seconds (sink_start_time));
+ sinkApp3.Stop (Seconds (sink_stop_time));
+ // #4
+ uint16_t port4 = 50004;
+ Address sinkLocalAddress4 (InetSocketAddress (Ipv4Address::GetAny (), port4));
+ PacketSinkHelper sinkHelper4 ("ns3::TcpSocketFactory", sinkLocalAddress4);
+ ApplicationContainer sinkApp4 = sinkHelper4.Install (n1n2.Get (0));
+ sinkApp4.Start (Seconds (sink_start_time));
+ sinkApp4.Stop (Seconds (sink_stop_time));
+
+ // Connection #1
+ /*
+ * Create the OnOff applications to send TCP to the server
+ * onoffhelper is a client that send data to TCP destination
+ */
+ OnOffHelper clientHelper1 ("ns3::TcpSocketFactory", Address ());
+ clientHelper1.SetAttribute
+ ("OnTime", RandomVariableValue (ConstantVariable (1)));
+ clientHelper1.SetAttribute
+ ("OffTime", RandomVariableValue (ConstantVariable (0)));
+ clientHelper1.SetAttribute
+ ("DataRate", DataRateValue (DataRate ("10Mb/s")));
+ clientHelper1.SetAttribute
+ ("PacketSize", UintegerValue (1000));
+
+ ApplicationContainer clientApps1;
+ AddressValue remoteAddress1
+ (InetSocketAddress (i3i4.GetAddress (1), port1));
+ clientHelper1.SetAttribute ("Remote", remoteAddress1);
+ clientApps1.Add (clientHelper1.Install (n0n2.Get (0)));
+ clientApps1.Start (Seconds (client_start_time));
+ clientApps1.Stop (Seconds (client_stop_time));
+
+ // Connection #2
+ OnOffHelper clientHelper2 ("ns3::TcpSocketFactory", Address ());
+ clientHelper2.SetAttribute
+ ("OnTime", RandomVariableValue (ConstantVariable (1)));
+ clientHelper2.SetAttribute
+ ("OffTime", RandomVariableValue (ConstantVariable (0)));
+ clientHelper2.SetAttribute
+ ("DataRate", DataRateValue (DataRate ("10Mb/s")));
+ clientHelper2.SetAttribute
+ ("PacketSize", UintegerValue (1000));
+
+ ApplicationContainer clientApps2;
+ AddressValue remoteAddress2
+ (InetSocketAddress (i3i5.GetAddress (1), port2));
+ clientHelper2.SetAttribute ("Remote", remoteAddress2);
+ clientApps2.Add (clientHelper2.Install (n1n2.Get (0)));
+ clientApps2.Start (Seconds (2.0));
+ clientApps2.Stop (Seconds (client_stop_time));
+
+ // Connection #3
+ OnOffHelper clientHelper3 ("ns3::TcpSocketFactory", Address ());
+ clientHelper3.SetAttribute
+ ("OnTime", RandomVariableValue (ConstantVariable (1)));
+ clientHelper3.SetAttribute
+ ("OffTime", RandomVariableValue (ConstantVariable (0)));
+ clientHelper3.SetAttribute
+ ("DataRate", DataRateValue (DataRate ("10Mb/s")));
+ clientHelper3.SetAttribute
+ ("PacketSize", UintegerValue (1000));
+
+ ApplicationContainer clientApps3;
+ AddressValue remoteAddress3
+ (InetSocketAddress (i0i2.GetAddress (0), port3));
+ clientHelper3.SetAttribute ("Remote", remoteAddress3);
+ clientApps3.Add (clientHelper3.Install (n3n4.Get (1)));
+ clientApps3.Start (Seconds (3.5));
+ clientApps3.Stop (Seconds (client_stop_time));
+
+ // Connection #4
+ OnOffHelper clientHelper4 ("ns3::TcpSocketFactory", Address ());
+ clientHelper4.SetAttribute
+ ("OnTime", RandomVariableValue (ConstantVariable (1)));
+ clientHelper4.SetAttribute
+ ("OffTime", RandomVariableValue (ConstantVariable (0)));
+ clientHelper4.SetAttribute
+ ("DataRate", DataRateValue (DataRate ("40b/s")));
+ clientHelper4.SetAttribute
+ ("PacketSize", UintegerValue (5 * 8)); // telnet
+
+ ApplicationContainer clientApps4;
+ AddressValue remoteAddress4
+ (InetSocketAddress (i1i2.GetAddress (0), port4));
+ clientHelper4.SetAttribute ("Remote", remoteAddress4);
+ clientApps4.Add (clientHelper4.Install (n3n5.Get (1)));
+ clientApps4.Start (Seconds (1.0));
+ clientApps4.Stop (Seconds (client_stop_time));
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ // LogComponentEnable ("RedExamples", LOG_LEVEL_INFO);
+ // LogComponentEnable ("TcpNewReno", LOG_LEVEL_INFO);
+ // LogComponentEnable ("RedQueue", LOG_LEVEL_FUNCTION);
+ LogComponentEnable ("RedQueue", LOG_LEVEL_INFO);
+
+ uint32_t redTest;
+ std::string redLinkDataRate = "1.5Mbps";
+ std::string redLinkDelay = "20ms";
+
+ std::string pathOut;
+ bool writeForPlot = false;
+ bool writePcap = false;
+ bool flowMonitor = false;
+
+ bool printRedStats = true;
+
+ global_start_time = 0.0;
+ global_stop_time = 11;
+ sink_start_time = global_start_time;
+ sink_stop_time = global_stop_time + 3.0;
+ client_start_time = sink_start_time + 0.2;
+ client_stop_time = global_stop_time - 2.0;
+
+ // Configuration and command line parameter parsing
+ redTest = 1;
+ // Will only save in the directory if enable opts below
+ pathOut = "."; // Current directory
+ CommandLine cmd;
+ cmd.AddValue ("testNumber", "Run test 1, 3, 4 or 5", redTest);
+ cmd.AddValue ("pathOut", "Path to save results from --writeForPlot/--writePcap/--writeFlowMonitor", pathOut);
+ cmd.AddValue ("writeForPlot", "<0/1> to write results for plot (gnuplot)", writeForPlot);
+ cmd.AddValue ("writePcap", "<0/1> to write results in pcapfile", writePcap);
+ cmd.AddValue ("writeFlowMonitor", "<0/1> to enable Flow Monitor and write their results", flowMonitor);
+
+ cmd.Parse (argc, argv);
+ if ( (redTest != 1) && (redTest != 3) && (redTest != 4) && (redTest != 5) )
+ {
+ NS_ABORT_MSG ("Invalid test number. Supported tests are 1, 3, 4 or 5");
+ }
+
+ NS_LOG_INFO ("Create nodes");
+ NodeContainer c;
+ c.Create (6);
+ Names::Add ( "N0", c.Get (0));
+ Names::Add ( "N1", c.Get (1));
+ Names::Add ( "N2", c.Get (2));
+ Names::Add ( "N3", c.Get (3));
+ Names::Add ( "N4", c.Get (4));
+ Names::Add ( "N5", c.Get (5));
+ n0n2 = NodeContainer (c.Get (0), c.Get (2));
+ n1n2 = NodeContainer (c.Get (1), c.Get (2));
+ n2n3 = NodeContainer (c.Get (2), c.Get (3));
+ n3n4 = NodeContainer (c.Get (3), c.Get (4));
+ n3n5 = NodeContainer (c.Get (3), c.Get (5));
+
+ Config::SetDefault ("ns3::TcpL4Protocol::SocketType", StringValue ("ns3::TcpReno"));
+ // 42 = headers size
+ Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (1000 - 42));
+ Config::SetDefault ("ns3::TcpSocket::DelAckCount", UintegerValue (1));
+ GlobalValue::Bind ("ChecksumEnabled", BooleanValue (false));
+
+ uint32_t meanPktSize = 500;
+
+ // RED params
+ NS_LOG_INFO ("Set RED params");
+ Config::SetDefault ("ns3::RedQueue::Mode", StringValue ("Packets"));
+ Config::SetDefault ("ns3::RedQueue::MeanPktSize", UintegerValue (meanPktSize));
+ Config::SetDefault ("ns3::RedQueue::Wait", BooleanValue (true));
+ Config::SetDefault ("ns3::RedQueue::Gentle", BooleanValue (true));
+ Config::SetDefault ("ns3::RedQueue::QW", DoubleValue (0.002));
+ Config::SetDefault ("ns3::RedQueue::MinTh", DoubleValue (5));
+ Config::SetDefault ("ns3::RedQueue::MaxTh", DoubleValue (15));
+ Config::SetDefault ("ns3::RedQueue::QueueLimit", UintegerValue (25));
+
+ if (redTest == 3) // test like 1, but with bad params
+ {
+ Config::SetDefault ("ns3::RedQueue::MaxTh", DoubleValue (10));
+ Config::SetDefault ("ns3::RedQueue::QW", DoubleValue (0.003));
+ }
+ else if (redTest == 5) // test 5, same of test 4, but in byte mode
+ {
+ Config::SetDefault ("ns3::RedQueue::Mode", StringValue ("Bytes"));
+ Config::SetDefault ("ns3::RedQueue::Ns1Compat", BooleanValue (true));
+ Config::SetDefault ("ns3::RedQueue::MinTh", DoubleValue (5 * meanPktSize));
+ Config::SetDefault ("ns3::RedQueue::MaxTh", DoubleValue (15 * meanPktSize));
+ Config::SetDefault ("ns3::RedQueue::QueueLimit", UintegerValue (25 * meanPktSize));
+ }
+
+ NS_LOG_INFO ("Install internet stack on all nodes.");
+ InternetStackHelper internet;
+ internet.Install (c);
+
+ NS_LOG_INFO ("Create channels");
+ PointToPointHelper p2p;
+
+ p2p.SetQueue ("ns3::DropTailQueue");
+ p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps"));
+ p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
+ NetDeviceContainer devn0n2 = p2p.Install (n0n2);
+
+ p2p.SetQueue ("ns3::DropTailQueue");
+ p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps"));
+ p2p.SetChannelAttribute ("Delay", StringValue ("3ms"));
+ NetDeviceContainer devn1n2 = p2p.Install (n1n2);
+
+ p2p.SetQueue ("ns3::RedQueue", // only backbone link has RED queue
+ "LinkBandwidth", StringValue (redLinkDataRate),
+ "LinkDelay", StringValue (redLinkDelay));
+ p2p.SetDeviceAttribute ("DataRate", StringValue (redLinkDataRate));
+ p2p.SetChannelAttribute ("Delay", StringValue (redLinkDelay));
+ NetDeviceContainer devn2n3 = p2p.Install (n2n3);
+
+ p2p.SetQueue ("ns3::DropTailQueue");
+ p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps"));
+ p2p.SetChannelAttribute ("Delay", StringValue ("4ms"));
+ NetDeviceContainer devn3n4 = p2p.Install (n3n4);
+
+ p2p.SetQueue ("ns3::DropTailQueue");
+ p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps"));
+ p2p.SetChannelAttribute ("Delay", StringValue ("5ms"));
+ NetDeviceContainer devn3n5 = p2p.Install (n3n5);
+
+ NS_LOG_INFO ("Assign IP Addresses");
+ Ipv4AddressHelper ipv4;
+
+ ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+ i0i2 = ipv4.Assign (devn0n2);
+
+ ipv4.SetBase ("10.1.2.0", "255.255.255.0");
+ i1i2 = ipv4.Assign (devn1n2);
+
+ ipv4.SetBase ("10.1.3.0", "255.255.255.0");
+ i2i3 = ipv4.Assign (devn2n3);
+
+ ipv4.SetBase ("10.1.4.0", "255.255.255.0");
+ i3i4 = ipv4.Assign (devn3n4);
+
+ ipv4.SetBase ("10.1.5.0", "255.255.255.0");
+ i3i5 = ipv4.Assign (devn3n5);
+
+ // Set up the routing
+ Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+
+ if (redTest == 5)
+ {
+ // like in ns2 test, r2 -> r1, have a queue in packet mode
+ Ptr<PointToPointNetDevice> nd = StaticCast<PointToPointNetDevice> (devn2n3.Get (1));
+ Ptr<Queue> queue = nd->GetQueue ();
+
+ StaticCast<RedQueue> (queue)->SetMode (RedQueue::PACKETS);
+ StaticCast<RedQueue> (queue)->SetTh (5, 15);
+ StaticCast<RedQueue> (queue)->SetQueueLimit (25);
+ }
+
+ BuildAppsTest (redTest);
+
+ if (writePcap)
+ {
+ PointToPointHelper ptp;
+ std::stringstream stmp;
+ stmp << pathOut << "/red";
+ ptp.EnablePcapAll (stmp.str ().c_str ());
+ }
+
+ Ptr<FlowMonitor> flowmon;
+ if (flowMonitor)
+ {
+ FlowMonitorHelper flowmonHelper;
+ flowmon = flowmonHelper.InstallAll ();
+ }
+
+ if (writeForPlot)
+ {
+ filePlotQueue << pathOut << "/" << "red-queue.plotme";
+ filePlotQueueAvg << pathOut << "/" << "red-queue_avg.plotme";
+
+ remove (filePlotQueue.str ().c_str ());
+ remove (filePlotQueueAvg.str ().c_str ());
+ Ptr<PointToPointNetDevice> nd = StaticCast<PointToPointNetDevice> (devn2n3.Get (0));
+ Ptr<Queue> queue = nd->GetQueue ();
+ Simulator::ScheduleNow (&CheckQueueSize, queue);
+ }
+
+ Simulator::Stop (Seconds (sink_stop_time));
+ Simulator::Run ();
+
+ if (flowMonitor)
+ {
+ std::stringstream stmp;
+ stmp << pathOut << "/red.flowmon";
+
+ flowmon->SerializeToXmlFile (stmp.str ().c_str (), false, false);
+ }
+
+ if (printRedStats)
+ {
+ Ptr<PointToPointNetDevice> nd = StaticCast<PointToPointNetDevice> (devn2n3.Get (0));
+ RedQueue::Stats st = StaticCast<RedQueue> (nd->GetQueue ())->GetStats ();
+ std::cout << "*** RED stats from Node 2 queue ***" << std::endl;
+ std::cout << "\t " << st.unforcedDrop << " drops due prob mark" << std::endl;
+ std::cout << "\t " << st.forcedDrop << " drops due hard mark" << std::endl;
+ std::cout << "\t " << st.qLimDrop << " drops due queue full" << std::endl;
+
+ nd = StaticCast<PointToPointNetDevice> (devn2n3.Get (1));
+ st = StaticCast<RedQueue> (nd->GetQueue ())->GetStats ();
+ std::cout << "*** RED stats from Node 3 queue ***" << std::endl;
+ std::cout << "\t " << st.unforcedDrop << " drops due prob mark" << std::endl;
+ std::cout << "\t " << st.forcedDrop << " drops due hard mark" << std::endl;
+ std::cout << "\t " << st.qLimDrop << " drops due queue full" << std::endl;
+ }
+
+ Simulator::Destroy ();
+
+ return 0;
+}
--- a/src/network/examples/wscript Fri Dec 16 18:50:05 2011 +0100
+++ b/src/network/examples/wscript Fri Dec 16 18:51:18 2011 +0100
@@ -10,3 +10,8 @@
obj = bld.create_ns3_program('main-packet-tag', ['network'])
obj.source = 'main-packet-tag.cc'
+ obj = bld.create_ns3_program('red-tests', ['point-to-point', 'internet', 'applications', 'flow-monitor'])
+ obj.source = 'red-tests.cc'
+
+ obj = bld.create_ns3_program('droptail_vs_red', ['point-to-point', 'point-to-point-layout', 'internet', 'applications'])
+ obj.source = 'droptail_vs_red.cc'
--- a/src/network/model/packet.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/network/model/packet.h Fri Dec 16 18:51:18 2011 +0100
@@ -168,9 +168,10 @@
* were serialized in the byte buffer. The maintenance of metadata is
* optional and disabled by default. To enable it, you must call
* Packet::EnablePrinting and this will allow you to get non-empty
- * output from Packet::Print and Packet::Print. If you wish to only enable
+ * output from Packet::Print. If you wish to only enable
* checking of metadata, and do not need any printing capability, you can
- * call Packet::EnableChecking: its runtime cost is lower than Packet::EnablePrinting.
+ * call Packet::EnableChecking: its runtime cost is lower than
+ * Packet::EnablePrinting.
*
* - The set of tags contain simulation-specific information which cannot
* be stored in the packet byte buffer because the protocol headers or trailers
@@ -415,7 +416,7 @@
/**
* By default, packets do not keep around enough metadata to
* perform the operations requested by the Print methods. If you
- * want to be able to invoke any of the two ::Print methods,
+ * want to be able the Packet::Print method,
* you need to invoke this method at least once during the
* simulation setup and before any packet is created.
*/
--- a/src/network/test/examples-to-run.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/network/test/examples-to-run.py Fri Dec 16 18:51:18 2011 +0100
@@ -10,6 +10,7 @@
cpp_examples = [
("main-packet-header", "True", "True"),
("main-packet-tag", "True", "True"),
+ ("red-tests", "True", "True"),
]
# A list of Python examples to run in order to ensure that they remain
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network/test/red-queue-test-suite.cc Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,283 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright © 2011 Marcos Talau
+ *
+ * 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: Marcos Talau (talau@users.sourceforge.net)
+ *
+ */
+
+#include "ns3/test.h"
+#include "ns3/red-queue.h"
+#include "ns3/uinteger.h"
+#include "ns3/string.h"
+#include "ns3/double.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+
+namespace ns3 {
+
+class RedQueueTestCase : public TestCase
+{
+public:
+ RedQueueTestCase ();
+ virtual void DoRun (void);
+private:
+ void Enqueue (Ptr<RedQueue> queue, uint32_t size, uint32_t nPkt);
+ void RunRedTest (StringValue mode);
+};
+
+RedQueueTestCase::RedQueueTestCase ()
+ : TestCase ("Sanity check on the red queue implementation")
+{
+}
+
+void
+RedQueueTestCase::RunRedTest (StringValue mode)
+{
+ uint32_t pktSize = 0;
+ // 1 for packets; pktSize for bytes
+ uint32_t modeSize = 1;
+ double minTh = 2;
+ double maxTh = 5;
+ uint32_t qSize = 8;
+ Ptr<RedQueue> queue = CreateObject<RedQueue> ();
+
+ // test 1: simple enqueue/dequeue with no drops
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
+ "Verify that we can actually set the attribute Mode");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
+ "Verify that we can actually set the attribute MinTh");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
+ "Verify that we can actually set the attribute MaxTh");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
+ "Verify that we can actually set the attribute QueueLimit");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.002)), true,
+ "Verify that we can actually set the attribute QW");
+
+ if (queue->GetMode () == RedQueue::BYTES)
+ {
+ pktSize = 1000;
+ modeSize = pktSize;
+ queue->SetTh (minTh * pktSize, maxTh * pktSize);
+ queue->SetQueueLimit (qSize * pktSize);
+ }
+
+ Ptr<Packet> p1, p2, p3, p4, p5, p6, p7, p8;
+ p1 = Create<Packet> (pktSize);
+ p2 = Create<Packet> (pktSize);
+ p3 = Create<Packet> (pktSize);
+ p4 = Create<Packet> (pktSize);
+ p5 = Create<Packet> (pktSize);
+ p6 = Create<Packet> (pktSize);
+ p7 = Create<Packet> (pktSize);
+ p8 = Create<Packet> (pktSize);
+
+ NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 0 * modeSize, "There should be no packets in there");
+ queue->Enqueue (p1);
+ NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 1 * modeSize, "There should be one packet in there");
+ queue->Enqueue (p2);
+ NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 2 * modeSize, "There should be two packets in there");
+ queue->Enqueue (p3);
+ queue->Enqueue (p4);
+ queue->Enqueue (p5);
+ queue->Enqueue (p6);
+ queue->Enqueue (p7);
+ queue->Enqueue (p8);
+ NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 8 * modeSize, "There should be eight packets in there");
+
+ Ptr<Packet> p;
+
+ p = queue->Dequeue ();
+ NS_TEST_EXPECT_MSG_EQ ((p != 0), true, "I want to remove the first packet");
+ NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 7 * modeSize, "There should be seven packets in there");
+ NS_TEST_EXPECT_MSG_EQ (p->GetUid (), p1->GetUid (), "was this the first packet ?");
+
+ p = queue->Dequeue ();
+ NS_TEST_EXPECT_MSG_EQ ((p != 0), true, "I want to remove the second packet");
+ NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 6 * modeSize, "There should be six packet in there");
+ NS_TEST_EXPECT_MSG_EQ (p->GetUid (), p2->GetUid (), "Was this the second packet ?");
+
+ p = queue->Dequeue ();
+ NS_TEST_EXPECT_MSG_EQ ((p != 0), true, "I want to remove the third packet");
+ NS_TEST_EXPECT_MSG_EQ (queue->GetQueueSize (), 5 * modeSize, "There should be five packets in there");
+ NS_TEST_EXPECT_MSG_EQ (p->GetUid (), p3->GetUid (), "Was this the third packet ?");
+
+ p = queue->Dequeue ();
+ p = queue->Dequeue ();
+ p = queue->Dequeue ();
+ p = queue->Dequeue ();
+ p = queue->Dequeue ();
+
+ p = queue->Dequeue ();
+ NS_TEST_EXPECT_MSG_EQ ((p == 0), true, "There are really no packets in there");
+
+
+ // test 2: more data, but with no drops
+ queue = CreateObject<RedQueue> ();
+ minTh = 70 * modeSize;
+ maxTh = 150 * modeSize;
+ qSize = 300 * modeSize;
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
+ "Verify that we can actually set the attribute Mode");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
+ "Verify that we can actually set the attribute MinTh");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
+ "Verify that we can actually set the attribute MaxTh");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
+ "Verify that we can actually set the attribute QueueLimit");
+ Enqueue (queue, pktSize, 300);
+ RedQueue::Stats st = StaticCast<RedQueue> (queue)->GetStats ();
+ NS_TEST_EXPECT_MSG_EQ (st.unforcedDrop, 0, "There should zero dropped packets due probability mark");
+ NS_TEST_EXPECT_MSG_EQ (st.forcedDrop, 0, "There should zero dropped packets due hardmark mark");
+ NS_TEST_EXPECT_MSG_EQ (st.qLimDrop, 0, "There should zero dropped packets due queue full");
+
+ // save number of drops from tests
+ struct d {
+ uint32_t test3;
+ uint32_t test4;
+ uint32_t test5;
+ uint32_t test6;
+ uint32_t test7;
+ } drop;
+
+
+ // test 3: more data, now drops due QW change
+ queue = CreateObject<RedQueue> ();
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
+ "Verify that we can actually set the attribute Mode");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
+ "Verify that we can actually set the attribute MinTh");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
+ "Verify that we can actually set the attribute MaxTh");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
+ "Verify that we can actually set the attribute QueueLimit");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
+ "Verify that we can actually set the attribute QW");
+ Enqueue (queue, pktSize, 300);
+ st = StaticCast<RedQueue> (queue)->GetStats ();
+ drop.test3 = st.unforcedDrop + st.forcedDrop + st.qLimDrop;
+ NS_TEST_EXPECT_MSG_NE (drop.test3, 0, "There should be some dropped packets");
+
+
+ // test 4: reduced maxTh, this causes more drops
+ maxTh = 100 * modeSize;
+ queue = CreateObject<RedQueue> ();
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
+ "Verify that we can actually set the attribute Mode");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
+ "Verify that we can actually set the attribute MinTh");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
+ "Verify that we can actually set the attribute MaxTh");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
+ "Verify that we can actually set the attribute QueueLimit");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
+ "Verify that we can actually set the attribute QW");
+ Enqueue (queue, pktSize, 300);
+ st = StaticCast<RedQueue> (queue)->GetStats ();
+ drop.test4 = st.unforcedDrop + st.forcedDrop + st.qLimDrop;
+ NS_TEST_EXPECT_MSG_GT (drop.test4, drop.test3, "Test 4 should have more drops than test 3");
+
+
+ // test 5: change drop probability to a high value (LInterm)
+ maxTh = 150 * modeSize;
+ queue = CreateObject<RedQueue> ();
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
+ "Verify that we can actually set the attribute Mode");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
+ "Verify that we can actually set the attribute MinTh");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
+ "Verify that we can actually set the attribute MaxTh");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
+ "Verify that we can actually set the attribute QueueLimit");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
+ "Verify that we can actually set the attribute QW");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("LInterm", DoubleValue (5)), true,
+ "Verify that we can actually set the attribute LInterm");
+ Enqueue (queue, pktSize, 300);
+ st = StaticCast<RedQueue> (queue)->GetStats ();
+ drop.test5 = st.unforcedDrop + st.forcedDrop + st.qLimDrop;
+ NS_TEST_EXPECT_MSG_GT (drop.test5, drop.test3, "Test 5 should have more drops than test 3");
+
+
+ // test 6: disable Gentle param
+ queue = CreateObject<RedQueue> ();
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
+ "Verify that we can actually set the attribute Mode");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
+ "Verify that we can actually set the attribute MinTh");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
+ "Verify that we can actually set the attribute MaxTh");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
+ "Verify that we can actually set the attribute QueueLimit");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
+ "Verify that we can actually set the attribute QW");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Gentle", BooleanValue (false)), true,
+ "Verify that we can actually set the attribute Gentle");
+ Enqueue (queue, pktSize, 300);
+ st = StaticCast<RedQueue> (queue)->GetStats ();
+ drop.test6 = st.unforcedDrop + st.forcedDrop + st.qLimDrop;
+ NS_TEST_EXPECT_MSG_GT (drop.test6, drop.test3, "Test 6 should have more drops than test 3");
+
+
+ // test 7: disable Wait param
+ queue = CreateObject<RedQueue> ();
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Mode", mode), true,
+ "Verify that we can actually set the attribute Mode");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MinTh", DoubleValue (minTh)), true,
+ "Verify that we can actually set the attribute MinTh");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxTh", DoubleValue (maxTh)), true,
+ "Verify that we can actually set the attribute MaxTh");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QueueLimit", UintegerValue (qSize)), true,
+ "Verify that we can actually set the attribute QueueLimit");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("QW", DoubleValue (0.020)), true,
+ "Verify that we can actually set the attribute QW");
+ NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("Wait", BooleanValue (false)), true,
+ "Verify that we can actually set the attribute Wait");
+ Enqueue (queue, pktSize, 300);
+ st = StaticCast<RedQueue> (queue)->GetStats ();
+ drop.test7 = st.unforcedDrop + st.forcedDrop + st.qLimDrop;
+ NS_TEST_EXPECT_MSG_GT (drop.test7, drop.test3, "Test 7 should have more drops than test 3");
+}
+
+void
+RedQueueTestCase::Enqueue (Ptr<RedQueue> queue, uint32_t size, uint32_t nPkt)
+{
+ for (uint32_t i = 0; i < nPkt; i++)
+ {
+ queue->Enqueue (Create<Packet> (size));
+ }
+}
+
+void
+RedQueueTestCase::DoRun (void)
+{
+ RunRedTest (StringValue ("Packets"));
+ RunRedTest (StringValue ("Bytes"));
+ Simulator::Destroy ();
+
+}
+
+static class RedQueueTestSuite : public TestSuite
+{
+public:
+ RedQueueTestSuite ()
+ : TestSuite ("red-queue", UNIT)
+ {
+ AddTestCase (new RedQueueTestCase ());
+ }
+} g_redQueueTestSuite;
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network/utils/red-queue.cc Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,653 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This code was ported from NS-2.34, with licence:
+ *
+ * Copyright (c) 1990-1997 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *
+ * This port:
+ *
+ * Copyright © 2011 Marcos Talau
+ *
+ * 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: Marcos Talau (talau@users.sourceforge.net)
+ *
+ * Thanks to: Duy Nguyen<duy@soe.ucsc.edu> by RED efforts in NS3
+ *
+ */
+
+/*
+ * PORT NOTE: Almost all comments have also been ported from NS-2
+ */
+
+#include "ns3/log.h"
+#include "ns3/enum.h"
+#include "ns3/uinteger.h"
+#include "ns3/double.h"
+#include "ns3/simulator.h"
+#include "ns3/abort.h"
+#include "red-queue.h"
+
+NS_LOG_COMPONENT_DEFINE ("RedQueue");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (RedQueue);
+
+TypeId RedQueue::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::RedQueue")
+ .SetParent<Queue> ()
+ .AddConstructor<RedQueue> ()
+ .AddAttribute ("Mode",
+ "Bytes or packets",
+ EnumValue (PACKETS),
+ MakeEnumAccessor (&RedQueue::SetMode),
+ MakeEnumChecker (BYTES, "Bytes",
+ PACKETS, "Packets"))
+ .AddAttribute ("MeanPktSize",
+ "Average of packet size",
+ UintegerValue (500),
+ MakeUintegerAccessor (&RedQueue::m_meanPktSize),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("IdlePktSize",
+ "Average packet size used during idle times. Used when m_cautions = 3",
+ UintegerValue (0),
+ MakeUintegerAccessor (&RedQueue::m_idlePktSize),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("Wait",
+ "True for waiting between dropped packets",
+ BooleanValue (true),
+ MakeBooleanAccessor (&RedQueue::m_isWait),
+ MakeBooleanChecker ())
+ .AddAttribute ("Gentle",
+ "True to increases dropping probability slowly when average queue exceeds maxthresh",
+ BooleanValue (true),
+ MakeBooleanAccessor (&RedQueue::m_isGentle),
+ MakeBooleanChecker ())
+ .AddAttribute ("MinTh",
+ "Minimum average length threshold in packets/bytes",
+ DoubleValue (5),
+ MakeDoubleAccessor (&RedQueue::m_minTh),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("MaxTh",
+ "Maximum average length threshold in packets/bytes",
+ DoubleValue (15),
+ MakeDoubleAccessor (&RedQueue::m_maxTh),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("QueueLimit",
+ "Queue limit in bytes/packets",
+ UintegerValue (25),
+ MakeUintegerAccessor (&RedQueue::m_queueLimit),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("QW",
+ "Queue weight related to the exponential weighted moving average (EWMA)",
+ DoubleValue (0.002),
+ MakeDoubleAccessor (&RedQueue::m_qW),
+ MakeDoubleChecker <double> ())
+ .AddAttribute ("LInterm",
+ "The maximum probability of dropping a packet",
+ DoubleValue (50),
+ MakeDoubleAccessor (&RedQueue::m_lInterm),
+ MakeDoubleChecker <double> ())
+ .AddAttribute ("Ns1Compat",
+ "NS-1 compatibility",
+ BooleanValue (false),
+ MakeBooleanAccessor (&RedQueue::m_isNs1Compat),
+ MakeBooleanChecker ())
+ .AddAttribute ("LinkBandwidth",
+ "The RED link bandwidth",
+ DataRateValue (DataRate ("1.5Mbps")),
+ MakeDataRateAccessor (&RedQueue::m_linkBandwidth),
+ MakeDataRateChecker ())
+ .AddAttribute ("LinkDelay",
+ "The RED link delay",
+ TimeValue (MilliSeconds (20)),
+ MakeTimeAccessor (&RedQueue::m_linkDelay),
+ MakeTimeChecker ())
+ ;
+
+ return tid;
+}
+
+RedQueue::RedQueue () :
+ Queue (),
+ m_packets (),
+ m_bytesInQueue (0),
+ m_hasRedStarted (false)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+RedQueue::~RedQueue ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+RedQueue::SetMode (enum Mode mode)
+{
+ NS_LOG_FUNCTION (mode);
+ m_mode = mode;
+}
+
+RedQueue::Mode
+RedQueue::GetMode (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_mode;
+}
+
+void
+RedQueue::SetQueueLimit (uint32_t lim)
+{
+ NS_LOG_FUNCTION (lim);
+ m_queueLimit = lim;
+}
+
+void
+RedQueue::SetTh (double minTh, double maxTh)
+{
+ NS_LOG_FUNCTION (this << minTh << maxTh);
+ NS_ASSERT (minTh <= maxTh);
+ m_minTh = minTh;
+ m_maxTh = maxTh;
+}
+
+RedQueue::Stats
+RedQueue::GetStats ()
+{
+ return m_stats;
+}
+
+bool
+RedQueue::DoEnqueue (Ptr<Packet> p)
+{
+ NS_LOG_FUNCTION (this << p);
+
+ if (!m_hasRedStarted )
+ {
+ NS_LOG_INFO ("Initializing RED params.");
+ InitializeParams ();
+ m_hasRedStarted = true;
+ }
+
+ uint32_t nQueued = 0;
+
+ if (GetMode () == BYTES)
+ {
+ NS_LOG_DEBUG ("Enqueue in bytes mode");
+ nQueued = m_bytesInQueue;
+ }
+ else if (GetMode () == PACKETS)
+ {
+ NS_LOG_DEBUG ("Enqueue in packets mode");
+ nQueued = m_packets.size ();
+ }
+
+ // simulate number of packets arrival during idle period
+ uint32_t m = 0;
+
+ if (m_idle == 1)
+ {
+ NS_LOG_DEBUG ("RED Queue is idle.");
+ Time now = Simulator::Now ();
+
+ if (m_cautious == 3)
+ {
+ double ptc = m_ptc * m_meanPktSize / m_idlePktSize;
+ m = uint32_t (ptc * (now - m_idleTime).GetSeconds ());
+ }
+ else
+ {
+ m = uint32_t (m_ptc * (now - m_idleTime).GetSeconds ());
+ }
+
+ m_idle = 0;
+ }
+
+ m_qAvg = Estimator (nQueued, m + 1, m_qAvg, m_qW);
+
+ NS_LOG_DEBUG ("\t bytesInQueue " << m_bytesInQueue << "\tQavg " << m_qAvg);
+ NS_LOG_DEBUG ("\t packetsInQueue " << m_packets.size () << "\tQavg " << m_qAvg);
+
+ m_count++;
+ m_countBytes += p->GetSize ();
+
+ uint32_t dropType = DTYPE_NONE;
+ if (m_qAvg >= m_minTh && nQueued > 1)
+ {
+ if ((!m_isGentle && m_qAvg >= m_maxTh) ||
+ (m_isGentle && m_qAvg >= 2 * m_maxTh))
+ {
+ NS_LOG_DEBUG ("adding DROP FORCED MARK");
+ dropType = DTYPE_FORCED;
+ }
+ else if (m_old == 0)
+ {
+ /*
+ * The average queue size has just crossed the
+ * threshold from below to above "minthresh", or
+ * from above "minthresh" with an empty queue to
+ * above "minthresh" with a nonempty queue.
+ */
+ m_count = 1;
+ m_countBytes = p->GetSize ();
+ m_old = 1;
+ }
+ else if (DropEarly (p, nQueued))
+ {
+ NS_LOG_LOGIC ("DropEarly returns 1");
+ dropType = DTYPE_UNFORCED;
+ }
+ }
+ else
+ {
+ // No packets are being dropped
+ m_vProb = 0.0;
+ m_old = 0;
+ }
+
+ if (nQueued >= m_queueLimit)
+ {
+ NS_LOG_DEBUG ("\t Dropping due to Queue Full " << nQueued);
+ dropType = DTYPE_FORCED;
+ m_stats.qLimDrop++;
+ }
+
+ if (dropType == DTYPE_UNFORCED)
+ {
+ NS_LOG_DEBUG ("\t Dropping due to Prob Mark " << m_qAvg);
+ m_stats.unforcedDrop++;
+ Drop (p);
+ return false;
+ }
+ else if (dropType == DTYPE_FORCED)
+ {
+ NS_LOG_DEBUG ("\t Dropping due to Hard Mark " << m_qAvg);
+ m_stats.forcedDrop++;
+ Drop (p);
+ if (m_isNs1Compat)
+ {
+ m_count = 0;
+ m_countBytes = 0;
+ }
+ return false;
+ }
+
+ m_bytesInQueue += p->GetSize ();
+ m_packets.push_back (p);
+
+ NS_LOG_LOGIC ("Number packets " << m_packets.size ());
+ NS_LOG_LOGIC ("Number bytes " << m_bytesInQueue);
+
+ return true;
+}
+
+/*
+ * Note: if the link bandwidth changes in the course of the
+ * simulation, the bandwidth-dependent RED parameters do not change.
+ * This should be fixed, but it would require some extra parameters,
+ * and didn't seem worth the trouble...
+ */
+void
+RedQueue::InitializeParams (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ NS_ASSERT (m_minTh <= m_maxTh);
+ m_stats.forcedDrop = 0;
+ m_stats.unforcedDrop = 0;
+ m_stats.qLimDrop = 0;
+
+ m_cautious = 0;
+ m_ptc = m_linkBandwidth.GetBitRate () / (8.0 * m_meanPktSize);
+
+ m_qAvg = 0.0;
+ m_count = 0;
+ m_countBytes = 0;
+ m_old = 0;
+ m_idle = 1;
+
+ double th_diff = (m_maxTh - m_minTh);
+ if (th_diff == 0)
+ {
+ th_diff = 1.0;
+ }
+ m_vA = 1.0 / th_diff;
+ m_curMaxP = 1.0 / m_lInterm;
+ m_vB = -m_minTh / th_diff;
+
+ if (m_isGentle)
+ {
+ m_vC = (1.0 - m_curMaxP) / m_maxTh;
+ m_vD = 2.0 * m_curMaxP - 1.0;
+ }
+ m_idleTime = NanoSeconds (0);
+
+/*
+ * If m_qW=0, set it to a reasonable value of 1-exp(-1/C)
+ * This corresponds to choosing m_qW to be of that value for
+ * which the packet time constant -1/ln(1-m)qW) per default RTT
+ * of 100ms is an order of magnitude more than the link capacity, C.
+ *
+ * If m_qW=-1, then the queue weight is set to be a function of
+ * the bandwidth and the link propagation delay. In particular,
+ * the default RTT is assumed to be three times the link delay and
+ * transmission delay, if this gives a default RTT greater than 100 ms.
+ *
+ * If m_qW=-2, set it to a reasonable value of 1-exp(-10/C).
+ */
+ if (m_qW == 0.0)
+ {
+ m_qW = 1.0 - exp (-1.0 / m_ptc);
+ }
+ else if (m_qW == -1.0)
+ {
+ double rtt = 3.0 * (m_linkDelay.GetSeconds () + 1.0 / m_ptc);
+
+ if (rtt < 0.1)
+ {
+ rtt = 0.1;
+ }
+ m_qW = 1.0 - exp (-1.0 / (10 * rtt * m_ptc));
+ }
+ else if (m_qW == -2.0)
+ {
+ m_qW = 1.0 - exp (-10.0 / m_ptc);
+ }
+
+ // TODO: implement adaptive RED
+
+ NS_LOG_DEBUG ("\tm_delay " << m_linkDelay.GetSeconds () << "; m_isWait "
+ << m_isWait << "; m_qW " << m_qW << "; m_ptc " << m_ptc
+ << "; m_minTh " << m_minTh << "; m_maxTh " << m_maxTh
+ << "; m_isGentle " << m_isGentle << "; th_diff " << th_diff
+ << "; lInterm " << m_lInterm << "; va " << m_vA << "; cur_max_p "
+ << m_curMaxP << "; v_b " << m_vB << "; m_vC "
+ << m_vC << "; m_vD " << m_vD);
+}
+
+// Compute the average queue size
+double
+RedQueue::Estimator (uint32_t nQueued, uint32_t m, double qAvg, double qW)
+{
+ NS_LOG_FUNCTION (this << nQueued << m << qAvg << qW);
+ double newAve;
+
+ newAve = qAvg;
+ while (--m >= 1)
+ {
+ newAve *= 1.0 - qW;
+ }
+ newAve *= 1.0 - qW;
+ newAve += qW * nQueued;
+
+ // TODO: implement adaptive RED
+
+ return newAve;
+}
+
+// Check if packet p needs to be dropped due to probability mark
+uint32_t
+RedQueue::DropEarly (Ptr<Packet> p, uint32_t qSize)
+{
+ NS_LOG_FUNCTION (this << p << qSize);
+ m_vProb1 = CalculatePNew (m_qAvg, m_maxTh, m_isGentle, m_vA, m_vB, m_vC, m_vD, m_curMaxP);
+ m_vProb = ModifyP (m_vProb1, m_count, m_countBytes, m_meanPktSize, m_isWait, p->GetSize ());
+
+ // Drop probability is computed, pick random number and act
+ if (m_cautious == 1)
+ {
+ /*
+ * Don't drop/mark if the instantaneous queue is much below the average.
+ * For experimental purposes only.
+ * pkts: the number of packets arriving in 50 ms
+ */
+ double pkts = m_ptc * 0.05;
+ double fraction = pow ((1 - m_qW), pkts);
+
+ if ((double) qSize < fraction * m_qAvg)
+ {
+ // Queue could have been empty for 0.05 seconds
+ return 0;
+ }
+ }
+
+ UniformVariable uV;
+ double u = uV.GetValue ();
+
+ if (m_cautious == 2)
+ {
+ /*
+ * Decrease the drop probability if the instantaneous
+ * queue is much below the average.
+ * For experimental purposes only.
+ * pkts: the number of packets arriving in 50 ms
+ */
+ double pkts = m_ptc * 0.05;
+ double fraction = pow ((1 - m_qW), pkts);
+ double ratio = qSize / (fraction * m_qAvg);
+
+ if (ratio < 1.0)
+ {
+ u *= 1.0 / ratio;
+ }
+ }
+
+ if (u <= m_vProb)
+ {
+ NS_LOG_LOGIC ("u <= m_vProb; u " << u << "; m_vProb " << m_vProb);
+
+ // DROP or MARK
+ m_count = 0;
+ m_countBytes = 0;
+ // TODO: Implement set bit to mark
+
+ return 1; // drop
+ }
+
+ return 0; // no drop/mark
+}
+
+// Returns a probability using these function parameters for the DropEarly funtion
+double
+RedQueue::CalculatePNew (double qAvg, double maxTh, bool isGentle, double vA,
+ double vB, double vC, double vD, double maxP)
+{
+ NS_LOG_FUNCTION (this << qAvg << maxTh << isGentle << vA << vB << vC << vD << maxP);
+ double p;
+
+ if (isGentle && qAvg >= maxTh)
+ {
+ // p ranges from maxP to 1 as the average queue
+ // Size ranges from maxTh to twice maxTh
+ p = vC * qAvg + vD;
+ }
+ else if (!isGentle && qAvg >= maxTh)
+ {
+ /*
+ * OLD: p continues to range linearly above max_p as
+ * the average queue size ranges above th_max.
+ * NEW: p is set to 1.0
+ */
+ p = 1.0;
+ }
+ else
+ {
+ /*
+ * p ranges from 0 to max_p as the average queue size ranges from
+ * th_min to th_max
+ */
+ p = vA * qAvg + vB;
+ p *= maxP;
+ }
+
+ if (p > 1.0)
+ {
+ p = 1.0;
+ }
+
+ return p;
+}
+
+// Returns a probability using these function parameters for the DropEarly funtion
+double
+RedQueue::ModifyP (double p, uint32_t count, uint32_t countBytes,
+ uint32_t meanPktSize, bool isWait, uint32_t size)
+{
+ NS_LOG_FUNCTION (this << p << count << countBytes << meanPktSize << isWait << size);
+ double count1 = (double) count;
+
+ if (GetMode () == BYTES)
+ {
+ count1 = (double) (countBytes / meanPktSize);
+ }
+
+ if (isWait)
+ {
+ if (count1 * p < 1.0)
+ {
+ p = 0.0;
+ }
+ else if (count1 * p < 2.0)
+ {
+ p /= (2.0 - count1 * p);
+ }
+ else
+ {
+ p = 1.0;
+ }
+ }
+ else
+ {
+ if (count1 * p < 1.0)
+ {
+ p /= (1.0 - count1 * p);
+ }
+ else
+ {
+ p = 1.0;
+ }
+ }
+
+ if ((GetMode () == BYTES) && (p < 1.0))
+ {
+ p = (p * size) / meanPktSize;
+ }
+
+ if (p > 1.0)
+ {
+ p = 1.0;
+ }
+
+ return p;
+}
+
+uint32_t
+RedQueue::GetQueueSize (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ if (GetMode () == BYTES)
+ {
+ return m_bytesInQueue;
+ }
+ else if (GetMode () == PACKETS)
+ {
+ return m_packets.size ();
+ }
+ else
+ {
+ NS_ABORT_MSG ("Unknown RED mode.");
+ }
+}
+
+Ptr<Packet>
+RedQueue::DoDequeue (void)
+{
+ NS_LOG_FUNCTION (this);
+
+ if (m_packets.empty ())
+ {
+ NS_LOG_LOGIC ("Queue empty");
+ m_idle = 1;
+ m_idleTime = Simulator::Now ();
+
+ return 0;
+ }
+ else
+ {
+ m_idle = 0;
+ Ptr<Packet> p = m_packets.front ();
+ m_packets.pop_front ();
+ m_bytesInQueue -= p->GetSize ();
+
+ NS_LOG_LOGIC ("Popped " << p);
+
+ NS_LOG_LOGIC ("Number packets " << m_packets.size ());
+ NS_LOG_LOGIC ("Number bytes " << m_bytesInQueue);
+
+ return p;
+ }
+}
+
+Ptr<const Packet>
+RedQueue::DoPeek (void) const
+{
+ NS_LOG_FUNCTION (this);
+ if (m_packets.empty ())
+ {
+ NS_LOG_LOGIC ("Queue empty");
+ return 0;
+ }
+
+ Ptr<Packet> p = m_packets.front ();
+
+ NS_LOG_LOGIC ("Number packets " << m_packets.size ());
+ NS_LOG_LOGIC ("Number bytes " << m_bytesInQueue);
+
+ return p;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network/utils/red-queue.h Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,277 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This code was ported from NS-2.34, with licence:
+ *
+ * Copyright (c) 1990-1997 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *
+ * This port:
+ *
+ * Copyright © 2011 Marcos Talau
+ *
+ * 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: Marcos Talau (talau@users.sourceforge.net)
+ *
+ * Thanks to: Duy Nguyen<duy@soe.ucsc.edu> by RED efforts in NS3
+ *
+ */
+
+/*
+ * PORT NOTE: Almost all comments also been ported from NS-2
+ * This implementation aims to be close to the results cited in [0]
+ * [0] S.Floyd, K.Fall http://icir.org/floyd/papers/redsims.ps
+ */
+
+#ifndef RED_QUEUE_H
+#define RED_QUEUE_H
+
+#include <queue>
+#include "ns3/packet.h"
+#include "ns3/queue.h"
+#include "ns3/nstime.h"
+#include "ns3/random-variable.h"
+#include "ns3/boolean.h"
+#include "ns3/data-rate.h"
+#include "ns3/nstime.h"
+
+namespace ns3 {
+
+class TraceContainer;
+
+/*
+ * \ingroup queue
+ *
+ * \brief A RED packet queue
+ */
+class RedQueue : public Queue
+{
+public:
+ static TypeId GetTypeId (void);
+ /*
+ * \brief RedQueue Constructor
+ *
+ * Create a RED queue
+ */
+ RedQueue ();
+
+ /*
+ * \brief Destructor
+ *
+ * Destructor
+ */
+ virtual ~RedQueue ();
+
+ /*
+ * \brief Stats
+ *
+ */
+ typedef struct
+ {
+ // Early probability drops
+ uint32_t unforcedDrop;
+ // Forced drops, qavg > max threshold
+ uint32_t forcedDrop;
+ // Drops due to queue limits
+ uint32_t qLimDrop;
+ } Stats;
+
+ /*
+ * \brief Drop types
+ *
+ */
+ enum
+ {
+ DTYPE_NONE, // Ok, no drop
+ DTYPE_FORCED, // A "forced" drop
+ DTYPE_UNFORCED, // An "unforced" (random) drop
+ };
+
+ /*
+ * \brief Enumeration of the modes supported in the class.
+ *
+ */
+ enum Mode
+ {
+ ILLEGAL, // Mode not set
+ PACKETS, // Use number of packets for maximum queue size
+ BYTES, // Use number of bytes for maximum queue size
+ };
+
+ /*
+ * \brief Set the operating mode of this queue.
+ * Set operating mode
+ *
+ * \param mode The operating mode of this queue.
+ */
+ void SetMode (RedQueue::Mode mode);
+
+ /*
+ * \brief Get the encapsulation mode of this queue.
+ * Get the encapsulation mode of this queue
+ *
+ * \returns The encapsulation mode of this queue.
+ */
+ RedQueue::Mode GetMode (void);
+
+ /*
+ * \brief Get the current value of the queue in bytes or packets.
+ *
+ * \returns The queue size in bytes or packets.
+ */
+ uint32_t GetQueueSize (void);
+
+ /*
+ * \brief Set the limit of the queue.
+ *
+ * \param lim The limit in bytes or packets.
+ */
+ void SetQueueLimit (uint32_t lim);
+
+ /*
+ * \brief Set the thresh limits of RED.
+ *
+ * \param min Minimum thresh in bytes or packets.
+ * \param max Maximum thresh in bytes or packets.
+ */
+ void SetTh (double minTh, double maxTh);
+
+ /*
+ * \brief Get the RED statistics after running.
+ *
+ * \returns The drop statistics.
+ */
+ Stats GetStats ();
+
+private:
+ virtual bool DoEnqueue (Ptr<Packet> p);
+ virtual Ptr<Packet> DoDequeue (void);
+ virtual Ptr<const Packet> DoPeek (void) const;
+
+ // ...
+ void InitializeParams (void);
+ // Compute the average queue size
+ double Estimator (uint32_t nQueued, uint32_t m, double qAvg, double qW);
+ // Check if packet p needs to be dropped due to probability mark
+ uint32_t DropEarly (Ptr<Packet> p, uint32_t qSize);
+ // Returns a probability using these function parameters for the DropEarly funtion
+ double CalculatePNew (double qAvg, double maxTh, bool gentle, double vA,
+ double vB, double vC, double vD, double maxP);
+ // Returns a probability using these function parameters for the DropEarly funtion
+ double ModifyP (double p, uint32_t count, uint32_t countBytes,
+ uint32_t meanPktSize, bool wait, uint32_t size);
+
+ std::list<Ptr<Packet> > m_packets;
+
+ uint32_t m_bytesInQueue;
+ bool m_hasRedStarted;
+ Stats m_stats;
+
+ // ** Variables supplied by user
+ // Bytes or packets?
+ Mode m_mode;
+ // Avg pkt size
+ uint32_t m_meanPktSize;
+ // Avg pkt size used during idle times
+ uint32_t m_idlePktSize;
+ // True for waiting between dropped packets
+ bool m_isWait;
+ // True to increases dropping prob. slowly when ave queue exceeds maxthresh
+ bool m_isGentle;
+ // Min avg length threshold (bytes)
+ double m_minTh;
+ // Max avg length threshold (bytes), should be >= 2*minTh
+ double m_maxTh;
+ // Queue limit in bytes / packets
+ uint32_t m_queueLimit;
+ // Queue weight given to cur q size sample
+ double m_qW;
+ // The max probability of dropping a packet
+ double m_lInterm;
+ // Ns-1 compatibility
+ bool m_isNs1Compat;
+ // Link bandwidth
+ DataRate m_linkBandwidth;
+ // Link delay
+ Time m_linkDelay;
+
+ // ** Variables maintained by RED
+ // Prob. of packet drop before "count"
+ double m_vProb1;
+ // v_prob = v_a * v_ave + v_b
+ double m_vA;
+ double m_vB;
+ // Used for "gentle" mode
+ double m_vC;
+ // Used for "gentle" mode
+ double m_vD;
+ // Current max_p
+ double m_curMaxP;
+ // Prob. of packet drop
+ double m_vProb;
+ // # of bytes since last drop
+ uint32_t m_countBytes;
+ // 0 when average queue first exceeds thresh
+ uint32_t m_old;
+ // 0/1 idle status
+ uint32_t m_idle;
+ // packet time constant in packets/second
+ double m_ptc;
+ // Average queue length
+ double m_qAvg;
+ // number of packets since last random number generation
+ uint32_t m_count;
+ /*
+ * 0 for default RED
+ * 1 experimental (see red-queue.cc)
+ * 2 experimental (see red-queue.cc)
+ * 3 use Idle packet size in the ptc
+ */
+ uint32_t m_cautious;
+ // Start of current idle period
+ Time m_idleTime;
+};
+
+}; // namespace ns3
+
+#endif // RED_QUEUE_H
--- a/src/network/wscript Fri Dec 16 18:50:05 2011 +0100
+++ b/src/network/wscript Fri Dec 16 18:51:18 2011 +0100
@@ -47,6 +47,7 @@
'utils/pcap-file-wrapper.cc',
'utils/queue.cc',
'utils/radiotap-header.cc',
+ 'utils/red-queue.cc',
'utils/simple-channel.cc',
'utils/simple-net-device.cc',
'helper/application-container.cc',
@@ -64,6 +65,7 @@
'test/packet-test-suite.cc',
'test/packet-metadata-test.cc',
'test/pcap-file-test-suite.cc',
+ 'test/red-queue-test-suite.cc',
'test/sequence-number-test-suite.cc',
]
@@ -115,6 +117,7 @@
'utils/generic-phy.h',
'utils/queue.h',
'utils/radiotap-header.h',
+ 'utils/red-queue.h',
'utils/sequence-number.h',
'utils/sgi-hashmap.h',
'utils/simple-channel.h',
--- a/src/olsr/model/olsr-repositories.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/olsr/model/olsr-repositories.h Fri Dec 16 18:51:18 2011 +0100
@@ -21,8 +21,7 @@
*/
///
-/// \file olsr-repositories.h
-/// \brief Here are defined all data structures needed by an OLSR node.
+/// \brief Here are defined all data structures needed by an OLSR node.
///
#ifndef OLSR_REPOSITORIES_H
--- a/src/olsr/model/olsr-routing-protocol.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/olsr/model/olsr-routing-protocol.cc Fri Dec 16 18:51:18 2011 +0100
@@ -22,8 +22,7 @@
///
-/// \file OLSR.cc
-/// \brief Implementation of OLSR agent and related classes.
+/// \brief Implementation of OLSR agent and related classes.
///
/// This is the main file of this software because %OLSR's behaviour is
/// implemented here.
@@ -499,7 +498,6 @@
receiverIfaceAddr, inetSourceAddr.GetIpv4 ());
}
}
-
}
// After processing all OLSR messages, we must recompute the routing table
@@ -573,7 +571,6 @@
// MPR computation should be done for each interface. See section 8.3.1
// (RFC 3626) for details.
MprSet mprSet;
-
// N is the subset of neighbors of the node, which are
// neighbor "of the interface I"
@@ -586,7 +583,7 @@
N.push_back (*neighbor);
}
}
-
+
// N2 is the set of 2-hop neighbors reachable from "the interface
// I", excluding:
// (i) the nodes only reachable by members of N with willingness WILL_NEVER
@@ -681,7 +678,7 @@
// 2. Calculate D(y), where y is a member of N, for all nodes in N.
// (we do this later)
-
+
// 3. Add to the MPR set those nodes in N, which are the *only*
// nodes to provide reachability to a node in N2.
std::set<Ipv4Address> coveredTwoHopNeighbors;
@@ -734,7 +731,7 @@
twoHopNeigh++;
}
}
-
+
// 4. While there exist nodes in N2 which are not covered by at
// least one node in the MPR set:
while (N2.begin () != N2.end ())
@@ -882,7 +879,7 @@
// 1. All the entries from the routing table are removed.
Clear ();
-
+
// 2. The new routing entries are added starting with the
// symmetric neighbors (h=1) as the destination nodes.
const NeighborSet &neighborSet = m_state.GetNeighbors ();
@@ -1080,9 +1077,9 @@
// 4. For each entry in the multiple interface association base
// where there exists a routing entry such that:
- // R_dest_addr == I_main_addr (of the multiple interface association entry)
+ // R_dest_addr == I_main_addr (of the multiple interface association entry)
// AND there is no routing entry such that:
- // R_dest_addr == I_iface_addr
+ // R_dest_addr == I_iface_addr
const IfaceAssocSet &ifaceAssocSet = m_state.GetIfaceAssocSet ();
for (IfaceAssocSet::const_iterator it = ifaceAssocSet.begin ();
it != ifaceAssocSet.end (); it++)
@@ -1268,13 +1265,13 @@
{
const olsr::MessageHeader::Tc &tc = msg.GetTc ();
Time now = Simulator::Now ();
-
+
// 1. If the sender interface of this message is not in the symmetric
// 1-hop neighborhood of this node, the message MUST be discarded.
const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
if (link_tuple == NULL)
return;
-
+
// 2. If there exist some tuple in the topology set where:
// T_last_addr == originator address AND
// T_seq > ANSN,
@@ -1284,10 +1281,10 @@
m_state.FindNewerTopologyTuple (msg.GetOriginatorAddress (), tc.ansn);
if (topologyTuple != NULL)
return;
-
+
// 3. All tuples in the topology set where:
- // T_last_addr == originator address AND
- // T_seq < ANSN
+ // T_last_addr == originator address AND
+ // T_seq < ANSN
// MUST be removed from the topology set.
m_state.EraseOlderTopologyTuples (msg.GetOriginatorAddress (), tc.ansn);
@@ -1298,10 +1295,10 @@
{
const Ipv4Address &addr = *i;
// 4.1. If there exist some tuple in the topology set where:
- // T_dest_addr == advertised neighbor main address, AND
- // T_last_addr == originator address,
+ // T_dest_addr == advertised neighbor main address, AND
+ // T_last_addr == originator address,
// then the holding time of that tuple MUST be set to:
- // T_time = current time + validity time.
+ // T_time = current time + validity time.
TopologyTuple *topologyTuple =
m_state.FindTopologyTuple (addr, msg.GetOriginatorAddress ());
@@ -1313,10 +1310,10 @@
{
// 4.2. Otherwise, a new tuple MUST be recorded in the topology
// set where:
- // T_dest_addr = advertised neighbor main address,
- // T_last_addr = originator address,
- // T_seq = ANSN,
- // T_time = current time + validity time.
+ // T_dest_addr = advertised neighbor main address,
+ // T_last_addr = originator address,
+ // T_seq = ANSN,
+ // T_time = current time + validity time.
TopologyTuple topologyTuple;;
topologyTuple.destAddr = addr;
topologyTuple.lastAddr = msg.GetOriginatorAddress ();
@@ -1376,7 +1373,7 @@
" the message MUST be discarded.");
return;
}
-
+
// 2. For each interface address listed in the MID message
for (std::vector<Ipv4Address>::const_iterator i = mid.interfaceAddresses.begin ();
i != mid.interfaceAddresses.end (); i++)
@@ -1526,7 +1523,7 @@
" from " << olsrMessage.GetOriginatorAddress () << " because it is duplicated");
return;
}
-
+
// If the sender interface address is an interface address
// of a MPR selector of this node and ttl is greater than 1,
// the message must be retransmitted
@@ -1545,7 +1542,7 @@
retransmitted = true;
}
}
-
+
// Update duplicate tuple...
if (duplicated != NULL)
{
@@ -1680,7 +1677,7 @@
std::vector<olsr::MessageHeader::Hello::LinkMessage>
&linkMessages = hello.linkMessages;
-
+
const LinkSet &links = m_state.GetLinks ();
for (LinkSet::const_iterator link_tuple = links.begin ();
link_tuple != links.end (); link_tuple++)
@@ -1921,7 +1918,7 @@
/// in HNA messages sent by the node.
/// If this method is called more than once, entries from the old
/// association are deleted before entries from the new one are added.
-/// \param the Ipv4StaticRouting routing table to be associated.
+/// \param routingTable the Ipv4StaticRouting routing table to be associated.
///
void
RoutingProtocol::SetRoutingTableAssociation (Ptr<Ipv4StaticRouting> routingTable)
@@ -1983,8 +1980,8 @@
}
///
-/// \brief Updates Link Set according to a new received HELLO message (following RFC 3626
-/// specification). Neighbor Set is also updated if needed.
+/// \brief Updates Link Set according to a new received HELLO message
+/// (following RFC 3626 specification). Neighbor Set is also updated if needed.
void
RoutingProtocol::LinkSensing (const olsr::MessageHeader &msg,
const olsr::MessageHeader::Hello &hello,
@@ -1997,7 +1994,7 @@
NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
<< ": LinkSensing(receiverIface=" << receiverIface
<< ", senderIface=" << senderIface << ") BEGIN");
-
+
NS_ASSERT (msg.GetVTime () > Seconds (0));
LinkTuple *link_tuple = m_state.FindLinkTuple (senderIface);
if (link_tuple == NULL)
@@ -2017,7 +2014,7 @@
NS_LOG_LOGIC ("Existing link tuple already exists => will update it");
updated = true;
}
-
+
link_tuple->asymTime = now + msg.GetVTime ();
for (std::vector<olsr::MessageHeader::Hello::LinkMessage>::const_iterator linkMessage =
hello.linkMessages.begin ();
@@ -2118,8 +2115,8 @@
}
///
-/// \brief Updates the Neighbor Set according to the information contained in a new received
-/// HELLO message (following RFC 3626).
+/// \brief Updates the Neighbor Set according to the information contained in
+/// a new received HELLO message (following RFC 3626).
void
RoutingProtocol::PopulateNeighborSet (const olsr::MessageHeader &msg,
const olsr::MessageHeader::Hello &hello)
@@ -2133,8 +2130,8 @@
///
-/// \brief Updates the 2-hop Neighbor Set according to the information contained in a new
-/// received HELLO message (following RFC 3626).
+/// \brief Updates the 2-hop Neighbor Set according to the information contained
+/// in a new received HELLO message (following RFC 3626).
void
RoutingProtocol::PopulateTwoHopNeighborSet (const olsr::MessageHeader &msg,
const olsr::MessageHeader::Hello &hello)
@@ -2142,7 +2139,7 @@
Time now = Simulator::Now ();
NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet BEGIN");
-
+
for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin ();
link_tuple != m_state.GetLinks ().end (); link_tuple++)
{
@@ -2245,8 +2242,8 @@
///
-/// \brief Updates the MPR Selector Set according to the information contained in a new
-/// received HELLO message (following RFC 3626).
+/// \brief Updates the MPR Selector Set according to the information contained in
+/// a new received HELLO message (following RFC 3626).
void
RoutingProtocol::PopulateMprSelectorSet (const olsr::MessageHeader &msg,
const olsr::MessageHeader::Hello &hello)
@@ -2254,7 +2251,7 @@
NS_LOG_FUNCTION (this);
Time now = Simulator::Now ();
-
+
typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
linkMessage != hello.linkMessages.end ();
@@ -2305,9 +2302,9 @@
#if 0
///
-/// \brief Drops a given packet because it couldn't be delivered to the corresponding
-/// destination by the MAC layer. This may cause a neighbor loss, and appropiate
-/// actions are then taken.
+/// \brief Drops a given packet because it couldn't be delivered to the corresponding
+/// destination by the MAC layer. This may cause a neighbor loss, and appropiate
+/// actions are then taken.
///
/// \param p the packet which couldn't be delivered by the MAC layer.
///
@@ -2316,17 +2313,17 @@
double now = Simulator::Now ();
struct hdr_ip* ih = HDR_IP (p);
struct hdr_cmn* ch = HDR_CMN (p);
-
+
debug ("%f: Node %d MAC Layer detects a breakage on link to %d\n",
now,
OLSR::node_id (ra_addr ()),
OLSR::node_id (ch->next_hop ()));
-
+
if ((u_int32_t)ih->daddr () == IP_BROADCAST) {
drop (p, DROP_RTR_MAC_CALLBACK);
return;
}
-
+
OLSR_link_tuple* link_tuple = state_.find_link_tuple (ch->next_hop ());
if (link_tuple != NULL) {
link_tuple->lost_time () = now + OLSR_NEIGHB_HOLD_TIME;
@@ -2431,8 +2428,8 @@
}
///
-/// \brief This function is invoked when a link tuple is updated. Its aim is to
-/// also update the corresponding neighbor tuple if it is needed.
+/// \brief This function is invoked when a link tuple is updated. Its aim is to
+/// also update the corresponding neighbor tuple if it is needed.
///
/// \param tuple the link tuple which has been updated.
///
@@ -2525,7 +2522,7 @@
// OLSR::node_id(ra_addr()),
// OLSR::node_id(tuple->neighborMainAddr),
// ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
-
+
m_state.EraseNeighborTuple (tuple);
IncrementAnsn ();
}
@@ -2987,7 +2984,7 @@
///
/// \brief Deletes the entry whose destination address is given.
-/// \param dest address of the destination node.
+/// \param dest address of the destination node.
///
void
RoutingProtocol::RemoveEntry (Ipv4Address const &dest)
@@ -2997,9 +2994,9 @@
///
/// \brief Looks up an entry for the specified destination address.
-/// \param dest destination address.
+/// \param dest destination address.
/// \param outEntry output parameter to hold the routing entry result, if fuond
-/// \return true if found, false if not found
+/// \return true if found, false if not found
///
bool
RoutingProtocol::Lookup (Ipv4Address const &dest,
@@ -3016,8 +3013,8 @@
}
///
-/// \brief Finds the appropiate entry which must be used in order to forward
-/// a data packet to a next hop (given a destination).
+/// \brief Finds the appropiate entry which must be used in order to forward
+/// a data packet to a next hop (given a destination).
///
/// Imagine a routing table like this: [A,B] [B,C] [C,C]; being each pair of the
/// form [dest addr,next-hop addr]. In this case, if this function is invoked with
@@ -3025,11 +3022,11 @@
/// to forward a data packet destined to A. That is, C is a neighbor of this node,
/// but B isn't. This function finds the appropiate neighbor for forwarding a packet.
///
-/// \param entry the routing table entry which indicates the destination node
-/// we are interested in.
-/// \return the appropiate routing table entry which indicates the next
-/// hop which must be used for forwarding a data packet, or NULL
-/// if there is no such entry.
+/// \param entry the routing table entry which indicates the destination node
+/// we are interested in.
+/// \return the appropiate routing table entry which indicates the next
+/// hop which must be used for forwarding a data packet, or NULL
+/// if there is no such entry.
///
bool
RoutingProtocol::FindSendEntry (RoutingTableEntry const &entry,
@@ -3239,10 +3236,10 @@
///
/// If an entry for the given destination existed, it is deleted and freed.
///
-/// \param dest address of the destination node.
-/// \param next address of the next hop node.
-/// \param iface address of the local interface.
-/// \param dist distance to the destination node.
+/// \param dest address of the destination node.
+/// \param next address of the next hop node.
+/// \param iface address of the local interface.
+/// \param dist distance to the destination node.
///
void
RoutingProtocol::AddEntry (Ipv4Address const &dest,
@@ -3348,7 +3345,7 @@
#endif //NS3_LOG_ENABLE
}
-}
-} // namespace olsr, ns3
-
-
+} // namespace olsr
+} // namespace ns3
+
+
--- a/src/olsr/model/olsr-state.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/olsr/model/olsr-state.cc Fri Dec 16 18:51:18 2011 +0100
@@ -21,7 +21,7 @@
*/
///
-/// \file OlsrState.cc
+/// \file olsr-state.cc
/// \brief Implementation of all functions needed for manipulating the internal
/// state of an OLSR node.
///
Binary file src/olsr/test/bug780-2-0.pcap has changed
--- a/src/propagation/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/propagation/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:51:18 2011 +0100
@@ -50,6 +50,10 @@
module.add_class('TraceSourceInformation', import_from_module='ns.core', outer_class=root_module['ns3::TypeId'])
## random-variable.h (module 'core'): ns3::UniformVariable [class]
module.add_class('UniformVariable', import_from_module='ns.core', parent=root_module['ns3::RandomVariable'])
+ ## vector.h (module 'core'): ns3::Vector2D [class]
+ module.add_class('Vector2D', import_from_module='ns.core')
+ ## vector.h (module 'core'): ns3::Vector3D [class]
+ module.add_class('Vector3D', import_from_module='ns.core')
## random-variable.h (module 'core'): ns3::WeibullVariable [class]
module.add_class('WeibullVariable', import_from_module='ns.core', parent=root_module['ns3::RandomVariable'])
## random-variable.h (module 'core'): ns3::ZetaVariable [class]
@@ -146,6 +150,8 @@
module.add_class('LogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
## propagation-loss-model.h (module 'propagation'): ns3::MatrixPropagationLossModel [class]
module.add_class('MatrixPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
+ ## mobility-model.h (module 'mobility'): ns3::MobilityModel [class]
+ module.add_class('MobilityModel', import_from_module='ns.mobility', parent=root_module['ns3::Object'])
## propagation-loss-model.h (module 'propagation'): ns3::NakagamiPropagationLossModel [class]
module.add_class('NakagamiPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
## random-variable.h (module 'core'): ns3::RandomVariableChecker [class]
@@ -160,6 +166,26 @@
module.add_class('TypeIdChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
## type-id.h (module 'core'): ns3::TypeIdValue [class]
module.add_class('TypeIdValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
+ ## vector.h (module 'core'): ns3::Vector2DChecker [class]
+ module.add_class('Vector2DChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
+ ## vector.h (module 'core'): ns3::Vector2DValue [class]
+ module.add_class('Vector2DValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
+ ## vector.h (module 'core'): ns3::Vector3DChecker [class]
+ module.add_class('Vector3DChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
+ ## vector.h (module 'core'): ns3::Vector3DValue [class]
+ module.add_class('Vector3DValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
+ typehandlers.add_type_alias('ns3::Vector3DValue', 'ns3::VectorValue')
+ typehandlers.add_type_alias('ns3::Vector3DValue*', 'ns3::VectorValue*')
+ typehandlers.add_type_alias('ns3::Vector3DValue&', 'ns3::VectorValue&')
+ module.add_typedef(root_module['ns3::Vector3DValue'], 'VectorValue')
+ typehandlers.add_type_alias('ns3::Vector3D', 'ns3::Vector')
+ typehandlers.add_type_alias('ns3::Vector3D*', 'ns3::Vector*')
+ typehandlers.add_type_alias('ns3::Vector3D&', 'ns3::Vector&')
+ module.add_typedef(root_module['ns3::Vector3D'], 'Vector')
+ typehandlers.add_type_alias('ns3::Vector3DChecker', 'ns3::VectorChecker')
+ typehandlers.add_type_alias('ns3::Vector3DChecker*', 'ns3::VectorChecker*')
+ typehandlers.add_type_alias('ns3::Vector3DChecker&', 'ns3::VectorChecker&')
+ module.add_typedef(root_module['ns3::Vector3DChecker'], 'VectorChecker')
## Register a nested module for the namespace FatalImpl
@@ -186,6 +212,8 @@
register_Ns3TypeIdAttributeInformation_methods(root_module, root_module['ns3::TypeId::AttributeInformation'])
register_Ns3TypeIdTraceSourceInformation_methods(root_module, root_module['ns3::TypeId::TraceSourceInformation'])
register_Ns3UniformVariable_methods(root_module, root_module['ns3::UniformVariable'])
+ register_Ns3Vector2D_methods(root_module, root_module['ns3::Vector2D'])
+ register_Ns3Vector3D_methods(root_module, root_module['ns3::Vector3D'])
register_Ns3WeibullVariable_methods(root_module, root_module['ns3::WeibullVariable'])
register_Ns3ZetaVariable_methods(root_module, root_module['ns3::ZetaVariable'])
register_Ns3ZipfVariable_methods(root_module, root_module['ns3::ZipfVariable'])
@@ -231,6 +259,7 @@
register_Ns3JakesPropagationLossModel_methods(root_module, root_module['ns3::JakesPropagationLossModel'])
register_Ns3LogDistancePropagationLossModel_methods(root_module, root_module['ns3::LogDistancePropagationLossModel'])
register_Ns3MatrixPropagationLossModel_methods(root_module, root_module['ns3::MatrixPropagationLossModel'])
+ register_Ns3MobilityModel_methods(root_module, root_module['ns3::MobilityModel'])
register_Ns3NakagamiPropagationLossModel_methods(root_module, root_module['ns3::NakagamiPropagationLossModel'])
register_Ns3RandomVariableChecker_methods(root_module, root_module['ns3::RandomVariableChecker'])
register_Ns3RandomVariableValue_methods(root_module, root_module['ns3::RandomVariableValue'])
@@ -238,6 +267,10 @@
register_Ns3TimeValue_methods(root_module, root_module['ns3::TimeValue'])
register_Ns3TypeIdChecker_methods(root_module, root_module['ns3::TypeIdChecker'])
register_Ns3TypeIdValue_methods(root_module, root_module['ns3::TypeIdValue'])
+ register_Ns3Vector2DChecker_methods(root_module, root_module['ns3::Vector2DChecker'])
+ register_Ns3Vector2DValue_methods(root_module, root_module['ns3::Vector2DValue'])
+ register_Ns3Vector3DChecker_methods(root_module, root_module['ns3::Vector3DChecker'])
+ register_Ns3Vector3DValue_methods(root_module, root_module['ns3::Vector3DValue'])
return
def register_Ns3AttributeConstructionList_methods(root_module, cls):
@@ -648,6 +681,36 @@
[param('double', 's'), param('double', 'l')])
return
+def register_Ns3Vector2D_methods(root_module, cls):
+ cls.add_output_stream_operator()
+ ## vector.h (module 'core'): ns3::Vector2D::Vector2D(ns3::Vector2D const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Vector2D const &', 'arg0')])
+ ## vector.h (module 'core'): ns3::Vector2D::Vector2D(double _x, double _y) [constructor]
+ cls.add_constructor([param('double', '_x'), param('double', '_y')])
+ ## vector.h (module 'core'): ns3::Vector2D::Vector2D() [constructor]
+ cls.add_constructor([])
+ ## vector.h (module 'core'): ns3::Vector2D::x [variable]
+ cls.add_instance_attribute('x', 'double', is_const=False)
+ ## vector.h (module 'core'): ns3::Vector2D::y [variable]
+ cls.add_instance_attribute('y', 'double', is_const=False)
+ return
+
+def register_Ns3Vector3D_methods(root_module, cls):
+ cls.add_output_stream_operator()
+ ## vector.h (module 'core'): ns3::Vector3D::Vector3D(ns3::Vector3D const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Vector3D const &', 'arg0')])
+ ## vector.h (module 'core'): ns3::Vector3D::Vector3D(double _x, double _y, double _z) [constructor]
+ cls.add_constructor([param('double', '_x'), param('double', '_y'), param('double', '_z')])
+ ## vector.h (module 'core'): ns3::Vector3D::Vector3D() [constructor]
+ cls.add_constructor([])
+ ## vector.h (module 'core'): ns3::Vector3D::x [variable]
+ cls.add_instance_attribute('x', 'double', is_const=False)
+ ## vector.h (module 'core'): ns3::Vector3D::y [variable]
+ cls.add_instance_attribute('y', 'double', is_const=False)
+ ## vector.h (module 'core'): ns3::Vector3D::z [variable]
+ cls.add_instance_attribute('z', 'double', is_const=False)
+ return
+
def register_Ns3WeibullVariable_methods(root_module, cls):
## random-variable.h (module 'core'): ns3::WeibullVariable::WeibullVariable(ns3::WeibullVariable const & arg0) [copy constructor]
cls.add_constructor([param('ns3::WeibullVariable const &', 'arg0')])
@@ -1789,6 +1852,62 @@
is_const=True, visibility='private', is_virtual=True)
return
+def register_Ns3MobilityModel_methods(root_module, cls):
+ ## mobility-model.h (module 'mobility'): ns3::MobilityModel::MobilityModel(ns3::MobilityModel const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::MobilityModel const &', 'arg0')])
+ ## mobility-model.h (module 'mobility'): ns3::MobilityModel::MobilityModel() [constructor]
+ cls.add_constructor([])
+ ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetDistanceFrom(ns3::Ptr<const ns3::MobilityModel> position) const [member function]
+ cls.add_method('GetDistanceFrom',
+ 'double',
+ [param('ns3::Ptr< ns3::MobilityModel const >', 'position')],
+ is_const=True)
+ ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::GetPosition() const [member function]
+ cls.add_method('GetPosition',
+ 'ns3::Vector',
+ [],
+ is_const=True)
+ ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+ cls.add_method('GetRelativeSpeed',
+ 'double',
+ [param('ns3::Ptr< ns3::MobilityModel const >', 'other')],
+ is_const=True)
+ ## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
+ cls.add_method('GetTypeId',
+ 'ns3::TypeId',
+ [],
+ is_static=True)
+ ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::GetVelocity() const [member function]
+ cls.add_method('GetVelocity',
+ 'ns3::Vector',
+ [],
+ is_const=True)
+ ## mobility-model.h (module 'mobility'): void ns3::MobilityModel::SetPosition(ns3::Vector const & position) [member function]
+ cls.add_method('SetPosition',
+ 'void',
+ [param('ns3::Vector const &', 'position')])
+ ## mobility-model.h (module 'mobility'): void ns3::MobilityModel::NotifyCourseChange() const [member function]
+ cls.add_method('NotifyCourseChange',
+ 'void',
+ [],
+ is_const=True, visibility='protected')
+ ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::DoGetPosition() const [member function]
+ cls.add_method('DoGetPosition',
+ 'ns3::Vector',
+ [],
+ is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
+ ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::DoGetVelocity() const [member function]
+ cls.add_method('DoGetVelocity',
+ 'ns3::Vector',
+ [],
+ is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
+ ## mobility-model.h (module 'mobility'): void ns3::MobilityModel::DoSetPosition(ns3::Vector const & position) [member function]
+ cls.add_method('DoSetPosition',
+ 'void',
+ [param('ns3::Vector const &', 'position')],
+ is_pure_virtual=True, visibility='private', is_virtual=True)
+ return
+
def register_Ns3NakagamiPropagationLossModel_methods(root_module, cls):
## propagation-loss-model.h (module 'propagation'): static ns3::TypeId ns3::NakagamiPropagationLossModel::GetTypeId() [member function]
cls.add_method('GetTypeId',
@@ -1924,6 +2043,86 @@
[param('ns3::TypeId const &', 'value')])
return
+def register_Ns3Vector2DChecker_methods(root_module, cls):
+ ## vector.h (module 'core'): ns3::Vector2DChecker::Vector2DChecker() [constructor]
+ cls.add_constructor([])
+ ## vector.h (module 'core'): ns3::Vector2DChecker::Vector2DChecker(ns3::Vector2DChecker const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Vector2DChecker const &', 'arg0')])
+ return
+
+def register_Ns3Vector2DValue_methods(root_module, cls):
+ ## vector.h (module 'core'): ns3::Vector2DValue::Vector2DValue() [constructor]
+ cls.add_constructor([])
+ ## vector.h (module 'core'): ns3::Vector2DValue::Vector2DValue(ns3::Vector2DValue const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Vector2DValue const &', 'arg0')])
+ ## vector.h (module 'core'): ns3::Vector2DValue::Vector2DValue(ns3::Vector2D const & value) [constructor]
+ cls.add_constructor([param('ns3::Vector2D const &', 'value')])
+ ## vector.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::Vector2DValue::Copy() const [member function]
+ cls.add_method('Copy',
+ 'ns3::Ptr< ns3::AttributeValue >',
+ [],
+ is_const=True, is_virtual=True)
+ ## vector.h (module 'core'): bool ns3::Vector2DValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+ cls.add_method('DeserializeFromString',
+ 'bool',
+ [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
+ is_virtual=True)
+ ## vector.h (module 'core'): ns3::Vector2D ns3::Vector2DValue::Get() const [member function]
+ cls.add_method('Get',
+ 'ns3::Vector2D',
+ [],
+ is_const=True)
+ ## vector.h (module 'core'): std::string ns3::Vector2DValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+ cls.add_method('SerializeToString',
+ 'std::string',
+ [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
+ is_const=True, is_virtual=True)
+ ## vector.h (module 'core'): void ns3::Vector2DValue::Set(ns3::Vector2D const & value) [member function]
+ cls.add_method('Set',
+ 'void',
+ [param('ns3::Vector2D const &', 'value')])
+ return
+
+def register_Ns3Vector3DChecker_methods(root_module, cls):
+ ## vector.h (module 'core'): ns3::Vector3DChecker::Vector3DChecker() [constructor]
+ cls.add_constructor([])
+ ## vector.h (module 'core'): ns3::Vector3DChecker::Vector3DChecker(ns3::Vector3DChecker const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Vector3DChecker const &', 'arg0')])
+ return
+
+def register_Ns3Vector3DValue_methods(root_module, cls):
+ ## vector.h (module 'core'): ns3::Vector3DValue::Vector3DValue() [constructor]
+ cls.add_constructor([])
+ ## vector.h (module 'core'): ns3::Vector3DValue::Vector3DValue(ns3::Vector3DValue const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Vector3DValue const &', 'arg0')])
+ ## vector.h (module 'core'): ns3::Vector3DValue::Vector3DValue(ns3::Vector3D const & value) [constructor]
+ cls.add_constructor([param('ns3::Vector3D const &', 'value')])
+ ## vector.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::Vector3DValue::Copy() const [member function]
+ cls.add_method('Copy',
+ 'ns3::Ptr< ns3::AttributeValue >',
+ [],
+ is_const=True, is_virtual=True)
+ ## vector.h (module 'core'): bool ns3::Vector3DValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+ cls.add_method('DeserializeFromString',
+ 'bool',
+ [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
+ is_virtual=True)
+ ## vector.h (module 'core'): ns3::Vector3D ns3::Vector3DValue::Get() const [member function]
+ cls.add_method('Get',
+ 'ns3::Vector3D',
+ [],
+ is_const=True)
+ ## vector.h (module 'core'): std::string ns3::Vector3DValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+ cls.add_method('SerializeToString',
+ 'std::string',
+ [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
+ is_const=True, is_virtual=True)
+ ## vector.h (module 'core'): void ns3::Vector3DValue::Set(ns3::Vector3D const & value) [member function]
+ cls.add_method('Set',
+ 'void',
+ [param('ns3::Vector3D const &', 'value')])
+ return
+
def register_functions(root_module):
module = root_module
register_functions_ns3_FatalImpl(module.get_submodule('FatalImpl'), root_module)
--- a/src/propagation/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/propagation/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:51:18 2011 +0100
@@ -50,6 +50,10 @@
module.add_class('TraceSourceInformation', import_from_module='ns.core', outer_class=root_module['ns3::TypeId'])
## random-variable.h (module 'core'): ns3::UniformVariable [class]
module.add_class('UniformVariable', import_from_module='ns.core', parent=root_module['ns3::RandomVariable'])
+ ## vector.h (module 'core'): ns3::Vector2D [class]
+ module.add_class('Vector2D', import_from_module='ns.core')
+ ## vector.h (module 'core'): ns3::Vector3D [class]
+ module.add_class('Vector3D', import_from_module='ns.core')
## random-variable.h (module 'core'): ns3::WeibullVariable [class]
module.add_class('WeibullVariable', import_from_module='ns.core', parent=root_module['ns3::RandomVariable'])
## random-variable.h (module 'core'): ns3::ZetaVariable [class]
@@ -146,6 +150,8 @@
module.add_class('LogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
## propagation-loss-model.h (module 'propagation'): ns3::MatrixPropagationLossModel [class]
module.add_class('MatrixPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
+ ## mobility-model.h (module 'mobility'): ns3::MobilityModel [class]
+ module.add_class('MobilityModel', import_from_module='ns.mobility', parent=root_module['ns3::Object'])
## propagation-loss-model.h (module 'propagation'): ns3::NakagamiPropagationLossModel [class]
module.add_class('NakagamiPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
## random-variable.h (module 'core'): ns3::RandomVariableChecker [class]
@@ -160,6 +166,26 @@
module.add_class('TypeIdChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
## type-id.h (module 'core'): ns3::TypeIdValue [class]
module.add_class('TypeIdValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
+ ## vector.h (module 'core'): ns3::Vector2DChecker [class]
+ module.add_class('Vector2DChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
+ ## vector.h (module 'core'): ns3::Vector2DValue [class]
+ module.add_class('Vector2DValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
+ ## vector.h (module 'core'): ns3::Vector3DChecker [class]
+ module.add_class('Vector3DChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
+ ## vector.h (module 'core'): ns3::Vector3DValue [class]
+ module.add_class('Vector3DValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
+ typehandlers.add_type_alias('ns3::Vector3DValue', 'ns3::VectorValue')
+ typehandlers.add_type_alias('ns3::Vector3DValue*', 'ns3::VectorValue*')
+ typehandlers.add_type_alias('ns3::Vector3DValue&', 'ns3::VectorValue&')
+ module.add_typedef(root_module['ns3::Vector3DValue'], 'VectorValue')
+ typehandlers.add_type_alias('ns3::Vector3D', 'ns3::Vector')
+ typehandlers.add_type_alias('ns3::Vector3D*', 'ns3::Vector*')
+ typehandlers.add_type_alias('ns3::Vector3D&', 'ns3::Vector&')
+ module.add_typedef(root_module['ns3::Vector3D'], 'Vector')
+ typehandlers.add_type_alias('ns3::Vector3DChecker', 'ns3::VectorChecker')
+ typehandlers.add_type_alias('ns3::Vector3DChecker*', 'ns3::VectorChecker*')
+ typehandlers.add_type_alias('ns3::Vector3DChecker&', 'ns3::VectorChecker&')
+ module.add_typedef(root_module['ns3::Vector3DChecker'], 'VectorChecker')
## Register a nested module for the namespace FatalImpl
@@ -186,6 +212,8 @@
register_Ns3TypeIdAttributeInformation_methods(root_module, root_module['ns3::TypeId::AttributeInformation'])
register_Ns3TypeIdTraceSourceInformation_methods(root_module, root_module['ns3::TypeId::TraceSourceInformation'])
register_Ns3UniformVariable_methods(root_module, root_module['ns3::UniformVariable'])
+ register_Ns3Vector2D_methods(root_module, root_module['ns3::Vector2D'])
+ register_Ns3Vector3D_methods(root_module, root_module['ns3::Vector3D'])
register_Ns3WeibullVariable_methods(root_module, root_module['ns3::WeibullVariable'])
register_Ns3ZetaVariable_methods(root_module, root_module['ns3::ZetaVariable'])
register_Ns3ZipfVariable_methods(root_module, root_module['ns3::ZipfVariable'])
@@ -231,6 +259,7 @@
register_Ns3JakesPropagationLossModel_methods(root_module, root_module['ns3::JakesPropagationLossModel'])
register_Ns3LogDistancePropagationLossModel_methods(root_module, root_module['ns3::LogDistancePropagationLossModel'])
register_Ns3MatrixPropagationLossModel_methods(root_module, root_module['ns3::MatrixPropagationLossModel'])
+ register_Ns3MobilityModel_methods(root_module, root_module['ns3::MobilityModel'])
register_Ns3NakagamiPropagationLossModel_methods(root_module, root_module['ns3::NakagamiPropagationLossModel'])
register_Ns3RandomVariableChecker_methods(root_module, root_module['ns3::RandomVariableChecker'])
register_Ns3RandomVariableValue_methods(root_module, root_module['ns3::RandomVariableValue'])
@@ -238,6 +267,10 @@
register_Ns3TimeValue_methods(root_module, root_module['ns3::TimeValue'])
register_Ns3TypeIdChecker_methods(root_module, root_module['ns3::TypeIdChecker'])
register_Ns3TypeIdValue_methods(root_module, root_module['ns3::TypeIdValue'])
+ register_Ns3Vector2DChecker_methods(root_module, root_module['ns3::Vector2DChecker'])
+ register_Ns3Vector2DValue_methods(root_module, root_module['ns3::Vector2DValue'])
+ register_Ns3Vector3DChecker_methods(root_module, root_module['ns3::Vector3DChecker'])
+ register_Ns3Vector3DValue_methods(root_module, root_module['ns3::Vector3DValue'])
return
def register_Ns3AttributeConstructionList_methods(root_module, cls):
@@ -648,6 +681,36 @@
[param('double', 's'), param('double', 'l')])
return
+def register_Ns3Vector2D_methods(root_module, cls):
+ cls.add_output_stream_operator()
+ ## vector.h (module 'core'): ns3::Vector2D::Vector2D(ns3::Vector2D const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Vector2D const &', 'arg0')])
+ ## vector.h (module 'core'): ns3::Vector2D::Vector2D(double _x, double _y) [constructor]
+ cls.add_constructor([param('double', '_x'), param('double', '_y')])
+ ## vector.h (module 'core'): ns3::Vector2D::Vector2D() [constructor]
+ cls.add_constructor([])
+ ## vector.h (module 'core'): ns3::Vector2D::x [variable]
+ cls.add_instance_attribute('x', 'double', is_const=False)
+ ## vector.h (module 'core'): ns3::Vector2D::y [variable]
+ cls.add_instance_attribute('y', 'double', is_const=False)
+ return
+
+def register_Ns3Vector3D_methods(root_module, cls):
+ cls.add_output_stream_operator()
+ ## vector.h (module 'core'): ns3::Vector3D::Vector3D(ns3::Vector3D const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Vector3D const &', 'arg0')])
+ ## vector.h (module 'core'): ns3::Vector3D::Vector3D(double _x, double _y, double _z) [constructor]
+ cls.add_constructor([param('double', '_x'), param('double', '_y'), param('double', '_z')])
+ ## vector.h (module 'core'): ns3::Vector3D::Vector3D() [constructor]
+ cls.add_constructor([])
+ ## vector.h (module 'core'): ns3::Vector3D::x [variable]
+ cls.add_instance_attribute('x', 'double', is_const=False)
+ ## vector.h (module 'core'): ns3::Vector3D::y [variable]
+ cls.add_instance_attribute('y', 'double', is_const=False)
+ ## vector.h (module 'core'): ns3::Vector3D::z [variable]
+ cls.add_instance_attribute('z', 'double', is_const=False)
+ return
+
def register_Ns3WeibullVariable_methods(root_module, cls):
## random-variable.h (module 'core'): ns3::WeibullVariable::WeibullVariable(ns3::WeibullVariable const & arg0) [copy constructor]
cls.add_constructor([param('ns3::WeibullVariable const &', 'arg0')])
@@ -1789,6 +1852,62 @@
is_const=True, visibility='private', is_virtual=True)
return
+def register_Ns3MobilityModel_methods(root_module, cls):
+ ## mobility-model.h (module 'mobility'): ns3::MobilityModel::MobilityModel(ns3::MobilityModel const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::MobilityModel const &', 'arg0')])
+ ## mobility-model.h (module 'mobility'): ns3::MobilityModel::MobilityModel() [constructor]
+ cls.add_constructor([])
+ ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetDistanceFrom(ns3::Ptr<const ns3::MobilityModel> position) const [member function]
+ cls.add_method('GetDistanceFrom',
+ 'double',
+ [param('ns3::Ptr< ns3::MobilityModel const >', 'position')],
+ is_const=True)
+ ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::GetPosition() const [member function]
+ cls.add_method('GetPosition',
+ 'ns3::Vector',
+ [],
+ is_const=True)
+ ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+ cls.add_method('GetRelativeSpeed',
+ 'double',
+ [param('ns3::Ptr< ns3::MobilityModel const >', 'other')],
+ is_const=True)
+ ## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
+ cls.add_method('GetTypeId',
+ 'ns3::TypeId',
+ [],
+ is_static=True)
+ ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::GetVelocity() const [member function]
+ cls.add_method('GetVelocity',
+ 'ns3::Vector',
+ [],
+ is_const=True)
+ ## mobility-model.h (module 'mobility'): void ns3::MobilityModel::SetPosition(ns3::Vector const & position) [member function]
+ cls.add_method('SetPosition',
+ 'void',
+ [param('ns3::Vector const &', 'position')])
+ ## mobility-model.h (module 'mobility'): void ns3::MobilityModel::NotifyCourseChange() const [member function]
+ cls.add_method('NotifyCourseChange',
+ 'void',
+ [],
+ is_const=True, visibility='protected')
+ ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::DoGetPosition() const [member function]
+ cls.add_method('DoGetPosition',
+ 'ns3::Vector',
+ [],
+ is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
+ ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::DoGetVelocity() const [member function]
+ cls.add_method('DoGetVelocity',
+ 'ns3::Vector',
+ [],
+ is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
+ ## mobility-model.h (module 'mobility'): void ns3::MobilityModel::DoSetPosition(ns3::Vector const & position) [member function]
+ cls.add_method('DoSetPosition',
+ 'void',
+ [param('ns3::Vector const &', 'position')],
+ is_pure_virtual=True, visibility='private', is_virtual=True)
+ return
+
def register_Ns3NakagamiPropagationLossModel_methods(root_module, cls):
## propagation-loss-model.h (module 'propagation'): static ns3::TypeId ns3::NakagamiPropagationLossModel::GetTypeId() [member function]
cls.add_method('GetTypeId',
@@ -1924,6 +2043,86 @@
[param('ns3::TypeId const &', 'value')])
return
+def register_Ns3Vector2DChecker_methods(root_module, cls):
+ ## vector.h (module 'core'): ns3::Vector2DChecker::Vector2DChecker() [constructor]
+ cls.add_constructor([])
+ ## vector.h (module 'core'): ns3::Vector2DChecker::Vector2DChecker(ns3::Vector2DChecker const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Vector2DChecker const &', 'arg0')])
+ return
+
+def register_Ns3Vector2DValue_methods(root_module, cls):
+ ## vector.h (module 'core'): ns3::Vector2DValue::Vector2DValue() [constructor]
+ cls.add_constructor([])
+ ## vector.h (module 'core'): ns3::Vector2DValue::Vector2DValue(ns3::Vector2DValue const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Vector2DValue const &', 'arg0')])
+ ## vector.h (module 'core'): ns3::Vector2DValue::Vector2DValue(ns3::Vector2D const & value) [constructor]
+ cls.add_constructor([param('ns3::Vector2D const &', 'value')])
+ ## vector.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::Vector2DValue::Copy() const [member function]
+ cls.add_method('Copy',
+ 'ns3::Ptr< ns3::AttributeValue >',
+ [],
+ is_const=True, is_virtual=True)
+ ## vector.h (module 'core'): bool ns3::Vector2DValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+ cls.add_method('DeserializeFromString',
+ 'bool',
+ [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
+ is_virtual=True)
+ ## vector.h (module 'core'): ns3::Vector2D ns3::Vector2DValue::Get() const [member function]
+ cls.add_method('Get',
+ 'ns3::Vector2D',
+ [],
+ is_const=True)
+ ## vector.h (module 'core'): std::string ns3::Vector2DValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+ cls.add_method('SerializeToString',
+ 'std::string',
+ [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
+ is_const=True, is_virtual=True)
+ ## vector.h (module 'core'): void ns3::Vector2DValue::Set(ns3::Vector2D const & value) [member function]
+ cls.add_method('Set',
+ 'void',
+ [param('ns3::Vector2D const &', 'value')])
+ return
+
+def register_Ns3Vector3DChecker_methods(root_module, cls):
+ ## vector.h (module 'core'): ns3::Vector3DChecker::Vector3DChecker() [constructor]
+ cls.add_constructor([])
+ ## vector.h (module 'core'): ns3::Vector3DChecker::Vector3DChecker(ns3::Vector3DChecker const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Vector3DChecker const &', 'arg0')])
+ return
+
+def register_Ns3Vector3DValue_methods(root_module, cls):
+ ## vector.h (module 'core'): ns3::Vector3DValue::Vector3DValue() [constructor]
+ cls.add_constructor([])
+ ## vector.h (module 'core'): ns3::Vector3DValue::Vector3DValue(ns3::Vector3DValue const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Vector3DValue const &', 'arg0')])
+ ## vector.h (module 'core'): ns3::Vector3DValue::Vector3DValue(ns3::Vector3D const & value) [constructor]
+ cls.add_constructor([param('ns3::Vector3D const &', 'value')])
+ ## vector.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::Vector3DValue::Copy() const [member function]
+ cls.add_method('Copy',
+ 'ns3::Ptr< ns3::AttributeValue >',
+ [],
+ is_const=True, is_virtual=True)
+ ## vector.h (module 'core'): bool ns3::Vector3DValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+ cls.add_method('DeserializeFromString',
+ 'bool',
+ [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
+ is_virtual=True)
+ ## vector.h (module 'core'): ns3::Vector3D ns3::Vector3DValue::Get() const [member function]
+ cls.add_method('Get',
+ 'ns3::Vector3D',
+ [],
+ is_const=True)
+ ## vector.h (module 'core'): std::string ns3::Vector3DValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+ cls.add_method('SerializeToString',
+ 'std::string',
+ [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
+ is_const=True, is_virtual=True)
+ ## vector.h (module 'core'): void ns3::Vector3DValue::Set(ns3::Vector3D const & value) [member function]
+ cls.add_method('Set',
+ 'void',
+ [param('ns3::Vector3D const &', 'value')])
+ return
+
def register_functions(root_module):
module = root_module
register_functions_ns3_FatalImpl(module.get_submodule('FatalImpl'), root_module)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/propagation/bindings/modulegen_customizations.py Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,5 @@
+
+def post_register_types(root_module):
+ root_module.add_include('"ns3/mobility-model.h"')
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/propagation/bindings/scan-header.h Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,2 @@
+#include "ns3/mobility-model.h"
+#include "ns3/propagation-module.h"
--- a/src/propagation/model/propagation-loss-model.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/propagation/model/propagation-loss-model.h Fri Dec 16 18:51:18 2011 +0100
@@ -56,7 +56,7 @@
/**
* \brief Enables a chain of loss models to act on the signal
- * \param The next PropagationLossModel to add to the chain
+ * \param next The next PropagationLossModel to add to the chain
*
* This method of chaining propagation loss models only works commutatively
* if the propagation loss of all models in the chain are independent
@@ -516,8 +516,8 @@
* \brief Set loss (in dB, positive) between pair of ns-3 objects
* (typically, nodes).
*
- * \param ma Source mobility model
- * \param mb Destination mobility model
+ * \param a ma Source mobility model
+ * \param b mb Destination mobility model
* \param loss a -> b path loss, positive in dB
* \param symmetric If true (default), both a->b and b->a paths will be affected
*/
--- a/src/spectrum/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/spectrum/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:51:18 2011 +0100
@@ -3495,6 +3495,10 @@
cls.add_constructor([param('ns3::SpectrumInterference const &', 'arg0')])
## spectrum-interference.h (module 'spectrum'): ns3::SpectrumInterference::SpectrumInterference() [constructor]
cls.add_constructor([])
+ ## spectrum-interference.h (module 'spectrum'): void ns3::SpectrumInterference::AbortRx() [member function]
+ cls.add_method('AbortRx',
+ 'void',
+ [])
## spectrum-interference.h (module 'spectrum'): void ns3::SpectrumInterference::AddSignal(ns3::Ptr<ns3::SpectrumValue const> spd, ns3::Time const duration) [member function]
cls.add_method('AddSignal',
'void',
@@ -4876,6 +4880,11 @@
'ns3::Vector',
[],
is_const=True)
+ ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+ cls.add_method('GetRelativeSpeed',
+ 'double',
+ [param('ns3::Ptr< ns3::MobilityModel const >', 'other')],
+ is_const=True)
## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
cls.add_method('GetTypeId',
'ns3::TypeId',
@@ -6248,14 +6257,14 @@
module.add_function('Norm',
'double',
[param('ns3::SpectrumValue const &', 'x')])
- ## spectrum-value.h (module 'spectrum'): extern ns3::SpectrumValue ns3::Pow(ns3::SpectrumValue const & base, double exp) [free function]
+ ## spectrum-value.h (module 'spectrum'): extern ns3::SpectrumValue ns3::Pow(ns3::SpectrumValue const & lhs, double rhs) [free function]
module.add_function('Pow',
'ns3::SpectrumValue',
- [param('ns3::SpectrumValue const &', 'base'), param('double', 'exp')])
- ## spectrum-value.h (module 'spectrum'): extern ns3::SpectrumValue ns3::Pow(double base, ns3::SpectrumValue const & exp) [free function]
+ [param('ns3::SpectrumValue const &', 'lhs'), param('double', 'rhs')])
+ ## spectrum-value.h (module 'spectrum'): extern ns3::SpectrumValue ns3::Pow(double lhs, ns3::SpectrumValue const & rhs) [free function]
module.add_function('Pow',
'ns3::SpectrumValue',
- [param('double', 'base'), param('ns3::SpectrumValue const &', 'exp')])
+ [param('double', 'lhs'), param('ns3::SpectrumValue const &', 'rhs')])
## spectrum-value.h (module 'spectrum'): extern double ns3::Prod(ns3::SpectrumValue const & x) [free function]
module.add_function('Prod',
'double',
--- a/src/spectrum/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/spectrum/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:51:18 2011 +0100
@@ -3495,6 +3495,10 @@
cls.add_constructor([param('ns3::SpectrumInterference const &', 'arg0')])
## spectrum-interference.h (module 'spectrum'): ns3::SpectrumInterference::SpectrumInterference() [constructor]
cls.add_constructor([])
+ ## spectrum-interference.h (module 'spectrum'): void ns3::SpectrumInterference::AbortRx() [member function]
+ cls.add_method('AbortRx',
+ 'void',
+ [])
## spectrum-interference.h (module 'spectrum'): void ns3::SpectrumInterference::AddSignal(ns3::Ptr<ns3::SpectrumValue const> spd, ns3::Time const duration) [member function]
cls.add_method('AddSignal',
'void',
@@ -4876,6 +4880,11 @@
'ns3::Vector',
[],
is_const=True)
+ ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+ cls.add_method('GetRelativeSpeed',
+ 'double',
+ [param('ns3::Ptr< ns3::MobilityModel const >', 'other')],
+ is_const=True)
## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
cls.add_method('GetTypeId',
'ns3::TypeId',
@@ -6248,14 +6257,14 @@
module.add_function('Norm',
'double',
[param('ns3::SpectrumValue const &', 'x')])
- ## spectrum-value.h (module 'spectrum'): extern ns3::SpectrumValue ns3::Pow(ns3::SpectrumValue const & base, double exp) [free function]
+ ## spectrum-value.h (module 'spectrum'): extern ns3::SpectrumValue ns3::Pow(ns3::SpectrumValue const & lhs, double rhs) [free function]
module.add_function('Pow',
'ns3::SpectrumValue',
- [param('ns3::SpectrumValue const &', 'base'), param('double', 'exp')])
- ## spectrum-value.h (module 'spectrum'): extern ns3::SpectrumValue ns3::Pow(double base, ns3::SpectrumValue const & exp) [free function]
+ [param('ns3::SpectrumValue const &', 'lhs'), param('double', 'rhs')])
+ ## spectrum-value.h (module 'spectrum'): extern ns3::SpectrumValue ns3::Pow(double lhs, ns3::SpectrumValue const & rhs) [free function]
module.add_function('Pow',
'ns3::SpectrumValue',
- [param('double', 'base'), param('ns3::SpectrumValue const &', 'exp')])
+ [param('double', 'lhs'), param('ns3::SpectrumValue const &', 'rhs')])
## spectrum-value.h (module 'spectrum'): extern double ns3::Prod(ns3::SpectrumValue const & x) [free function]
module.add_function('Prod',
'double',
--- a/src/spectrum/helper/adhoc-aloha-noack-ideal-phy-helper.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/spectrum/helper/adhoc-aloha-noack-ideal-phy-helper.h Fri Dec 16 18:51:18 2011 +0100
@@ -37,11 +37,7 @@
/**
* \ingroup spectrum
- *
- *
- * create the NetDevice depicted in the figure
- * @image html HdOfdmAlohaNoAck.png
- *
+ * \brief create the AlohaNoackNetDevice
*/
class AdhocAlohaNoackIdealPhyHelper
{
--- a/src/spectrum/model/spectrum-value.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/spectrum/model/spectrum-value.h Fri Dec 16 18:51:18 2011 +0100
@@ -434,23 +434,23 @@
/**
*
*
- * @param base the base
- * @param exp the exponent
+ * @param lhs the base
+ * @param rhs the exponent
*
* @return each value in base raised to the exponent
*/
- friend SpectrumValue Pow (const SpectrumValue& base, double exp);
+ friend SpectrumValue Pow (const SpectrumValue& lhs, double rhs);
/**
*
*
- * @param base the base
- * @param exp the exponent
+ * @param lhs the base
+ * @param rhs the exponent
*
* @return the value in base raised to each value in the exponent
*/
- friend SpectrumValue Pow (double base, const SpectrumValue& exp);
+ friend SpectrumValue Pow (double lhs, const SpectrumValue& rhs);
/**
*
@@ -535,15 +535,14 @@
double Norm (const SpectrumValue& x);
double Sum (const SpectrumValue& x);
double Prod (const SpectrumValue& x);
-SpectrumValue Pow (const SpectrumValue& base, double exp);
-SpectrumValue Pow (double base, const SpectrumValue& exp);
-SpectrumValue Log10 (const SpectrumValue& arg);
-SpectrumValue Log2 (const SpectrumValue& arg);
-SpectrumValue Log (const SpectrumValue& arg);
+SpectrumValue Pow (const SpectrumValue& lhs, double rhs);
+SpectrumValue Pow (double lhs, const SpectrumValue& rhs);
+SpectrumValue Log10 (const SpectrumValue& arg);
+SpectrumValue Log2 (const SpectrumValue& arg);
+SpectrumValue Log (const SpectrumValue& arg);
double Integral (const SpectrumValue& x);
} // namespace ns3
-
#endif /* SPECTRUM_VALUE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/ns3tcp/ns3tcp-no-delay-test-suite.cc Fri Dec 16 18:51:18 2011 +0100
@@ -0,0 +1,206 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ns3/log.h"
+#include "ns3/abort.h"
+#include "ns3/test.h"
+#include "ns3/pcap-file.h"
+#include "ns3/config.h"
+#include "ns3/string.h"
+#include "ns3/uinteger.h"
+#include "ns3/boolean.h"
+#include "ns3/data-rate.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/point-to-point-helper.h"
+#include "ns3/csma-helper.h"
+#include "ns3/internet-stack-helper.h"
+#include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/ipv4-address-helper.h"
+#include "ns3/packet-sink-helper.h"
+#include "ns3/tcp-socket-factory.h"
+#include "ns3/node-container.h"
+#include "ns3/simulator.h"
+#include "ns3tcp-socket-writer.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("Ns3TcpNoDelayTest");
+
+// ===========================================================================
+// Tests of Nagle's algorithm and the TCP no delay option
+// ===========================================================================
+//
+//
+class Ns3TcpNoDelayTestCase : public TestCase
+{
+public:
+ Ns3TcpNoDelayTestCase (bool noDelay);
+ virtual ~Ns3TcpNoDelayTestCase () {}
+
+private:
+ virtual void DoRun (void);
+ bool m_noDelay;
+ bool m_writeResults;
+
+ void SinkRx (std::string path, Ptr<const Packet> p, const Address &address);
+
+ TestVectors<uint32_t> m_inputs;
+ TestVectors<uint32_t> m_responses;
+};
+
+Ns3TcpNoDelayTestCase::Ns3TcpNoDelayTestCase (bool noDelay)
+ : TestCase ("Check that ns-3 TCP Nagle's algorithm works correctly and that we can turn it off."),
+ m_noDelay (noDelay),
+ m_writeResults (false)
+{
+}
+
+void
+Ns3TcpNoDelayTestCase::SinkRx (std::string path, Ptr<const Packet> p, const Address &address)
+{
+ m_responses.Add (p->GetSize ());
+}
+
+void
+Ns3TcpNoDelayTestCase::DoRun (void)
+{
+ uint16_t sinkPort = 50000;
+ double sinkStopTime = 8; // sec; will trigger Socket::Close
+ double writerStopTime = 5; // sec; will trigger Socket::Close
+ double simStopTime = 10; // sec
+ Time sinkStopTimeObj = Seconds (sinkStopTime);
+ Time writerStopTimeObj = Seconds (writerStopTime);
+ Time simStopTimeObj= Seconds (simStopTime);
+
+ Ptr<Node> n0 = CreateObject<Node> ();
+ Ptr<Node> n1 = CreateObject<Node> ();
+
+ PointToPointHelper pointToPoint;
+ pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
+ pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
+
+ NetDeviceContainer devices;
+ devices = pointToPoint.Install (n0, n1);
+
+ InternetStackHelper internet;
+ internet.InstallAll ();
+
+ Ipv4AddressHelper address;
+ address.SetBase ("10.1.1.0", "255.255.255.252");
+ Ipv4InterfaceContainer ifContainer = address.Assign (devices);
+
+ Ptr<SocketWriter> socketWriter = CreateObject<SocketWriter> ();
+ Address sinkAddress (InetSocketAddress (ifContainer.GetAddress (1), sinkPort));
+ socketWriter->Setup (n0, sinkAddress);
+ n0->AddApplication (socketWriter);
+ socketWriter->SetStartTime (Seconds (0.));
+ socketWriter->SetStopTime (writerStopTimeObj);
+
+ PacketSinkHelper sink ("ns3::TcpSocketFactory",
+ InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
+ ApplicationContainer apps = sink.Install (n1);
+ // Start the sink application at time zero, and stop it at sinkStopTime
+ apps.Start (Seconds (0.0));
+ apps.Stop (sinkStopTimeObj);
+
+ Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx",
+ MakeCallback (&Ns3TcpNoDelayTestCase::SinkRx, this));
+
+ // Enable or disable TCP no delay option
+ Config::SetDefault ("ns3::TcpSocket::TcpNoDelay", BooleanValue (m_noDelay));
+
+ // Connect the socket writer
+ Simulator::Schedule (Seconds (1), &SocketWriter::Connect, socketWriter);
+
+ // Write 5 packets to get some bytes in flight and some acks going
+ Simulator::Schedule (Seconds (2), &SocketWriter::Write, socketWriter, 2680);
+ m_inputs.Add (536);
+ m_inputs.Add (536);
+ m_inputs.Add (536);
+ m_inputs.Add (536);
+ m_inputs.Add (536);
+
+ // Write one byte after 10 ms to ensure that some data is outstanding
+ // and the window is big enough
+ Simulator::Schedule (Seconds (2.010), &SocketWriter::Write, socketWriter, 1);
+
+ // If Nagle is not enabled, i.e. no delay is on, add an input for a 1-byte
+ // packet to be received
+ if (m_noDelay)
+ {
+ m_inputs.Add (1);
+ }
+
+ // One ms later, write 535 bytes, i.e. one segment size - 1
+ Simulator::Schedule (Seconds (2.012), &SocketWriter::Write, socketWriter, 535);
+
+ // If Nagle is not enabled, add an input for a 535 byte packet,
+ // otherwise, we should get a single "full" packet of 536 bytes
+ if (m_noDelay)
+ {
+ m_inputs.Add (535);
+ }
+ else
+ {
+ m_inputs.Add (536);
+ }
+
+ // Close down the socket
+ Simulator::Schedule (writerStopTimeObj, &SocketWriter::Close, socketWriter);
+
+ if (m_writeResults)
+ {
+ std::ostringstream oss;
+ if (m_noDelay)
+ {
+ oss << "tcp-no-delay-on-test-case";
+ pointToPoint.EnablePcapAll (oss.str ());
+ }
+ else
+ {
+ oss << "tcp-no-delay-off-test-case";
+ pointToPoint.EnablePcapAll (oss.str ());
+ }
+ }
+
+ Simulator::Stop (simStopTimeObj);
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ // Compare inputs and outputs
+ NS_TEST_ASSERT_MSG_EQ (m_inputs.GetN (), m_responses.GetN (), "Incorrect number of expected receive events");
+ for (uint32_t i = 0; i < m_responses.GetN (); i++)
+ {
+ uint32_t in = m_inputs.Get (i);
+ uint32_t out = m_responses.Get (i);
+ NS_TEST_ASSERT_MSG_EQ (in, out, "Mismatch: expected " << in << " bytes, got " << out << " bytes");
+ }
+}
+
+class Ns3TcpNoDelayTestSuite : public TestSuite
+{
+public:
+ Ns3TcpNoDelayTestSuite ();
+};
+
+Ns3TcpNoDelayTestSuite::Ns3TcpNoDelayTestSuite ()
+ : TestSuite ("ns3-tcp-no-delay", SYSTEM)
+{
+ AddTestCase (new Ns3TcpNoDelayTestCase (true));
+ AddTestCase (new Ns3TcpNoDelayTestCase (false));
+}
+
+static Ns3TcpNoDelayTestSuite ns3TcpNoDelayTestSuite;
--- a/src/test/ns3tcp/trTidy.pl Fri Dec 16 18:50:05 2011 +0100
+++ b/src/test/ns3tcp/trTidy.pl Fri Dec 16 18:51:18 2011 +0100
@@ -1,3 +1,4 @@
+#!/usr/bin/perl
###
# *
# * Copyright (c) 2010 Adrian Sai-wah Tam
--- a/src/test/ns3tcp/wscript Fri Dec 16 18:50:05 2011 +0100
+++ b/src/test/ns3tcp/wscript Fri Dec 16 18:51:18 2011 +0100
@@ -28,6 +28,7 @@
'ns3tcp-socket-test-suite.cc',
'ns3tcp-loss-test-suite.cc',
'ns3tcp-state-test-suite.cc',
+ 'ns3tcp-no-delay-test-suite.cc',
]
if bld.env['NSC_ENABLED']:
--- a/src/topology-read/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/topology-read/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:51:18 2011 +0100
@@ -1591,14 +1591,16 @@
cls.add_method('AttributesEnd',
'std::_Rb_tree_const_iterator< std::pair< std::basic_string< char, std::char_traits< char >, std::allocator< char > > const, std::basic_string< char, std::char_traits< char >, std::allocator< char > > > >',
[])
- ## topology-reader.h (module 'topology-read'): std::string ns3::TopologyReader::Link::GetAttribute(std::string name) [member function]
+ ## topology-reader.h (module 'topology-read'): std::string ns3::TopologyReader::Link::GetAttribute(std::string name) const [member function]
cls.add_method('GetAttribute',
'std::string',
- [param('std::string', 'name')])
- ## topology-reader.h (module 'topology-read'): bool ns3::TopologyReader::Link::GetAttributeFailSafe(std::string name, std::string & value) [member function]
+ [param('std::string', 'name')],
+ is_const=True)
+ ## topology-reader.h (module 'topology-read'): bool ns3::TopologyReader::Link::GetAttributeFailSafe(std::string name, std::string & value) const [member function]
cls.add_method('GetAttributeFailSafe',
'bool',
- [param('std::string', 'name'), param('std::string &', 'value')])
+ [param('std::string', 'name'), param('std::string &', 'value')],
+ is_const=True)
## topology-reader.h (module 'topology-read'): ns3::Ptr<ns3::Node> ns3::TopologyReader::Link::GetFromNode() const [member function]
cls.add_method('GetFromNode',
'ns3::Ptr< ns3::Node >',
--- a/src/topology-read/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/topology-read/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:51:18 2011 +0100
@@ -1591,14 +1591,16 @@
cls.add_method('AttributesEnd',
'std::_Rb_tree_const_iterator< std::pair< std::basic_string< char, std::char_traits< char >, std::allocator< char > > const, std::basic_string< char, std::char_traits< char >, std::allocator< char > > > >',
[])
- ## topology-reader.h (module 'topology-read'): std::string ns3::TopologyReader::Link::GetAttribute(std::string name) [member function]
+ ## topology-reader.h (module 'topology-read'): std::string ns3::TopologyReader::Link::GetAttribute(std::string name) const [member function]
cls.add_method('GetAttribute',
'std::string',
- [param('std::string', 'name')])
- ## topology-reader.h (module 'topology-read'): bool ns3::TopologyReader::Link::GetAttributeFailSafe(std::string name, std::string & value) [member function]
+ [param('std::string', 'name')],
+ is_const=True)
+ ## topology-reader.h (module 'topology-read'): bool ns3::TopologyReader::Link::GetAttributeFailSafe(std::string name, std::string & value) const [member function]
cls.add_method('GetAttributeFailSafe',
'bool',
- [param('std::string', 'name'), param('std::string &', 'value')])
+ [param('std::string', 'name'), param('std::string &', 'value')],
+ is_const=True)
## topology-reader.h (module 'topology-read'): ns3::Ptr<ns3::Node> ns3::TopologyReader::Link::GetFromNode() const [member function]
cls.add_method('GetFromNode',
'ns3::Ptr< ns3::Node >',
--- a/src/topology-read/model/topology-reader.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/topology-read/model/topology-reader.cc Fri Dec 16 18:51:18 2011 +0100
@@ -49,7 +49,7 @@
}
void
-TopologyReader::SetFileName (const std::string fileName)
+TopologyReader::SetFileName (const std::string &fileName)
{
m_fileName = fileName;
}
@@ -94,7 +94,7 @@
}
-TopologyReader::Link::Link ( Ptr<Node> fromPtr, std::string fromName, Ptr<Node> toPtr, std::string toName )
+TopologyReader::Link::Link ( Ptr<Node> fromPtr, const std::string &fromName, Ptr<Node> toPtr, const std::string &toName )
{
m_fromPtr = fromPtr;
m_fromName = fromName;
@@ -131,14 +131,14 @@
}
std::string
-TopologyReader::Link::GetAttribute (std::string name) const
+TopologyReader::Link::GetAttribute (const std::string &name) const
{
- NS_ASSERT_MSG (m_linkAttr.find (name) == m_linkAttr.end (), "Requested topology link attribute not found");
+ NS_ASSERT_MSG (m_linkAttr.find (name) != m_linkAttr.end (), "Requested topology link attribute not found");
return m_linkAttr.find (name)->second;
}
bool
-TopologyReader::Link::GetAttributeFailSafe (std::string name, std::string &value) const
+TopologyReader::Link::GetAttributeFailSafe (const std::string &name, std::string &value) const
{
if ( m_linkAttr.find (name) == m_linkAttr.end () )
{
@@ -149,7 +149,7 @@
}
void
-TopologyReader::Link::SetAttribute (std::string name, std::string &value)
+TopologyReader::Link::SetAttribute (const std::string &name, const std::string &value)
{
m_linkAttr[name] = value;
}
--- a/src/topology-read/model/topology-reader.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/topology-read/model/topology-reader.h Fri Dec 16 18:51:18 2011 +0100
@@ -57,7 +57,7 @@
/**
* \brief Constant iterator to scan the map of link attributes.
*/
- typedef std::map<std::string, std::string >::const_iterator ConstAttributesIterator;
+ typedef std::map<std::string, std::string>::const_iterator ConstAttributesIterator;
/**
* \brief Constructor
@@ -66,7 +66,7 @@
* \param toPtr Ptr to the node the link is directed to
* \param toName name of the node the link is directed to
*/
- Link ( Ptr<Node> fromPtr, std::string fromName, Ptr<Node> toPtr, std::string toName );
+ Link ( Ptr<Node> fromPtr, const std::string &fromName, Ptr<Node> toPtr, const std::string &toName );
/**
* \brief Returns a Ptr<Node> to the "from" node of the link
@@ -95,7 +95,7 @@
*
* \return the value of the attribute
*/
- std::string GetAttribute (std::string name) const;
+ std::string GetAttribute (const std::string &name) const;
/**
* \brief Returns the value of a link attribute.
* \param name the name of the attribute
@@ -103,13 +103,13 @@
*
* \return true if the attribute was defined, false otherwise.
*/
- bool GetAttributeFailSafe (std::string name, std::string &value) const;
+ bool GetAttributeFailSafe (const std::string &name, std::string &value) const;
/**
* \brief Sets an arbitrary link attribute.
* \param name the name of the attribute
* \param value the value of the attribute
*/
- void SetAttribute (std::string name, std::string &value);
+ void SetAttribute (const std::string &name, const std::string &value);
/**
* \brief Returns an iterator to the begin of the attributes.
* \return a const iterator to the first attribute of a link.
@@ -127,7 +127,7 @@
Ptr< Node > m_fromPtr;
std::string m_toName;
Ptr< Node > m_toPtr;
- std::map<std::string, std::string > m_linkAttr;
+ std::map<std::string, std::string> m_linkAttr;
};
/**
@@ -157,7 +157,7 @@
* \brief Sets the input file name.
* \param fileName the input file name.
*/
- void SetFileName (const std::string fileName);
+ void SetFileName (const std::string &fileName);
/**
* \brief Returns the input file name.
--- a/src/uan/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/uan/bindings/modulegen__gcc_ILP32.py Fri Dec 16 18:51:18 2011 +0100
@@ -6010,6 +6010,11 @@
'ns3::Vector',
[],
is_const=True)
+ ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+ cls.add_method('GetRelativeSpeed',
+ 'double',
+ [param('ns3::Ptr< ns3::MobilityModel const >', 'other')],
+ is_const=True)
## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
cls.add_method('GetTypeId',
'ns3::TypeId',
--- a/src/uan/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:50:05 2011 +0100
+++ b/src/uan/bindings/modulegen__gcc_LP64.py Fri Dec 16 18:51:18 2011 +0100
@@ -6010,6 +6010,11 @@
'ns3::Vector',
[],
is_const=True)
+ ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetRelativeSpeed(ns3::Ptr<const ns3::MobilityModel> other) const [member function]
+ cls.add_method('GetRelativeSpeed',
+ 'double',
+ [param('ns3::Ptr< ns3::MobilityModel const >', 'other')],
+ is_const=True)
## mobility-model.h (module 'mobility'): static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
cls.add_method('GetTypeId',
'ns3::TypeId',
--- a/src/uan/helper/uan-helper.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/uan/helper/uan-helper.h Fri Dec 16 18:51:18 2011 +0100
@@ -1,10 +1,9 @@
/*
* Copyright (c) 2008 University of Washington
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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
@@ -12,7 +11,8 @@
* 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, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Leonard Tracy <lentracy@u.washington.edu>
*/
@@ -188,8 +188,8 @@
NetDeviceContainer Install (NodeContainer c) const;
/**
+ * \param c a set of nodes
* \param channel a channel to use
- * \param c a set of nodes
*
* For each of the input nodes, a new ns3::UanNetDevice is attached
* to the shared input channel. Each ns3::UanNetDevice is also
@@ -202,6 +202,7 @@
/**
* \param node a node where to install the uan components
+ * \param channel a channel to use
*
* Create a default uan stack with:
* - default channel, ideal propagation and default noise model
--- a/src/uan/model/uan-phy.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/uan/model/uan-phy.h Fri Dec 16 18:51:18 2011 +0100
@@ -169,7 +169,7 @@
public:
static TypeId GetTypeId (void);
- // / Enum defining possible Phy states
+ /// Enum defining possible Phy states
enum State
{
IDLE, CCABUSY, RX, TX, SLEEP
--- a/src/uan/model/uan-tx-mode.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/uan/model/uan-tx-mode.h Fri Dec 16 18:51:18 2011 +0100
@@ -200,7 +200,7 @@
*/
std::istream &operator >> (std::istream &is, UanModesList &ml);
-///UanModesList is attribute value
+/// UanModesList is attribute value
ATTRIBUTE_HELPER_HEADER (UanModesList);
} // namespace ns3
--- a/src/wifi/model/interference-helper.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/wifi/model/interference-helper.h Fri Dec 16 18:51:18 2011 +0100
@@ -121,7 +121,7 @@
double m_noiseFigure; /**< noise figure (linear) */
Ptr<ErrorRateModel> m_errorRateModel;
- ///Experimental: needed for energy duration calculation
+ /// Experimental: needed for energy duration calculation
NiChanges m_niChanges;
double m_firstPower;
bool m_rxing;
--- a/src/wifi/model/wifi-information-element-vector.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/wifi/model/wifi-information-element-vector.h Fri Dec 16 18:51:18 2011 +0100
@@ -46,7 +46,7 @@
WifiInformationElementVector ();
~WifiInformationElementVector ();
///\name Inherited from Header
- //\{
+ // \{
static TypeId GetTypeId ();
TypeId GetInstanceTypeId () const;
virtual uint32_t GetSerializedSize () const;
--- a/src/wifi/model/wifi-phy.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/wifi/model/wifi-phy.h Fri Dec 16 18:51:18 2011 +0100
@@ -252,11 +252,9 @@
*/
static WifiMode GetPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble);
- /**
- *
- *
+ /**
* \param payloadMode the WifiMode use for the transmission of the payload
- * \param preamble the type of preamble
+ * \param preamble the type of preamble
*
* \return the duration of the PLCP header in microseconds
*/
@@ -271,8 +269,8 @@
static uint32_t GetPlcpPreambleDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble);
/**
+ * \param size the number of bytes in the packet to send
* \param payloadMode the WifiMode use for the transmission of the payload
- * \param preamble the type of preamble
*
* \return the duration of the payload in microseconds
*/
--- a/src/wifi/model/wifi-remote-station-manager.h Fri Dec 16 18:50:05 2011 +0100
+++ b/src/wifi/model/wifi-remote-station-manager.h Fri Dec 16 18:51:18 2011 +0100
@@ -64,17 +64,17 @@
* because it resets time of last update.
*/
double CalculateAveragingCoefficient ();
- ///averaging coefficient depends on the memory time
+ /// averaging coefficient depends on the memory time
Time m_memoryTime;
- ///when last update has occured
+ /// when last update has occured
Time m_lastUpdate;
/// moving percentage of failed frames
double m_failAvg;
};
/**
+ * \ingroup wifi
* \brief hold a list of per-remote-station state.
- * \ingroup wifi
*
* \sa ns3::WifiRemoteStation.
*/
--- a/src/wimax/model/bs-scheduler-rtps.cc Fri Dec 16 18:50:05 2011 +0100
+++ b/src/wimax/model/bs-scheduler-rtps.cc Fri Dec 16 18:51:18 2011 +0100
@@ -110,23 +110,23 @@
m_downlinkBursts->push_back (std::make_pair (dlMapIe, burst));
}
+/**
+ * \brief A DownLink Scheduler for rtPS Flows
+ *
+ * The DL Scheduler assigns the available bandwidth in the following order:
+ * - IR Connections
+ * - Broadcast Connections
+ * - Basic and Primary Connections
+ * - UGS Connections
+ * - rtPS Connections
+ * - nrtPS Connections
+ * - BE Connections
+ * All rtPS flows that have packets in the queue can transmit at least one
+ * packet, according to the available bandwidth.
+ */
void
BSSchedulerRtps::Schedule (void)
{
- /**
- * \brief A DownLink Scheduler for rtPS Flows
- *
- * The DL Scheduler assigns the available bandwidth in the following order:
- * - IR Connections
- * - Broadcast Connections
- * - Basic and Primary Connections
- * - UGS Connections
- * - rtPS Connections
- * - nrtPS Connections
- * - BE Connections
- * All rtPS flows that have packets in the queue can transmit at least one
- * packet, according to the available bandwidth.
- */
uint32_t availableSymbols = GetBs ()->GetNrDlSymbols ();
--- a/wscript Fri Dec 16 18:50:05 2011 +0100
+++ b/wscript Fri Dec 16 18:51:18 2011 +0100
@@ -361,6 +361,10 @@
conf.report_optional_feature("static", "Static build", False,
"Link flag -Wl,--whole-archive,-Bstatic does not work")
+ # Set this so that the lists won't be printed at the end of this
+ # configure command.
+ conf.env['PRINT_BUILT_MODULES_AT_END'] = False
+
conf.env['MODULES_NOT_BUILT'] = []
conf.sub_config('src')
@@ -782,6 +786,10 @@
# and module test libraries have been set.
bld.add_subdirs('utils')
+ # Set this so that the lists will be printed at the end of this
+ # build command.
+ bld.env['PRINT_BUILT_MODULES_AT_END'] = True
+
if Options.options.run:
# Check that the requested program name is valid
program_name, dummy_program_argv = wutils.get_run_program(Options.options.run, wutils.get_command_template(env))
@@ -806,14 +814,8 @@
return
env = bld.env
- # Don't print the lists if a program is being run, a Python
- # program is being run, this a clean, or this is a distribution
- # clean.
- if ((not Options.options.run)
- and (not Options.options.pyrun)
- and ('clean' not in Options.commands)
- and ('distclean' not in Options.commands)
- and ('shell' not in Options.commands)):
+ # Only print the lists if a build was done.
+ if (env['PRINT_BUILT_MODULES_AT_END']):
# Print the list of built modules.
print
@@ -828,6 +830,10 @@
print_module_names(env['MODULES_NOT_BUILT'])
print
+ # Set this so that the lists won't be printed until the next
+ # build is done.
+ bld.env['PRINT_BUILT_MODULES_AT_END'] = False
+
# Write the build status file.
build_status_file = os.path.join(bld.out_dir, 'build-status.py')
out = open(build_status_file, 'w')
@@ -973,6 +979,10 @@
bld.cmd = "build"
bld.execute()
+ # Set this so that the lists won't be printed when the user
+ # exits the shell.
+ bld.env['PRINT_BUILT_MODULES_AT_END'] = False
+
if sys.platform == 'win32':
shell = os.environ.get("COMSPEC", "cmd.exe")
else: