merge
This commit is contained in:
@@ -8,7 +8,12 @@
|
||||
^doc/html
|
||||
^doc/latex
|
||||
^doc/ns3-object.txt
|
||||
^\.lock-wafbuild
|
||||
^\.lock-waf_darwin_build
|
||||
^\.lock-waf_linux2_build
|
||||
^\.lock-waf_cygwin_build
|
||||
^\.lock-waf_freebsd7_build
|
||||
^\.lock-waf_freebsd8_build
|
||||
^\.lock-waf_freebsd9_build
|
||||
^\.waf
|
||||
^doc/introspected-doxygen\.h$
|
||||
.*\.py[co]$
|
||||
|
||||
1
.hgtags
1
.hgtags
@@ -60,3 +60,4 @@ e48ed3aabca6ad71c8c49e4604c0f83345eda6a8 ns-3.11-RC3
|
||||
9843c12351cb5ceb9613c9db390d94073b713284 ns-3.11
|
||||
19c9e2b33b4a53f200be80cd49810bdfecf76770 ns-3.12-RC1
|
||||
167fc2274f53d4d89fdd769e4a7683ad7b6b7157 ns-3.12
|
||||
9007193fbb8d18b69a1feb6aec16501dcf138b6f ns-3.13
|
||||
|
||||
14
AUTHORS
14
AUTHORS
@@ -1,3 +1,4 @@
|
||||
Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
Kirill Andreev (andreev@iitp.ru)
|
||||
Dean Armstrong (deanarm@gmail.com)
|
||||
Nicola Baldo (nbaldo@cttc.es)
|
||||
@@ -6,6 +7,7 @@ Ramon Bauza (monbauza@gmail.com)
|
||||
Mehdi Benamor (mehdi.benamor@telecom-bretagne.eu)
|
||||
Raj Bhattacharjea (raj.b@gatech.edu)
|
||||
Timo Bingmann (timo.bingmann@student.kit.edu)
|
||||
Julien Boite <juboite@gmail.com>
|
||||
Elena Borovkova (borokovaes@iitp.ru)
|
||||
Pavel Boyko (boyko@iitp.ru)
|
||||
Dan Broyles (muxman@sbcglobal.net)
|
||||
@@ -25,9 +27,13 @@ Martin Giachino (martin.giachino@gmail.com,giachino@fing.edu.uy)
|
||||
Charline Taibi Guguen (charline.guguen@gmail.com)
|
||||
Tom Goff (tgoff@tgoff.net)
|
||||
David Gross (gdavid.devel@gmail.com)
|
||||
Daniel Halperin <daniel@halper.in>
|
||||
Tom Henderson (tomhend@u.washington.edu)
|
||||
Blake Hurd (naimorai@gmail.com)
|
||||
ishan <ishan.chhabra@gmail.com>
|
||||
Mohamed Amine Ismail (amine.ismail@inria.fr, iamine@udcast.com)
|
||||
Atishay Jain <atishayjain25@gmail.com>
|
||||
Sascha Alexander Jopen <jopen@informatik.uni-bonn.de>
|
||||
Sam Jansen (sam.jansen@gmail.com)
|
||||
Liu Jian (liujatp@gmail.com)
|
||||
Joe Kopena (tjkopena@cs.drexel.edu)
|
||||
@@ -35,12 +41,14 @@ Flavio Kobuta (flaviokubota@gmail.com)
|
||||
Aleksey Kovalenko (kovalenko@iitp.ru)
|
||||
Mathieu Lacage (mathieu.lacage@inria.fr)
|
||||
Emmanuelle Laprise (emmmanuelle.laprise@bluekazoo.ca)
|
||||
Björn Lichtblau (lichtbla@informatik.hu-berlin.de)
|
||||
Keith Ma (keith.nwsuaf@gmail.com)
|
||||
Federico Maguolo (maguolof@dei.unipd.it)
|
||||
Antti Makela (zarhan@cc.hut.fi)
|
||||
Francesco Malandrino (francesco.malandrino@gmail.com)
|
||||
Fabian Mauchle (f1mauchl@hsr.ch)
|
||||
Andrey Mazo (mazo@iitp.ru)
|
||||
Vedran Miletić <rivanvx@gmail.com>
|
||||
Faker Moatamri (faker.moatamri@inria.fr)
|
||||
Sidharth Nabar (snabar@uw.edu)
|
||||
Hemanth Narra (hemanth@ittc.ku.edu)
|
||||
@@ -48,9 +56,11 @@ Michael Nowatkowski (nowatkom@gmail.com)
|
||||
Duy Nguyen (duy@soe.ucsc.edu)
|
||||
Tommaso Pecorella (tommaso.pecorella@unifi.it)
|
||||
Josh Pelkey (jpelkey@gatech.edu)
|
||||
Colin Perkins <csp@csperkins.org>
|
||||
Giuseppe Piro (g.piro@poliba.it)
|
||||
Yana Podkosova (yanapdk@rambler.ru)
|
||||
Guangyu Pei (guangyu.pei@boeing.com)
|
||||
Andrea Ranieri <andreran@uno.it>
|
||||
Bruno Ranieri (Yrrsinn@googlemail.com)
|
||||
Ken Renard (kenneth.renard@arl.army.mil)
|
||||
George F. Riley (riley@ece.gatech.edu)
|
||||
@@ -61,13 +71,17 @@ Florian Schmidt (Florian.Schmidt@cs.rwth-aachen.de)
|
||||
Guillaume Seguin (guillaume.seguin@inria.fr)
|
||||
Kulin Shah (m.kulin@gmail.com)
|
||||
Phillip Sitbon (phillip.sitbon@gmail.com)
|
||||
Anirudh Sivaraman <sk.anirudh@gmail.com>
|
||||
Ewgenij Starostin (estar@cs.tu-berlin.de)
|
||||
YunQiang Su <wzssyqa@gmail.com>
|
||||
Lalith Suresh (suresh.lalith@gmail.com)
|
||||
Marcos Talau <talau@users.sourceforge.net>
|
||||
Adrian S. W. Tam (adrian.sw.tam@gmail.com)
|
||||
Hajime Tazaki (tazaki@sfc.wide.ad.jp)
|
||||
Wilson Thong (wilsonwk@ee.cityu.edu.hk)
|
||||
Mauro Tortonesi (mauro.tortonesi@unife.it)
|
||||
Quincy Tse (quincy.tse@gmail.com)
|
||||
Frederic Urbani (frederic.urbani@inria.fr)
|
||||
Andras Varga (andras@omnetpp.org)
|
||||
Sebastien Vincent (vincent@clarinet.u-strasbg.fr)
|
||||
Guillaume Vu-Brugier (gvubrugier@gmail.com)
|
||||
|
||||
29
CHANGES.html
29
CHANGES.html
@@ -53,7 +53,7 @@ This has a few changes for users and developers:
|
||||
<ul>
|
||||
<li> by default, "build" no longer has a subdirectory debug or optimized.
|
||||
To get different build directories for different build types, you can use
|
||||
the waf configure -o xxx option, e.g.:
|
||||
the waf configure -o <argument> option, e.g.:
|
||||
<pre>
|
||||
./waf configure -o shared
|
||||
./waf configure --enable-static -o static
|
||||
@@ -76,7 +76,10 @@ instead of CXXDEFINES
|
||||
|
||||
<h2>New API:</h2>
|
||||
<ul>
|
||||
<li> In the mobility module, there is a new API MobilityModel::GetRelativeSpeed() returning the relative speed of two objects. Proposed by Jens Mittag.</li>
|
||||
<li> In the mobility module, there is a new MobilityModel::GetRelativeSpeed() method returning the relative speed of two objects. </li>
|
||||
<li> A new Ipv6AddressGenerator class was added to generate sequential
|
||||
addresses from a provided base prefix and interfaceId. It also will detect
|
||||
duplicate address assigments. </li>
|
||||
</ul>
|
||||
|
||||
<h2>Changes to existing API:</h2>
|
||||
@@ -101,6 +104,28 @@ width standards has had a change in capitalization:
|
||||
|
||||
<h2>Changed behavior:</h2>
|
||||
<ul>
|
||||
<li> TCP bug fixes
|
||||
<ul>
|
||||
<li> Connection retries count is a separate variable with the retries limit, so cloned sockets can reset the count
|
||||
<li> Fix bug on RTO that may halt the data flow
|
||||
<li> Make TCP endpoints always holds the accurate address:port info
|
||||
<li> RST packet is sent on closed sockets
|
||||
<li> Fix congestion window sizing problem upon partial ACK in TcpNewReno
|
||||
<li> Acknowledgement is sent, rather than staying silent, upon arrival of unacceptable packets
|
||||
<li> Advance TcpSocketBase::m_nextTxSequence after RTO
|
||||
</ul>
|
||||
<li> TCP enhancements
|
||||
<ul>
|
||||
<li> Latest RTT value now stored in variable TcpSocketBase::m_lastRtt
|
||||
<li> The list variable TcpL4Protocol::m_sockets now always holds all the created, running TcpSocketBase objects
|
||||
<li> Maximum announced window size now an attribute, ns3::TcpSocketBase::MaxWindowSize
|
||||
<li> TcpHeader now recognizes ECE and CWR flags (c.f. RFC3168)
|
||||
<li> Added TCP option handling call in TcpSocketBase for future extension
|
||||
<li> Data out of range (i.e. outsize acceptable range of receive window) now computed on bytes, not packets
|
||||
<li> TCP moves from time-wait state to closed state after twice the time specified by attribute ns3:TcpSocketBase::MaxSegLifeTime
|
||||
<li> TcpNewReno supports limited transmit (RFC3042) if asserting boolean attribute ns3::TcpNewReno::LimitedTransmit
|
||||
<li> Nagle's algorithm supported. Default off, turn on by calling TcpSocket::SetTcpNoDelay(true)
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
@@ -14,7 +14,27 @@ Release 3.13
|
||||
|
||||
Availability
|
||||
------------
|
||||
This release is not yet available.
|
||||
This release is available from:
|
||||
http://www.nsnam.org/release/ns-allinone-3.13.tar.bz2
|
||||
|
||||
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.10 (32 bit) with g++-4.5.2
|
||||
- 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 16 (32/64 bit) with g++-4.6.2
|
||||
-- however, g++-3.4.6 fails on Fedora 16 i686
|
||||
- Fedora Core 14 (64 bit) with g++-4.5.1
|
||||
- FreeBSD 9.0-RC1 (AMD64) with g++-4.2.1
|
||||
|
||||
New user-visible features
|
||||
-------------------------
|
||||
- IPv6 address generator with support for duplicate address detection
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
@@ -59,21 +79,6 @@ Bugs fixed
|
||||
- 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
|
||||
------------
|
||||
In general, known issues are tracked on the project tracker available
|
||||
|
||||
@@ -38,7 +38,7 @@ def set_pybindgen_pythonpath(env):
|
||||
|
||||
|
||||
def options(opt):
|
||||
opt.tool_options('python', ["waf-tools"])
|
||||
opt.tool_options('python')
|
||||
opt.add_option('--disable-python',
|
||||
help=("Don't build Python bindings."),
|
||||
action="store_true", default=False,
|
||||
@@ -91,7 +91,7 @@ def configure(conf):
|
||||
conf.env.PYTHON = Options.options.with_python
|
||||
|
||||
try:
|
||||
conf.check_tool('python', ["waf-tools"])
|
||||
conf.check_tool('python')
|
||||
conf.check_python_version((2,3))
|
||||
conf.check_python_headers()
|
||||
except Configure.ConfigurationError, ex:
|
||||
@@ -479,7 +479,7 @@ def build(bld):
|
||||
bld.new_task_gen(features='copy',
|
||||
source="ns__init__.py",
|
||||
target='ns/__init__.py')
|
||||
bld.install_as('${PYTHONDIR}/ns/__init__.py', 'ns__init__.py')
|
||||
bld.install_as('${PYTHONARCHDIR}/ns/__init__.py', 'ns__init__.py')
|
||||
|
||||
|
||||
# note: the actual build commands for the python bindings are in
|
||||
|
||||
@@ -655,7 +655,6 @@ EXAMPLE_PATH = src/aodv/examples \
|
||||
src/propagation/examples \
|
||||
src/spectrum/examples \
|
||||
src/tap-bridge/examples \
|
||||
src/template/examples \
|
||||
src/tools/examples \
|
||||
src/topology-read/examples \
|
||||
src/uan/examples \
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
* - spectrum
|
||||
* - stats
|
||||
* - tap-bridge
|
||||
* - template
|
||||
* - test
|
||||
* - tools
|
||||
* - topology-read
|
||||
@@ -66,7 +65,6 @@
|
||||
* - wifi
|
||||
* - wimax
|
||||
*
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* \namespace ns3
|
||||
|
||||
@@ -11,15 +11,23 @@ IMAGES_EPS = \
|
||||
# rescale pdf figures as necessary
|
||||
$(FIGURES)/software-organization.pdf_width = 5in
|
||||
|
||||
IMAGES_PNG = \
|
||||
# Do not delete/clean these png images upon make clean
|
||||
IMAGES_PNG_SAVED = \
|
||||
$(FIGURES)/plot-2d.png \
|
||||
$(FIGURES)/plot-2d-with-error-bars.png \
|
||||
$(FIGURES)/plot-3d.png \
|
||||
|
||||
IMAGES_PNG_CONVERTED = \
|
||||
${IMAGES_EPS:.eps=.png}
|
||||
|
||||
IMAGES_PNG = $(IMAGES_PNG_SAVED) $(IMAGES_PNG_CONVERTED)
|
||||
|
||||
IMAGES_PDF = ${IMAGES_EPS:.eps=.pdf}
|
||||
|
||||
IMAGES = $(IMAGES_EPS) $(IMAGES_PNG) $(IMAGES_PDF)
|
||||
|
||||
IMAGES_TO_CLEAN = $(IMAGES_PNG_CONVERTED) $(IMAGES_PDF) $(IMAGES_EPS)
|
||||
|
||||
%.eps : %.dia; $(DIA) -t eps $< -e $@
|
||||
%.png : %.dia; $(DIA) -t png $< -e $@
|
||||
%.png : %.eps; $(CONVERT) $< $@
|
||||
@@ -60,7 +68,7 @@ help:
|
||||
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)
|
||||
-rm -rf $(IMAGES)
|
||||
-rm -rf $(IMAGES_TO_CLEAN)
|
||||
|
||||
frag: pickle
|
||||
@if test ! -d $(BUILDDIR)/frag; then mkdir $(BUILDDIR)/frag; fi
|
||||
@@ -161,3 +169,4 @@ doctest: $(IMAGES)
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
|
||||
|
||||
test: $(IMAGES)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
.. include:: replace.txt
|
||||
|
||||
.. _Attributes:
|
||||
|
||||
Attributes
|
||||
----------
|
||||
|
||||
@@ -58,7 +60,7 @@ For most basic usage (syntax), treat a smart pointer like a regular pointer:::
|
||||
CreateObject
|
||||
++++++++++++
|
||||
|
||||
As we discussed above in :ref:`Memory management and class Ptr`, at the
|
||||
As we discussed above in :ref:`Memory-management-and-class-Ptr`, at the
|
||||
lowest-level API, objects of type :cpp:class:`ns3::Object` are not instantiated
|
||||
using ``operator new`` as usual but instead by a templated function called
|
||||
:cpp:func:`CreateObject()`.
|
||||
@@ -412,7 +414,7 @@ determine the required concrete configuration namespaced path.::
|
||||
|
||||
Config::Set ("/Names/server/eth0/TxQueue/MaxPackets", UintegerValue (25));
|
||||
|
||||
:ref:`Object names` for a fuller treatment of the |ns3| configuration namespace.
|
||||
:ref:`Object-names` for a fuller treatment of the |ns3| configuration namespace.
|
||||
|
||||
Setting through constructors helper classes
|
||||
+++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
@@ -249,7 +249,7 @@ use of class Object?
|
||||
This is an important design step; whether to use class :cpp:class:`Object` as a
|
||||
base class for your new classes.
|
||||
|
||||
As described in the chapter on the |ns3| :ref:`Object model`, classes that
|
||||
As described in the chapter on the |ns3| :ref:`Object-model`, classes that
|
||||
inherit from class :cpp:class:`Object` get special properties:
|
||||
|
||||
* the |ns3| type and attribute system (see :ref:`Attributes`)
|
||||
@@ -370,7 +370,7 @@ certain objects can be created via the object creation framework
|
||||
|
||||
The macro ``NS_OBJECT_ENSURE_REGISTERED (classname)`` is needed also once for
|
||||
every class that defines a new GetTypeId method, and it does the actual
|
||||
registration of the class into the system. The :ref:`Object model` chapter
|
||||
registration of the class into the system. The :ref:`Object-model` chapter
|
||||
discusses this in more detail.
|
||||
|
||||
how to include files from elsewhere
|
||||
|
||||
@@ -39,59 +39,47 @@ Not all directories will be present in each module.
|
||||
Step 2 - Create your new module based on the template module
|
||||
************************************************************
|
||||
|
||||
The template module ::
|
||||
A python program is provided in the source directory that will create a skeleton for a new module ::
|
||||
|
||||
src/template
|
||||
src/create-module.py
|
||||
|
||||
is a skeleton module that shows how modules should be created.
|
||||
For the purposes of this discussion we will assume that your new module is called "new-module". From the ``src`` directory, do the following to create the new module: ::
|
||||
|
||||
For the purposes of this discussion we will assume that your new module is called "new-module". From the top level |ns3| directory, do the following to copy the template module to a new directory with the same name as your new module: ::
|
||||
./create-module.py new-module
|
||||
|
||||
cp -r src/template src/new-module
|
||||
Next, cd into ``new-module``; you will find this directory layout: ::
|
||||
|
||||
Now you will need to open the following file in your favorite text editor: ::
|
||||
examples helper model test wscript
|
||||
|
||||
src/new-module/wscript
|
||||
|
||||
and replace all of the occurrences of "template" in this wscript file with the name of your new module, i.e. "new-module" for our assumed module name.
|
||||
|
||||
You will also need to specify the |ns3| modules your new module will
|
||||
depend on. Let's assume that "new-module" depends on the internet,
|
||||
We next walk through how to customize this module. All |ns3| modules
|
||||
depend on the 'core' module and usually on other modules. This
|
||||
dependency is specified in the wscript file.
|
||||
Let's assume that 'new-module' depends on the internet,
|
||||
mobility, and aodv modules. Then the call to the function that will
|
||||
create this module should look like this when you are done with this
|
||||
step: ::
|
||||
create this module should look like this before editing: ::
|
||||
|
||||
module = bld.create_ns3_module('new-module', ['internet', 'mobility', 'aodv'])
|
||||
def build(bld):
|
||||
module = bld.create_ns3_module('new-module', ['core'])
|
||||
|
||||
As an example, the dependencies for the spectrum module are specified
|
||||
in ::
|
||||
and after editing: ::
|
||||
|
||||
src/spectrum/wscript
|
||||
def build(bld):
|
||||
module = bld.create_ns3_module('new-module', ['internet', 'mobility', 'aodv'])
|
||||
|
||||
with the following function call: ::
|
||||
Your module will most likely have model source files. Initial skeletons (which will compile successfully) are created in ``model/new-module.cc`` and ``model/new-module.h``.
|
||||
|
||||
module = bld.create_ns3_module('spectrum', ['internet', 'propagation',
|
||||
'applications'])
|
||||
If your module will have helper source files, then they will go into the helper/ directory; again, initial skeletons are created in that directory.
|
||||
|
||||
If your module will have model source files, then create the following directory where they will go: ::
|
||||
Finally, it is good practice to write tests. A skeleton test suite and test case is created in the test/ directory. The below constructor specifies that it will be a unit test named 'new-module': ::
|
||||
|
||||
mkdir src/new-module/model
|
||||
New-moduleTestSuite::New-moduleTestSuite ()
|
||||
: TestSuite ("new-module", UNIT)
|
||||
{
|
||||
AddTestCase (new New-moduleTestCase1);
|
||||
}
|
||||
|
||||
Copy all of your module's model source files to the above directory.
|
||||
|
||||
If your module will have helper source files, then create the following directory where they will go: ::
|
||||
|
||||
mkdir src/new-module/helper
|
||||
|
||||
Copy all of your module's helper source files to the above directory.
|
||||
|
||||
If your module will have tests, then copy all of your module's test files to the following directory: ::
|
||||
|
||||
mkdir src/new-module/test
|
||||
|
||||
|
||||
Step 3 - Specify your module's source files
|
||||
*******************************************
|
||||
Step 3 - Adding to your module's source files
|
||||
*********************************************
|
||||
|
||||
If your new module has model and/or helper source files, then they
|
||||
must be specified in your ::
|
||||
@@ -139,7 +127,7 @@ with the following function call, module name, and list of header
|
||||
files. Note that the argument for the function new_task_gen() tells
|
||||
waf to install this module's headers with the other |ns3| headers: ::
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
|
||||
headers.module = 'spectrum'
|
||||
|
||||
@@ -194,7 +182,7 @@ As an example, the examples for the core module are specified in ::
|
||||
|
||||
The core module's C++ examples are specified using the following
|
||||
function calls and source file names. Note that the second argument
|
||||
for the function create_ns3_program() is the list of modules that the
|
||||
for the function ``create_ns3_program()`` is the list of modules that the
|
||||
program being created depends on: ::
|
||||
|
||||
obj = bld.create_ns3_program('main-callback', ['core'])
|
||||
@@ -210,18 +198,16 @@ depends on: ::
|
||||
|
||||
bld.register_ns3_script('sample-simulator.py', ['core'])
|
||||
|
||||
Step 7 - Specify which of your module's examples should be run
|
||||
**************************************************************
|
||||
Step 7 - Specify which of your module's examples should be run as tests
|
||||
***********************************************************************
|
||||
|
||||
If your new module has examples, then you must specify which of them
|
||||
should be run in your ::
|
||||
The test framework can also be instrumented to run example programs to
|
||||
try to catch regressions in the examples. However, not all examples
|
||||
are suitable for regression tests. A file called ``examples-to-run.py``
|
||||
that exists in each module's test directory can control the invocation
|
||||
of the examples when the test framework runs.
|
||||
|
||||
src/new-module/test/examples-to-run.py
|
||||
|
||||
file by modifying it with your text editor. These examples are run by
|
||||
test.py.
|
||||
|
||||
As an example, the examples that are run by test.py for the core module are specified in ::
|
||||
As an example, the examples that are run by ``test.py`` for the core module are specified in ::
|
||||
|
||||
src/core/test/examples-to-run.py
|
||||
|
||||
@@ -279,47 +265,15 @@ depend on waf configuration variables. For example, ::
|
||||
|
||||
("realtime-udp-echo.py", "ENABLE_REAL_TIME == False"),
|
||||
|
||||
If your new module has examples, then you must specify which of them
|
||||
should be run in your ::
|
||||
|
||||
Step 8 - Add your module to the list on |ns3| modules
|
||||
*****************************************************
|
||||
src/new-module/test/examples-to-run.py
|
||||
|
||||
Your new module must be added to the current list of |ns3| modules by modifying the following wscript file with your text editor: ::
|
||||
file by modifying it with your text editor. These examples are run by
|
||||
test.py.
|
||||
|
||||
src/wscript
|
||||
|
||||
In that file, you will find the following list of modules ::
|
||||
|
||||
all_modules = (
|
||||
'core',
|
||||
'network',
|
||||
'config-store',
|
||||
'internet',
|
||||
.
|
||||
.
|
||||
.
|
||||
'point-to-point-layout',
|
||||
'csma-layout',
|
||||
'template',
|
||||
)
|
||||
|
||||
Add your new module's name to the list like this ::
|
||||
|
||||
all_modules = (
|
||||
'core',
|
||||
'network',
|
||||
'config-store',
|
||||
'internet',
|
||||
.
|
||||
.
|
||||
.
|
||||
'point-to-point-layout',
|
||||
'csma-layout',
|
||||
'template',
|
||||
'new-module',
|
||||
)
|
||||
|
||||
|
||||
Step 9 - Build and test your new module
|
||||
Step 8 - Build and test your new module
|
||||
***************************************
|
||||
|
||||
You can now build and test your module as normal: ::
|
||||
@@ -328,4 +282,4 @@ You can now build and test your module as normal: ::
|
||||
./waf build
|
||||
./test.py
|
||||
|
||||
|
||||
and look for your new module's test suite (and example programs, if enabled) in the test output.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
.. include:: replace.txt
|
||||
|
||||
.. _Object-model:
|
||||
|
||||
Object model
|
||||
------------
|
||||
|
||||
@@ -67,6 +69,8 @@ system.
|
||||
In practice, class :cpp:class:`Object` is the variant of the three above that
|
||||
the |ns3| developer will most commonly encounter.
|
||||
|
||||
.. _Memory-management-and-class-Ptr:
|
||||
|
||||
Memory management and class Ptr
|
||||
*******************************
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
.. include:: replace.txt
|
||||
|
||||
.. _Object-names:
|
||||
|
||||
Object names
|
||||
------------
|
||||
|
||||
|
||||
@@ -239,9 +239,9 @@ Organization of the Monolithic Python Bindings
|
||||
|
||||
The monolithic Python API definitions are organized as follows. For each |ns3| module <name>, the file ``bindings/python/ns3_module_<name>.py`` describes its API. Each of those files have 3 toplevel functions:
|
||||
|
||||
#. :cpp:func:`def register_types(module)`: this function takes care of registering new types (e.g. C++ classes, enums) that are defined in tha module;
|
||||
#. :cpp:func:`def register_methods(module)`: this function calls, for each class <name>, another function register_methods_Ns3<name>(module). These latter functions add method definitions for each class;
|
||||
#. :cpp:func:`def register_functions(module)`: this function registers |ns3| functions that belong to that module.
|
||||
#. :py:func:`def register_types(module)`: this function takes care of registering new types (e.g. C++ classes, enums) that are defined in tha module;
|
||||
#. :py:func:`def register_methods(module)`: this function calls, for each class <name>, another function register_methods_Ns3<name>(module). These latter functions add method definitions for each class;
|
||||
#. :py:func:`def register_functions(module)`: this function registers |ns3| functions that belong to that module.
|
||||
|
||||
Modular Python Bindings
|
||||
***********************
|
||||
|
||||
@@ -264,7 +264,7 @@ list, so "/NodeList/0" refers to the zeroth node in the list of nodes created by
|
||||
the simulation. This node is actually a ``Ptr<Node>`` and so is a subclass of
|
||||
an :cpp:class:`ns3::Object`.
|
||||
|
||||
As described in the :ref:`Object Model` section, |ns3| supports an object
|
||||
As described in the :ref:`Object-model` section, |ns3| supports an object
|
||||
aggregation model. The next path segment begins with the "$" character which
|
||||
indicates a ``GetObject`` call should be made looking for the type that follows.
|
||||
When a node is initialized by an ``InternetStackHelper`` a number of interfaces
|
||||
|
||||
@@ -45,6 +45,7 @@ SOURCES = \
|
||||
$(SRC)/wifi/doc/wifi.rst \
|
||||
$(SRC)/wimax/doc/wimax.rst \
|
||||
$(SRC)/uan/doc/uan.rst \
|
||||
$(SRC)/topology-read/doc/topology.rst \
|
||||
$(SRC)/stats/doc/statistics.rst \
|
||||
$(SRC)/netanim/doc/animation.rst \
|
||||
$(SRC)/flow-monitor/doc/flow-monitor.rst \
|
||||
|
||||
@@ -7,17 +7,8 @@ Conclusion
|
||||
Futures
|
||||
*******
|
||||
|
||||
This document is a work in process. We hope and expect it to grow over time
|
||||
to cover more and more of the nuts and bolts of |ns3|.
|
||||
|
||||
We hope to add the following chapters over the next few releases:
|
||||
|
||||
* The Callback System
|
||||
* The Object System and Memory Management
|
||||
* The Routing System
|
||||
* Adding a New NetDevice and Channel
|
||||
* Adding a New Protocol
|
||||
* Working with Real Networks and Hosts
|
||||
This document is intended as a living document. We hope and expect it to
|
||||
grow over time to cover more and more of the nuts and bolts of |ns3|.
|
||||
|
||||
Writing manual and tutorial chapters is not something we all get excited about,
|
||||
but it is very important to the project. If you are an expert in one of these
|
||||
@@ -28,10 +19,13 @@ Closing
|
||||
*******
|
||||
|
||||
|ns3| is a large and complicated system. It is impossible to cover all
|
||||
of the things you will need to know in one small tutorial.
|
||||
of the things you will need to know in one small tutorial. Readers
|
||||
who want to learn more are encouraged to read the following additional
|
||||
documentation:
|
||||
|
||||
We have really just scratched the surface of |ns3| in this tutorial,
|
||||
but we hope to have covered enough to get you started doing useful networking
|
||||
research using our favorite simulator.
|
||||
* The |ns3| manual
|
||||
* The |ns3| model library documentatio
|
||||
* The |ns3| Doxygen (API documentation)
|
||||
* The |ns3| wiki
|
||||
|
||||
-- The |ns3| development team.
|
||||
|
||||
@@ -53,7 +53,6 @@ that approach, you can get a copy of ``ns-3-allinone`` by typing the
|
||||
following into your Linux shell (assuming you have installed Mercurial):
|
||||
|
||||
::
|
||||
|
||||
cd
|
||||
mkdir repos
|
||||
cd repos
|
||||
@@ -69,11 +68,12 @@ following displayed,
|
||||
adding changesets
|
||||
adding manifests
|
||||
adding file changes
|
||||
added 31 changesets with 45 changes to 7 files
|
||||
added 47 changesets with 67 changes to 7 files
|
||||
updating to branch default
|
||||
7 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||
|
||||
After the clone command completes, you should have a directory called
|
||||
``ns-3-allinone`` under your ``~/repos`` directory, the contents of which should
|
||||
``ns-3-allinone``, the contents of which should
|
||||
look something like the following:
|
||||
|
||||
::
|
||||
@@ -221,7 +221,7 @@ As mentioned above, one practice is to create a directory called ``repos``
|
||||
in one's home directory under which one can keep local Mercurial repositories.
|
||||
One could also keep a ``tarballs`` directory. *Hint: the tutorial
|
||||
will assume you downloaded into a ``repos`` directory, so remember the
|
||||
placekeeper.``* If you adopt the ``tarballs`` directory approach, you can
|
||||
placekeeper.* If you adopt the ``tarballs`` directory approach, you can
|
||||
get a copy of a release by typing the following into your Linux shell
|
||||
(substitute the appropriate version numbers, of course):
|
||||
|
||||
@@ -230,15 +230,15 @@ get a copy of a release by typing the following into your Linux shell
|
||||
cd
|
||||
mkdir tarballs
|
||||
cd tarballs
|
||||
wget http://www.nsnam.org/releases/ns-allinone-3.10.tar.bz2
|
||||
tar xjf ns-allinone-3.10.tar.bz2
|
||||
wget http://www.nsnam.org/releases/ns-allinone-3.13.tar.bz2
|
||||
tar xjf ns-allinone-3.13.tar.bz2
|
||||
|
||||
If you change into the directory ``ns-allinone-3.10`` you should see a
|
||||
If you change into the directory ``ns-allinone-3.13`` you should see a
|
||||
number of files:
|
||||
|
||||
::
|
||||
|
||||
build.py ns-3.10/ pybindgen-0.15.0/ util.py
|
||||
build.py ns-3.13/ pybindgen-0.15.0.795/ util.py
|
||||
constants.py nsc-0.5.2/ README
|
||||
|
||||
You are now ready to build the |ns3| distribution.
|
||||
@@ -248,16 +248,20 @@ Building ns-3
|
||||
|
||||
Building with build.py
|
||||
++++++++++++++++++++++
|
||||
The first time you build the |ns3| project you should build using the
|
||||
``allinone`` environment. This will get the project configured for you
|
||||
in the most commonly useful way.
|
||||
The first time you build the |ns3| project you can build using a
|
||||
convenience program found in the
|
||||
``allinone`` directory. This program is called ``build.py``. This
|
||||
program will get the project configured for you
|
||||
in the most commonly useful way. However, please note that more advanced
|
||||
configuration and work with |ns3| will typically involve using the
|
||||
native |ns3| build system, Waf, to be introduced later in this tutorial.
|
||||
|
||||
Change into the directory you created in the download section above. If you
|
||||
downloaded using Mercurial you should have a directory called
|
||||
``ns-3-allinone`` under your ``~/repos`` directory. If you downloaded
|
||||
using a tarball you should have a directory called something like
|
||||
``ns-allinone-3.10`` under your ``~/tarballs`` directory. Take a deep
|
||||
breath and type the following:
|
||||
``ns-allinone-3.13`` under your ``~/tarballs`` directory.
|
||||
Type the following:
|
||||
|
||||
::
|
||||
|
||||
@@ -265,8 +269,10 @@ breath and type the following:
|
||||
|
||||
Because we are working with examples and tests in this tutorial, and
|
||||
because they are not built by default in |ns3|, the arguments for
|
||||
build.py tells it to build them for us. In the future you can build
|
||||
|ns3| without examples and tests if you wish.
|
||||
build.py tells it to build them for us. The program also defaults to
|
||||
building all available modules. Later, you can build
|
||||
|ns3| without examples and tests, or eliminate the modules that
|
||||
are not necessary for your work, if you wish.
|
||||
|
||||
You will see lots of typical compiler output messages displayed as the build
|
||||
script builds the various pieces you downloaded. Eventually you should see the
|
||||
@@ -274,7 +280,7 @@ following magic words:
|
||||
|
||||
::
|
||||
|
||||
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
|
||||
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3.13/build'
|
||||
'build' finished successfully (2m30.586s)
|
||||
|
||||
Modules built:
|
||||
@@ -292,12 +298,12 @@ following magic words:
|
||||
topology-read uan virtual-net-device
|
||||
visualizer wifi wimax
|
||||
|
||||
Once the project has built you can say goodbye to your old friends, the
|
||||
Once the project has built, you can stop working with the
|
||||
``ns-3-allinone`` scripts. You got what you needed from them and will now
|
||||
interact directly with Waf and we do it in the ``ns-3-dev`` directory,
|
||||
interact directly with Waf and we do it in the |ns3| directory,
|
||||
not in the ``ns-3-allinone`` directory. Go ahead and change into the
|
||||
``ns-3-dev`` directory (or the directory for the appropriate release you
|
||||
downloaded.
|
||||
|ns3| directory (or the directory for the appropriate release or
|
||||
development snapshot that you downloaded; e.g.
|
||||
|
||||
::
|
||||
|
||||
@@ -305,7 +311,8 @@ downloaded.
|
||||
|
||||
Building with Waf
|
||||
+++++++++++++++++
|
||||
We use Waf to configure and build the |ns3| project. It's not
|
||||
Most users directly use Waf to configure and build the |ns3| project.
|
||||
It's not
|
||||
strictly required at this point, but it will be valuable to take a slight
|
||||
detour and look at how to make changes to the configuration of the project.
|
||||
Probably the most useful configuration change you can make will be to
|
||||
@@ -313,14 +320,19 @@ build the optimized version of the code. By default you have configured
|
||||
your project to build the debug version. Let's tell the project to
|
||||
make an optimized build. To explain to Waf that it should do optimized
|
||||
builds that include the examples and tests, you will need to execute the
|
||||
following command,
|
||||
following commands,
|
||||
|
||||
::
|
||||
|
||||
./waf clean
|
||||
./waf -d optimized --enable-examples --enable-tests configure
|
||||
|
||||
This runs Waf out of the local directory (which is provided as a convenience
|
||||
for you). As the build system checks for various dependencies you should see
|
||||
for you). The first command to clean out the previous build is not
|
||||
typically strictly necessary but is good practice; it will remove the
|
||||
previously built libraries and object files found in directory ``build/``.
|
||||
When the project is reconfigured and the build system checks for various
|
||||
dependencies, you should see
|
||||
output that looks similar to the following,
|
||||
|
||||
::
|
||||
@@ -396,15 +408,20 @@ Now go ahead and switch back to the debug build that includes the examples and t
|
||||
|
||||
::
|
||||
|
||||
./waf clean
|
||||
./waf -d debug --enable-examples --enable-tests configure
|
||||
|
||||
The build system is now configured and you can build the debug versions of
|
||||
the |ns3| programs by simply typing,
|
||||
the |ns3| programs by simply typing
|
||||
|
||||
::
|
||||
|
||||
./waf
|
||||
|
||||
Okay, sorry, I made you build the |ns3| part of the system twice,
|
||||
but now you know how to change the configuration and build optimized code.
|
||||
|
||||
Here are a few more introductory tips about Waf.
|
||||
Some waf commands are meaningful during the build phase and some commands are valid
|
||||
in the configuration phase. For example, if you wanted to use the emulation
|
||||
features of |ns3|, you might want to enable setting the suid bit using
|
||||
@@ -425,8 +442,17 @@ available in waf. To explore these options, type:
|
||||
|
||||
We'll use some of the testing-related commands in the next section.
|
||||
|
||||
Okay, sorry, I made you build the |ns3| part of the system twice,
|
||||
but now you know how to change the configuration and build optimized code.
|
||||
Finally, as an aside, it is possible to specify that waf builds the
|
||||
project in
|
||||
a directory different than the default ``build/`` directory by passing
|
||||
the ``-o`` option to configure; e.g.
|
||||
|
||||
::
|
||||
|
||||
./waf -d debug -o build/debug --enable-examples --enable-tests configure
|
||||
|
||||
This allows users to work with multiple builds rather than always
|
||||
overwriting the last build.
|
||||
|
||||
Testing ns-3
|
||||
************
|
||||
@@ -443,7 +469,7 @@ see a report saying that,
|
||||
|
||||
::
|
||||
|
||||
47 of 47 tests passed (47 passed, 0 failed, 0 crashed, 0 valgrind errors)
|
||||
92 of 92 tests passed (92 passed, 0 failed, 0 crashed, 0 valgrind errors)
|
||||
|
||||
This is the important message.
|
||||
|
||||
@@ -486,9 +512,9 @@ You will also see output from the test runner and the output will actually look
|
||||
PASS: TestSuite basic-random-number
|
||||
PASS: TestSuite object
|
||||
PASS: TestSuite random-number-generators
|
||||
95 of 95 tests passed (95 passed, 0 failed, 0 crashed, 0 valgrind errors)
|
||||
92 of 92 tests passed (92 passed, 0 failed, 0 crashed, 0 valgrind errors)
|
||||
|
||||
This command is typically run by ``users`` to quickly verify that an
|
||||
This command is typically run by users to quickly verify that an
|
||||
|ns3| distribution has built correctly.
|
||||
|
||||
Running a Script
|
||||
|
||||
@@ -25,48 +25,49 @@ A few key points are worth noting at the onset:
|
||||
* Ns-3 is not an extension of `ns-2
|
||||
<http://www.isi.edu/nsnam/ns>`_;
|
||||
it is a new simulator. The two simulators are both written in C++ but
|
||||
|ns3| is a new simulator that does not support the ns-2 APIs. Some
|
||||
models from ns-2 have already been ported from ns-2 to |ns3|. The
|
||||
project will continue to maintain ns-2 while |ns3| is being built,
|
||||
|ns3| is a new simulator that does not support the |ns2| APIs. Some
|
||||
models from |ns2| have already been ported from |ns2| to |ns3|. The
|
||||
project will continue to maintain |ns2| while |ns3| is being built,
|
||||
and will study transition and integration mechanisms.
|
||||
* |ns3| is open-source, and the project strives to maintain an
|
||||
open environment for researchers to contribute and share their software.
|
||||
open environment for researchers to contribute and share their software.
|
||||
|
||||
|
||||
For ns-2 Users
|
||||
**************
|
||||
For |ns2| Users
|
||||
***************
|
||||
|
||||
For those familiar with ns-2, the most visible outward change when moving to
|
||||
|ns3| is the choice of scripting language. Ns-2 is
|
||||
For those familiar with |ns2|, the most visible outward change when moving to
|
||||
|ns3| is the choice of scripting language. Programs in |ns2| are
|
||||
scripted in OTcl and results of simulations can be visualized using the
|
||||
Network Animator nam. It is not possible to run a simulation
|
||||
in ns-2 purely from C++ (i.e., as a main() program without any OTcl).
|
||||
Moreover, some components of ns-2 are written in C++ and others in OTcl.
|
||||
in |ns2| purely from C++ (i.e., as a main() program without any OTcl).
|
||||
Moreover, some components of |ns2| are written in C++ and others in OTcl.
|
||||
In |ns3|, the simulator is written entirely in C++, with optional
|
||||
Python bindings. Simulation scripts can therefore be written in C++
|
||||
or in Python. The results of some simulations can be visualized by
|
||||
nam, but new animators are under development. Since |ns3|
|
||||
or in Python. New animators and visualizers are available and under
|
||||
current development. Since |ns3|
|
||||
generates pcap packet trace files, other utilities can be used to
|
||||
analyze traces as well.
|
||||
In this tutorial, we will first concentrate on scripting
|
||||
directly in C++ and interpreting results via trace files.
|
||||
|
||||
But there are similarities as well (both, for example, are based on C++
|
||||
objects, and some code from ns-2 has already been ported to |ns3|).
|
||||
We will try to highlight differences between ns-2 and |ns3|
|
||||
objects, and some code from |ns2| has already been ported to |ns3|).
|
||||
We will try to highlight differences between |ns2| and |ns3|
|
||||
as we proceed in this tutorial.
|
||||
|
||||
A question that we often hear is "Should I still use ns-2 or move to
|
||||
A question that we often hear is "Should I still use |ns2| or move to
|
||||
|ns3|?" The answer is that it depends. |ns3| does not have
|
||||
all of the models that ns-2 currently has, but on the other hand, |ns3|
|
||||
all of the models that |ns2| currently has, but on the other hand, |ns3|
|
||||
does have new capabilities (such as handling multiple interfaces on nodes
|
||||
correctly, use of IP addressing and more alignment with Internet
|
||||
protocols and designs, more detailed 802.11 models, etc.). ns-2
|
||||
models can usually be ported to |ns3| (a porting guide is under
|
||||
development). There is active development on multiple fronts for
|
||||
|ns3|. The |ns3| developers believe (and certain early users
|
||||
have proven) that |ns3| is ready for active use, and should be an
|
||||
attractive alternative for users looking to start new simulation projects.
|
||||
protocols and designs, more detailed 802.11 models, etc.). |ns2|
|
||||
models can sometimes be ported to |ns3| (a porting guide is under
|
||||
development). The support available on the user mailing list, and the
|
||||
developer and maintainer activity, is higher for |ns3|. A good guideline
|
||||
would be to look at both simulators, and in particular the models available
|
||||
for your research, but when in doubt or when starting new simulation
|
||||
projects, choose the tool that is under more active development (|ns3|).
|
||||
|
||||
Contributing
|
||||
************
|
||||
@@ -75,13 +76,13 @@ Contributing
|
||||
research community. It will rely on the ongoing contributions of the
|
||||
community to develop new models, debug or maintain existing ones, and share
|
||||
results. There are a few policies that we hope will encourage people to
|
||||
contribute to |ns3| like they have for ns-2:
|
||||
contribute to |ns3| like they have for |ns2|:
|
||||
|
||||
* Open source licensing based on GNU GPLv2 compatibility
|
||||
* `wiki
|
||||
<http://www.nsnam.org/wiki/index.php>`_
|
||||
* `Contributed Code
|
||||
<http://www.nsnam.org/wiki/index.php/Contributed_Code>`_ page, similar to ns-2's popular Contributed Code
|
||||
<http://www.nsnam.org/wiki/index.php/Contributed_Code>`_ page, similar to |ns2|'s popular Contributed Code
|
||||
`page
|
||||
<http://nsnam.isi.edu/nsnam/index.php/Contributed_Code>`_
|
||||
* Open `bug tracker
|
||||
|
||||
@@ -10,7 +10,7 @@ There are several important resources of which any |ns3| user must be
|
||||
aware. The main web site is located at http://www.nsnam.org and
|
||||
provides access to basic information about the |ns3| system. Detailed
|
||||
documentation is available through the main web site at
|
||||
http://www.nsnam.org/documents.html. You can also find documents
|
||||
http://www.nsnam.org/documentation/. You can also find documents
|
||||
relating to the system architecture from this page.
|
||||
|
||||
There is a Wiki that complements the main |ns3| web site which you will
|
||||
@@ -61,9 +61,7 @@ using the Python language.
|
||||
|
||||
The build system Waf is used on the |ns3| project. It is one
|
||||
of the new generation of Python-based build systems. You will not need to
|
||||
understand any Python to build the existing |ns3| system, and will
|
||||
only have to understand a tiny and intuitively obvious subset of Python in
|
||||
order to extend the system in most cases.
|
||||
understand any Python to build the existing |ns3| system.
|
||||
|
||||
For those interested in the gory details of Waf, the main web site can be
|
||||
found at http://code.google.com/p/waf/.
|
||||
@@ -72,7 +70,7 @@ Development Environment
|
||||
***********************
|
||||
|
||||
As mentioned above, scripting in |ns3| is done in C++ or Python.
|
||||
As of ns-3.2, most of the |ns3| API is available in Python, but the
|
||||
Most of the |ns3| API is available in Python, but the
|
||||
models are written in C++ in either case. A working
|
||||
knowledge of C++ and object-oriented concepts is assumed in this document.
|
||||
We will take some time to review some of the more advanced concepts or
|
||||
@@ -98,26 +96,10 @@ neither make nor autotools. We use Waf for these functions.
|
||||
Typically an |ns3| author will work in Linux or a Linux-like
|
||||
environment. For those running under Windows, there do exist environments
|
||||
which simulate the Linux environment to various degrees. The |ns3|
|
||||
project supports development in the Cygwin environment for
|
||||
project has in the past (but not presently) supported development in the Cygwin environment for
|
||||
these users. See http://www.cygwin.com/
|
||||
for details on downloading (MinGW is presently not officially supported,
|
||||
although some of the project maintainers to work with it). Cygwin provides
|
||||
many of the popular Linux system commands. It can, however, sometimes be
|
||||
problematic due to the way it actually does its emulation, and sometimes
|
||||
interactions with other Windows software can cause problems.
|
||||
|
||||
If you do use Cygwin or MinGW; and use Logitech products, we will save you
|
||||
quite a bit of heartburn right off the bat and encourage you to take a look
|
||||
at the `MinGW FAQ
|
||||
<http://oldwiki.mingw.org/index.php/FAQ>`_.
|
||||
|
||||
Search for "Logitech" and read the FAQ entry, "why does make often
|
||||
crash creating a sh.exe.stackdump file when I try to compile my source code."
|
||||
Believe it or not, the ``Logitech Process Monitor`` insinuates itself into
|
||||
every DLL in the system when it is running. It can cause your Cygwin or
|
||||
MinGW DLLs to die in mysterious ways and often prevents debuggers from
|
||||
running. Beware of Logitech software when using Cygwin.
|
||||
|
||||
for details on downloading, and visit the |ns3| wiki for more information
|
||||
about Cygwin and |ns3|. MinGW is presently not officially supported.
|
||||
Another alternative to Cygwin is to install a virtual machine environment
|
||||
such as VMware server and install a Linux virtual machine.
|
||||
|
||||
|
||||
@@ -89,6 +89,12 @@ configure ns-3 with Click Integration support::
|
||||
|
||||
$: ./waf configure --enable-examples --enable-tests --with-nsclick=/path/to/click/source
|
||||
|
||||
Hint: If you have click installed one directory above ns-3 (such as in the
|
||||
ns-3-allinone directory), and the name of the directory is 'click' (or
|
||||
a symbolic link to the directory is named 'click'), then the --with-nsclick
|
||||
specifier is not necessary; the ns-3 build system will successfully find
|
||||
the directory.
|
||||
|
||||
If it says 'enabled' beside 'NS-3 Click Integration Support', then you're good to go. Note: If running modular ns-3, the minimum set of modules required to run all ns-3-click examples is wifi, csma and config-store.
|
||||
|
||||
Next, try running one of the examples::
|
||||
|
||||
@@ -256,11 +256,48 @@ Ipv4ClickRouting::GetClickInstanceFromSimNode (simclick_node_t *simnode)
|
||||
return m_clickInstanceFromSimNode[simnode];
|
||||
}
|
||||
|
||||
struct timeval
|
||||
Ipv4ClickRouting::GetTimevalFromNow () const
|
||||
{
|
||||
struct timeval curtime;
|
||||
uint64_t remainder = 0;
|
||||
|
||||
curtime.tv_sec = Simulator::Now ().GetSeconds ();
|
||||
curtime.tv_usec = Simulator::Now ().GetMicroSeconds () % 1000000;
|
||||
|
||||
switch (Simulator::Now ().GetResolution())
|
||||
{
|
||||
case Time::NS:
|
||||
remainder = Simulator::Now ().GetNanoSeconds () % 1000;
|
||||
break;
|
||||
case Time::PS:
|
||||
remainder = Simulator::Now ().GetPicoSeconds () % 1000000;
|
||||
break;
|
||||
case Time::FS:
|
||||
remainder = Simulator::Now ().GetFemtoSeconds () % 1000000000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (remainder)
|
||||
{
|
||||
++curtime.tv_usec;
|
||||
if (curtime.tv_usec == 1000000)
|
||||
{
|
||||
++curtime.tv_sec;
|
||||
curtime.tv_usec = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return curtime;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4ClickRouting::RunClickEvent ()
|
||||
{
|
||||
m_simNode->curtime.tv_sec = Simulator::Now ().GetSeconds ();
|
||||
m_simNode->curtime.tv_usec = Simulator::Now ().GetMicroSeconds () % 1000000;
|
||||
m_simNode->curtime = GetTimevalFromNow ();
|
||||
|
||||
NS_LOG_DEBUG ("RunClickEvent at " << m_simNode->curtime.tv_sec << " " <<
|
||||
m_simNode->curtime.tv_usec << " " << Simulator::Now ());
|
||||
simclick_click_run (m_simNode);
|
||||
@@ -311,8 +348,7 @@ void
|
||||
Ipv4ClickRouting::SendPacketToClick (int ifid, int ptype, const unsigned char* data, int len)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << ifid);
|
||||
m_simNode->curtime.tv_sec = Simulator::Now ().GetSeconds ();
|
||||
m_simNode->curtime.tv_usec = Simulator::Now ().GetMicroSeconds () % 1000000;
|
||||
m_simNode->curtime = GetTimevalFromNow ();
|
||||
|
||||
// Since packets in ns-3 don't have global Packet ID's and Flow ID's, we
|
||||
// feed dummy values into pinfo. This avoids the need to make changes in the Click code
|
||||
|
||||
@@ -180,6 +180,11 @@ private:
|
||||
*/
|
||||
void AddSimNodeToClickMapping ();
|
||||
|
||||
/**
|
||||
* \brief Get current simulation time as a timeval
|
||||
*/
|
||||
struct timeval GetTimevalFromNow () const;
|
||||
|
||||
/**
|
||||
* \brief This method has to be scheduled everytime Click calls SIMCLICK_SCHEDULE
|
||||
*/
|
||||
|
||||
@@ -19,6 +19,11 @@ def build(bld):
|
||||
'helper/%(MODULE)s-helper.cc',
|
||||
]
|
||||
|
||||
module_test = bld.create_ns3_module_test_library('%(MODULE)s')
|
||||
module_test.source = [
|
||||
'test/%(MODULE)s-test-suite.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = %(MODULE)r
|
||||
headers.source = [
|
||||
@@ -135,6 +140,76 @@ main (int argc, char *argv[])
|
||||
'''
|
||||
|
||||
|
||||
TEST_CC_TEMPLATE = '''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
|
||||
// Include a header file from your module to test.
|
||||
#include "ns3/%(MODULE)s.h"
|
||||
|
||||
// An essential include is test.h
|
||||
#include "ns3/test.h"
|
||||
|
||||
// Do not put your test classes in namespace ns3. You may find it useful
|
||||
// to use the using directive to access the ns3 namespace directly
|
||||
using namespace ns3;
|
||||
|
||||
// This is an example TestCase.
|
||||
class %(CAPITALIZED)sTestCase1 : public TestCase
|
||||
{
|
||||
public:
|
||||
%(CAPITALIZED)sTestCase1 ();
|
||||
virtual ~%(CAPITALIZED)sTestCase1 ();
|
||||
|
||||
private:
|
||||
virtual void DoRun (void);
|
||||
};
|
||||
|
||||
// Add some help text to this case to describe what it is intended to test
|
||||
%(CAPITALIZED)sTestCase1::%(CAPITALIZED)sTestCase1 ()
|
||||
: TestCase ("%(CAPITALIZED)s test case (does nothing)")
|
||||
{
|
||||
}
|
||||
|
||||
// This destructor does nothing but we include it as a reminder that
|
||||
// the test case should clean up after itself
|
||||
%(CAPITALIZED)sTestCase1::~%(CAPITALIZED)sTestCase1 ()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// This method is the pure virtual method from class TestCase that every
|
||||
// TestCase must implement
|
||||
//
|
||||
void
|
||||
%(CAPITALIZED)sTestCase1::DoRun (void)
|
||||
{
|
||||
// A wide variety of test macros are available in src/core/test.h
|
||||
NS_TEST_ASSERT_MSG_EQ (true, true, "true doesn't equal true for some reason");
|
||||
// Use this one for floating point comparisons
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (0.01, 0.01, 0.001, "Numbers are not equal within tolerance");
|
||||
}
|
||||
|
||||
// The TestSuite class names the TestSuite, identifies what type of TestSuite,
|
||||
// and enables the TestCases to be run. Typically, only the constructor for
|
||||
// this class must be defined
|
||||
//
|
||||
class %(CAPITALIZED)sTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
%(CAPITALIZED)sTestSuite ();
|
||||
};
|
||||
|
||||
%(CAPITALIZED)sTestSuite::%(CAPITALIZED)sTestSuite ()
|
||||
: TestSuite ("%(MODULE)s", UNIT)
|
||||
{
|
||||
AddTestCase (new %(CAPITALIZED)sTestCase1);
|
||||
}
|
||||
|
||||
// Do not forget to allocate an instance of this TestSuite
|
||||
static %(CAPITALIZED)sTestSuite %(MODULE)sTestSuite;
|
||||
|
||||
'''
|
||||
|
||||
|
||||
def main(argv):
|
||||
parser = OptionParser(usage=("Usage: %prog [options] modulename\n"
|
||||
"Utility script to create a basic template for a new ns-3 module"))
|
||||
@@ -174,6 +249,17 @@ def main(argv):
|
||||
|
||||
|
||||
|
||||
#
|
||||
# test
|
||||
#
|
||||
testdir = os.path.join(moduledir, "test")
|
||||
os.mkdir(testdir)
|
||||
test_cc = file(os.path.join(moduledir, "test", "%s-test-suite.cc" % modname), "wt")
|
||||
test_cc.write(TEST_CC_TEMPLATE % dict(MODULE=modname,CAPITALIZED=modname.capitalize()))
|
||||
test_cc.close()
|
||||
|
||||
|
||||
|
||||
#
|
||||
# helper
|
||||
#
|
||||
|
||||
@@ -6,10 +6,13 @@ Routing overview
|
||||
|ns3| is intended to support traditional routing approaches and protocols,
|
||||
support ports of open source routing implementations, and facilitate research
|
||||
into unorthodox routing techniques. The overall routing architecture is
|
||||
described below in :ref:`Routing architecture`. Users who wish to just read
|
||||
about how to configure global routing for wired topologies can read :ref:`Global
|
||||
centralized routing`. Unicast routing protocols are described in :ref:`Unicast
|
||||
routing`. Multicast routing is documented in :ref:`Multicast routing`.
|
||||
described below in :ref:`Routing-architecture`. Users who wish to just read
|
||||
about how to configure global routing for wired topologies can read
|
||||
:ref:`Global-centralized-routing`. Unicast routing protocols are described in
|
||||
:ref:`Unicast-routing`. Multicast routing is documented in
|
||||
:ref:`Multicast-routing`.
|
||||
|
||||
.. _Routing-architecture:
|
||||
|
||||
Routing architecture
|
||||
********************
|
||||
@@ -72,11 +75,13 @@ prioritized routing protocols (Ipv4ListRouting::AddRoutingProtocol(),
|
||||
Ipv4ListRouting::GetRoutingProtocol()).
|
||||
|
||||
The details of these routing protocols are described below in
|
||||
:ref:`Unicast routing`. For now, we will first start with a basic
|
||||
:ref:`Unicast-routing`. For now, we will first start with a basic
|
||||
unicast routing capability that is intended to globally build routing
|
||||
tables at simulation time t=0 for simulation users who do not care
|
||||
about dynamic routing.
|
||||
|
||||
.. _Global-centralized-routing:
|
||||
|
||||
Global centralized routing
|
||||
**************************
|
||||
|
||||
@@ -204,6 +209,8 @@ Advertisement for each router, and this link state database is
|
||||
fed into the OSPF shortest path computation logic. The Ipv4 API
|
||||
is finally used to populate the routes themselves.
|
||||
|
||||
.. _Unicast-routing:
|
||||
|
||||
Unicast routing
|
||||
***************
|
||||
|
||||
@@ -321,6 +328,8 @@ respond to dynamic changes to a device's IP address or link up/down
|
||||
notifications; i.e. the topology changes are due to loss/gain of connectivity
|
||||
over a wireless channel.
|
||||
|
||||
.. _Multicast-routing:
|
||||
|
||||
Multicast routing
|
||||
*****************
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ helper API, the TCP that is aggregated to nodes with an Internet stack is the
|
||||
native |ns3| TCP.
|
||||
|
||||
To configure behavior of TCP, a number of parameters are exported through the
|
||||
:ref:`Attributes <ns-3 attribute system>`. These are documented in the `Doxygen
|
||||
|ns3| attribute system. These are documented in the `Doxygen
|
||||
<http://www.nsnam.org/doxygen/classns3_1_1_tcp_socket.html>` for class
|
||||
:cpp:class:`TcpSocket`. For example, the maximum segment size is a
|
||||
settable attribute.
|
||||
@@ -137,7 +137,7 @@ the specified node, one would have to do something like:::
|
||||
|
||||
Once a TCP socket is created, one will want to follow conventional socket logic
|
||||
and either connect() and send() (for a TCP client) or bind(), listen(), and
|
||||
accept() (for a TCP server). :ref:`Sockets API <Sockets APIs>` for a review of
|
||||
accept() (for a TCP server). See :ref:`Sockets-APIs` for a review of
|
||||
how sockets are used in |ns3|.
|
||||
|
||||
Validation
|
||||
@@ -255,7 +255,7 @@ sockets, as described above and documented in `Doxygen
|
||||
<http://www.nsnam.org/doxygen/classns3_1_1_tcp_socket.html>`_
|
||||
|
||||
Additionally, NSC TCP exports a lot of configuration variables into the
|
||||
|ns3| :ref:`Attributes` system, via a `sysctl <http://en.wikipedia.org/wiki/Sysctl>`_-like interface. In the ``examples/tcp/tcp-nsc-zoo`` example, you
|
||||
|ns3| attributes system, via a `sysctl <http://en.wikipedia.org/wiki/Sysctl>`_-like interface. In the ``examples/tcp/tcp-nsc-zoo`` example, you
|
||||
can see the following configuration:::
|
||||
|
||||
|
||||
|
||||
@@ -35,6 +35,29 @@ class Socket;
|
||||
*
|
||||
* This abstract class defines the API for IPv6 RAW socket factory.
|
||||
*
|
||||
* A RAW Socket typically is used to access specific IP layers not usually
|
||||
* available through L4 sockets, e.g., ICMP. The implementer should take
|
||||
* particular care to define the Ipv6RawSocketImpl Attributes, and in
|
||||
* particular the Protocol attribute.
|
||||
* Not setting it will result in a zero protocol at IP level (corresponding
|
||||
* to the HopByHop IPv6 Extension header, i.e., Ipv6ExtensionHopByHopHeader)
|
||||
* when sending data through the socket, which is probably not the intended
|
||||
* behavior.
|
||||
*
|
||||
* A correct example is (from src/applications/model/radvd.cc):
|
||||
* \code
|
||||
if (!m_socket)
|
||||
{
|
||||
TypeId tid = TypeId::LookupByName ("ns3::Ipv6RawSocketFactory");
|
||||
m_socket = Socket::CreateSocket (GetNode (), tid);
|
||||
|
||||
NS_ASSERT (m_socket);
|
||||
|
||||
m_socket->SetAttribute ("Protocol", UintegerValue(Ipv6Header::IPV6_ICMPV6));
|
||||
m_socket->SetRecvCallback (MakeCallback (&Radvd::HandleRead, this));
|
||||
}
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
class Ipv6RawSocketFactory : public SocketFactory
|
||||
{
|
||||
|
||||
@@ -36,6 +36,30 @@ class Node;
|
||||
/**
|
||||
* \class Ipv6RawSocketImpl
|
||||
* \brief IPv6 raw socket.
|
||||
*
|
||||
* A RAW Socket typically is used to access specific IP layers not usually
|
||||
* available through L4 sockets, e.g., ICMP. The implementer should take
|
||||
* particular care to define the Ipv6RawSocketImpl Attributes, and in
|
||||
* particular the Protocol attribute.
|
||||
* Not setting it will result in a zero protocol at IP level (corresponding
|
||||
* to the HopByHop IPv6 Extension header, i.e., Ipv6ExtensionHopByHopHeader)
|
||||
* when sending data through the socket, which is probably not the intended
|
||||
* behavior.
|
||||
*
|
||||
* A correct example is (from src/applications/model/radvd.cc):
|
||||
* \code
|
||||
if (!m_socket)
|
||||
{
|
||||
TypeId tid = TypeId::LookupByName ("ns3::Ipv6RawSocketFactory");
|
||||
m_socket = Socket::CreateSocket (GetNode (), tid);
|
||||
|
||||
NS_ASSERT (m_socket);
|
||||
|
||||
m_socket->SetAttribute ("Protocol", UintegerValue(Ipv6Header::IPV6_ICMPV6));
|
||||
m_socket->SetRecvCallback (MakeCallback (&Radvd::HandleRead, this));
|
||||
}
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
class Ipv6RawSocketImpl : public Socket
|
||||
{
|
||||
|
||||
@@ -50,12 +50,22 @@ class ConstantVelocityMobilityModel;
|
||||
$ns at $time $node set Z_ Z1
|
||||
\endverbatim
|
||||
*
|
||||
* Following tools are known to support this format:
|
||||
* The following tools are known to support this format:
|
||||
* - BonnMotion http://net.cs.uni-bonn.de/wg/cs/applications/bonnmotion/
|
||||
* - SUMO http://sourceforge.net/apps/mediawiki/sumo/index.php?title=Main_Page
|
||||
* - TraNS http://trans.epfl.ch/
|
||||
*
|
||||
* See usage example in examples/mobility/ns2-mobility-trace.cc
|
||||
*
|
||||
* \bug Traces that generate initial position statements at the end of the
|
||||
* mobility file (e.g. SUMO TraceExporter) will not be read correctly. The
|
||||
* workaround is to relocate these three initial position statements to the
|
||||
* beginning of the trace.
|
||||
* See https://www.nsnam.org/bugzilla/show_bug.cgi?id=1316
|
||||
*
|
||||
* \bug Rounding errors may cause movement to diverge from the mobility
|
||||
* pattern in ns-2 (using the same trace).
|
||||
* See https://www.nsnam.org/bugzilla/show_bug.cgi?id=1316
|
||||
*/
|
||||
class Ns2MobilityHelper
|
||||
{
|
||||
|
||||
@@ -4,97 +4,45 @@ Animation
|
||||
---------
|
||||
|
||||
Animation is an important tool for network simulation. While |ns3| does not
|
||||
contain a default graphical animation tool, it does provide an animation
|
||||
interface for use with stand-alone animators. One such animator called NetAnim,
|
||||
presently supporting packet flow animation for point-to-point links, has been
|
||||
developed. Other animators and visualization tools are in development; they may
|
||||
make use of the existing animation interface or may develop new ones,
|
||||
contain a default graphical animation tool, we currently have two ways to provide
|
||||
animation, namely using the PyViz method or the NetAnim method.
|
||||
The PyViz method is described in http://www.nsnam.org/wiki/index.php/PyViz.
|
||||
The NetAnim method is described in detail at http://www.nsnam.org/wiki/index.php/NetAnim.
|
||||
We will describe the NetAnim method briefly here.
|
||||
|
||||
Animation interface
|
||||
AnimationInterface
|
||||
*******************
|
||||
|
||||
The animation interface uses underlying |ns3| trace sources to construct a
|
||||
timestamped ASCII file that can be read by a standalone animator. The animation
|
||||
interface in |ns3| currently only supports point-to-point links; however, we
|
||||
hope to support other link types such as CSMA and wireless in the near future.
|
||||
A snippet from a sample trace file is shown below.::
|
||||
The class "AnimationInterface" under "src/netanim" uses underlying |ns3| trace sources
|
||||
to construct a timestamped ASCII file in XML format that can be read by a standalone animator
|
||||
named "NetAnim".
|
||||
|
||||
0.0 N 0 4 5.5
|
||||
0.0 N 1 7 5.5
|
||||
0.0 N 2 2.5 2.90192
|
||||
Generating XML trace files for use in NetAnim
|
||||
+++++++++++++++++++++++++++++++++++++++++++++
|
||||
Apply the following statements before the "Simulator::Run ()" statement:::
|
||||
|
||||
...
|
||||
AnimationInterface anim ("animation.xml")
|
||||
|
||||
0.0 L 0 1
|
||||
0.0 L 0 2
|
||||
0.0 L 0 3
|
||||
where "animation.xml" is any arbitrary file name.
|
||||
It is important to ensure that your wscript includes the "netanim" module.
|
||||
Example as in: src/netanim/examples/wscript. Also include the header
|
||||
[#include "ns3/netanim-module.h"] in your test program
|
||||
|
||||
...
|
||||
The examples under "src/netanim/examples" illustrate this. The sample wscript is at
|
||||
"src/netanim/examples/wscript".
|
||||
|
||||
Running the simulation
|
||||
0.668926 P 11 1 0.66936 0.669926 0.67036
|
||||
0.67036 P 1 0 0.670794 0.67136 0.671794
|
||||
0.671794 P 0 6 0.672227 0.672794 0.673227
|
||||
Lets take an example: "src/netanim/examples/star-animation.cc". To run the example:::
|
||||
|
||||
...
|
||||
./waf --run "star-animation"
|
||||
|
||||
The tracefile describes where nodes and links should be placed at the top of the
|
||||
file. Following this placement, the packet events are shown. The format for node
|
||||
placement, link placement and packet events is shown below.
|
||||
This will generate an xml file "star-animation.xml" in the same directory. This XML file
|
||||
contains the information required by the standalone animator "NetAnim" to produce the required
|
||||
animation.
|
||||
|
||||
* Node placement: <time of placement> <N for node> <node id> <x position> <y
|
||||
position>
|
||||
* Link placement: <time of placement> <L for link> <node1 id> <node2 id>
|
||||
* Packet events: <time of first bit tx> <P for packet> <source node>
|
||||
<destination node> <time of last bit tx> <time of first bit rx> <time of last
|
||||
bit rx>
|
||||
|
||||
To get started using the animation interface, several example scripts have been
|
||||
provided to show proper use. These examples can be found in examples/animation.
|
||||
The example scripts use the animation interface as well as topology helpers in
|
||||
order to automatically place the nodes and generate the custom trace. It is
|
||||
important to note that if a topology helper is not used with its provided
|
||||
BoundingBox method, which automatically calculates the nodes' canvas positions,
|
||||
the nodes must be placed manually by aggregating a CanvasLocation to the node.
|
||||
An example use of CanvasLocation can be found in any of the topology helpers.
|
||||
Additionally, a simple example of placing a node is shown below:::
|
||||
|
||||
// assuming a node container m_hub exists and
|
||||
// contains at least one node.
|
||||
// we grab this node and associate a
|
||||
// CanvasLocation to it, in order for the
|
||||
// animation interface to place the node
|
||||
Ptr<Node> hub = m_hub.Get (0);
|
||||
Ptr<CanvasLocation> hubLoc = hub->GetObject<CanvasLocation> ();
|
||||
if (hubLoc == 0)
|
||||
{
|
||||
hubLoc = CreateObject<CanvasLocation> ();
|
||||
hub->AggregateObject (hubLoc);
|
||||
}
|
||||
Vector hubVec (5, 7);
|
||||
hubLoc->SetLocation (hubVec);
|
||||
|
||||
Finally, after the simulation has been set up and the nodes have been placed,
|
||||
the animation interface is used to start the animation, which writes the custom
|
||||
trace file. Below is an example of how to set up and start the animation
|
||||
interface.::
|
||||
|
||||
AnimationInterface anim;
|
||||
// the animation interface can be set up to write
|
||||
// to a socket, if a port > 0 is specified
|
||||
// see doxygen for more information
|
||||
if (port > 0)
|
||||
{
|
||||
anim.SetServerPort (port);
|
||||
}
|
||||
else if (!animFile.empty ())
|
||||
{
|
||||
// if a file name is specified,
|
||||
// the trace is written to the file.
|
||||
// otherwise, it is directed to stdout
|
||||
anim.SetOutputFile (animFile);
|
||||
}
|
||||
anim.StartAnimation ();
|
||||
Parts of the XML
|
||||
++++++++++++++++
|
||||
This is described in detail at http://www.nsnam.org/wiki/index.php/NetAnim#Parts_of_the_XML
|
||||
|
||||
NetAnim
|
||||
*******
|
||||
@@ -118,64 +66,6 @@ which allows a user to skip to any moment in the simulation. The bottom slider
|
||||
changes the granularity of the time step for the animation. Finally, there is a
|
||||
quit button to stop the simulation and quit the animator.
|
||||
|
||||
Prerequisites
|
||||
+++++++++++++
|
||||
|
||||
The animator requires the Qt4 development packages. If you are using a Debian or
|
||||
Ubuntu Linux distribution, you can get the following package: qt4-dev-tools
|
||||
|
||||
This should install everything you need to compile and build NetAnim. If you
|
||||
are using an Red Hat based distribution, look for similar qt4 packages (or
|
||||
libqt4*) and install these using yum. Mac users should install the binaries:
|
||||
`<http://qt.nokia.com/downloads>`_.
|
||||
|
||||
Make sure to download the binary package; look for a link to something without
|
||||
the word "src" or "debug" in the download filename. These will be the library
|
||||
binaries you need.
|
||||
|
||||
Downloading NetAnim
|
||||
+++++++++++++++++++
|
||||
|
||||
The tarball of the source code for NetAnim is available here:
|
||||
`<http://www.nsnam.org/~jpelkey3/NetAnim.tar.gz>`_. Download it, then untar
|
||||
it:::
|
||||
|
||||
tar -xzvf NetAnim.tar.gz
|
||||
|
||||
Building NetAnim
|
||||
++++++++++++++++
|
||||
|
||||
NetAnim uses a Qt4 build tool called qmake; this is similar to the configure
|
||||
script from autotools in that it generates the Makefile, which make then uses to
|
||||
build the project. qmake is different on different versions of Qt, so we'll
|
||||
provide some additional information that is system dependent. You can check your
|
||||
default version of qmake:::
|
||||
|
||||
qmake --version
|
||||
Qmake version: 1.07a (Qt 3.3.8b)
|
||||
Qmake is free software from Trolltech ASA.
|
||||
|
||||
If you see something like the above, where it says Qt 3.x.x, find the
|
||||
qt4 version of qmake on your system and explicitly call it instead.
|
||||
|
||||
In general,::
|
||||
|
||||
cd NetAnim
|
||||
qmake
|
||||
make
|
||||
|
||||
On Mac OSX,::
|
||||
|
||||
cd NetAnim
|
||||
/usr/local/Trolltech/Qt-4.x.y/bin/qmake
|
||||
make
|
||||
|
||||
Note that above, the x.y is the specific version of Qt4 you are running. As of
|
||||
April 1st 2009, the latest version is 4.5.0, although you might have an older
|
||||
version already installed.
|
||||
|
||||
On Ubuntu/Debian with Qt3 AND Qt4,::
|
||||
|
||||
cd NetAnim
|
||||
qmake-qt4
|
||||
make
|
||||
For detailed instructions on installing "NetAnim" and loading the XML trace file
|
||||
(mentioned earlier) using NetAnim please refer:
|
||||
http://www.nsnam.org/wiki/index.php/NetAnim
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
.. include:: replace.txt
|
||||
|
||||
.. _Sockets-APIs:
|
||||
|
||||
Sockets APIs
|
||||
------------
|
||||
|
||||
|
||||
@@ -19,9 +19,6 @@
|
||||
* Author: Blake Hurd <naimorai@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifdef NS3_OPENFLOW
|
||||
|
||||
// An essential include is test.h
|
||||
#include "ns3/test.h"
|
||||
|
||||
@@ -188,6 +185,5 @@ SwitchTestSuite::SwitchTestSuite () : TestSuite ("openflow", UNIT)
|
||||
}
|
||||
|
||||
// Do not forget to allocate an instance of this TestSuite
|
||||
SwitchTestSuite switchTestSuite;
|
||||
static SwitchTestSuite switchTestSuite;
|
||||
|
||||
#endif // NS3_OPENFLOW
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
.. include:: replace.txt
|
||||
|
||||
.. _Propagation:
|
||||
|
||||
Propagation
|
||||
-----------
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def build(bld):
|
||||
# Don't build any examples unless they are enabled.
|
||||
if not bld.env['ENABLE_EXAMPLES']:
|
||||
return;
|
||||
|
||||
# Uncomment these lines to build this C++ example program.
|
||||
#program = bld.create_ns3_program('sample-example', ['core'])
|
||||
#program.source = 'sample-example.cc'
|
||||
|
||||
# Uncomment this line to register the dependencies for this Python
|
||||
# example script.
|
||||
#bld.register_ns3_script('sample-example.py', ['core'])
|
||||
@@ -1,18 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
# A list of C++ examples to run in order to ensure that they remain
|
||||
# buildable and runnable over time. Each tuple in the list contains
|
||||
#
|
||||
# (example_name, do_run, do_valgrind_run).
|
||||
#
|
||||
# See test.py for more information.
|
||||
cpp_examples = []
|
||||
|
||||
# A list of Python examples to run in order to ensure that they remain
|
||||
# runnable over time. Each tuple in the list contains
|
||||
#
|
||||
# (example_name, do_run).
|
||||
#
|
||||
# See test.py for more information.
|
||||
python_examples = []
|
||||
@@ -1,63 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
|
||||
// An essential include is test.h
|
||||
#include "ns3/test.h"
|
||||
|
||||
// Do not put your test classes in namespace ns3. You may find it useful
|
||||
// to use the using directive to access the ns3 namespace directly
|
||||
using namespace ns3;
|
||||
|
||||
// This is an example TestCase.
|
||||
class SampleTestCase1 : public TestCase
|
||||
{
|
||||
public:
|
||||
SampleTestCase1 ();
|
||||
virtual ~SampleTestCase1 ();
|
||||
|
||||
private:
|
||||
virtual void DoRun (void);
|
||||
};
|
||||
|
||||
// Add some help text to this case to describe what it is intended to test
|
||||
SampleTestCase1::SampleTestCase1 ()
|
||||
: TestCase ("Sample test case (does nothing)")
|
||||
{
|
||||
}
|
||||
|
||||
// This destructor does nothing but we include it as a reminder that
|
||||
// the test case should clean up after itself
|
||||
SampleTestCase1::~SampleTestCase1 ()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// This method is the pure virtual method from class TestCase that every
|
||||
// TestCase must implement
|
||||
//
|
||||
void
|
||||
SampleTestCase1::DoRun (void)
|
||||
{
|
||||
// A wide variety of test macros are available in src/core/test.h
|
||||
NS_TEST_ASSERT_MSG_EQ (true, true, "true doesn't equal true for some reason");
|
||||
// Use this one for floating point comparisons
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (0.01, 0.01, 0.001, "Numbers are not equal within tolerance");
|
||||
}
|
||||
|
||||
// The TestSuite class names the TestSuite, identifies what type of TestSuite,
|
||||
// and enables the TestCases to be run. Typically, only the constructor for
|
||||
// this class must be defined
|
||||
//
|
||||
class SampleTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
SampleTestSuite ();
|
||||
};
|
||||
|
||||
SampleTestSuite::SampleTestSuite ()
|
||||
: TestSuite ("sample", UNIT)
|
||||
{
|
||||
AddTestCase (new SampleTestCase1);
|
||||
}
|
||||
|
||||
// Do not forget to allocate an instance of this TestSuite
|
||||
static SampleTestSuite sampleTestSuite;
|
||||
@@ -1,51 +0,0 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def build(bld):
|
||||
# Create the module with the appropriate name and the list of
|
||||
# modules it depends on.
|
||||
module = bld.create_ns3_module('template', ['core'])
|
||||
|
||||
# Set the C++ source files for this module.
|
||||
module.source = [
|
||||
# Uncomment these lines to compile these model source files.
|
||||
#'model/sample-model-1.cc',
|
||||
#'model/sample-model-2.cc',
|
||||
|
||||
# Uncomment these lines to compile these helper source files.
|
||||
#'helper/sample-helper-1.cc',
|
||||
#'helper/sample-helper-2.cc',
|
||||
]
|
||||
|
||||
# Create the module's test library.
|
||||
module_test = bld.create_ns3_module_test_library('template')
|
||||
|
||||
# Set the C++ source files for the module's test library.
|
||||
module_test.source = [
|
||||
# Uncomment these lines to compile these test suites.
|
||||
#'test/sample-test-suite-1.cc',
|
||||
#'test/sample-test-suite-2.cc',
|
||||
]
|
||||
|
||||
# Make headers be installed for this module.
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'template'
|
||||
|
||||
# Set the C++ header files for this module.
|
||||
headers.source = [
|
||||
# Uncomment these lines to install these model header files.
|
||||
#'model/sample-model-1.h',
|
||||
#'model/sample-model-2.h',
|
||||
|
||||
# Uncomment these lines to install these helper header files.
|
||||
#'helper/sample-helper-1.h',
|
||||
#'helper/sample-helper-2.h',
|
||||
]
|
||||
|
||||
# Uncomment these lines if this module needs a library such as the
|
||||
# real-time (RT) library to be linked in at build time.
|
||||
#module .uselib = 'RT'
|
||||
#module_test.uselib = 'RT'
|
||||
|
||||
# Look for examples if they are enabled.
|
||||
if (bld.env['ENABLE_EXAMPLES']):
|
||||
bld.add_subdirs('examples')
|
||||
@@ -196,7 +196,7 @@ class Node(PyVizObject):
|
||||
addresses = [
|
||||
'%s/%s' % (ipv6.GetAddress(ipv6_idx, i).GetAddress(),
|
||||
ipv6.GetAddress(ipv6_idx, i).GetPrefix())
|
||||
for i in range(ipv6.GetNAddresses(ipv4_idx))]
|
||||
for i in range(ipv6.GetNAddresses(ipv6_idx))]
|
||||
lines.append(' <b>IPv6 Addresses:</b> %s' % '; '.join(addresses))
|
||||
|
||||
lines.append(' <b>MAC Address:</b> %s' % (dev.GetAddress(),))
|
||||
|
||||
@@ -158,8 +158,8 @@ to get the defaults. Note the distinction above in creating a helper object vs.
|
||||
an actual simulation object. In |ns3|, helper objects (used at the helper API
|
||||
only) are created on the stack (they could also be created with operator new and
|
||||
later deleted). However, the actual |ns3| objects typically inherit from
|
||||
``class ns3::Object`` and are assigned to a smart pointer. See the chapter on
|
||||
:ref:`Object model` for a discussion of the |ns3| object model, if you are not
|
||||
``class ns3::Object`` and are assigned to a smart pointer. See the chapter in
|
||||
the |ns3| manual for a discussion of the |ns3| object model, if you are not
|
||||
familiar with it.
|
||||
|
||||
*Todo: Add notes about how to configure attributes with this helper API*
|
||||
@@ -243,7 +243,7 @@ on a set of nodes in a NodeContainer "c":::
|
||||
This creates the WifiNetDevice which includes also a WifiRemoteStationManager, a
|
||||
WifiMac, and a WifiPhy (connected to the matching WifiChannel).
|
||||
|
||||
There are many |ns3| :ref:`Attributes` that can be set on the above helpers to
|
||||
There are many |ns3| attributes that can be set on the above helpers to
|
||||
deviate from the default behavior; the example scripts show how to do some of
|
||||
this reconfiguration.
|
||||
|
||||
@@ -268,7 +268,7 @@ The WifiChannel and WifiPhy models
|
||||
The WifiChannel subclass can be used to connect together a set of
|
||||
``ns3::WifiNetDevice`` network interfaces. The class ``ns3::WifiPhy`` is the
|
||||
object within the WifiNetDevice that receives bits from the channel.
|
||||
For the channel propagation modeling, the propagation module is used; see section :ref:`propagation` for details.
|
||||
For the channel propagation modeling, the propagation module is used; see section :ref:`Propagation` for details.
|
||||
|
||||
|
||||
This section summarizes the description of the BER calculations found in the
|
||||
|
||||
@@ -152,7 +152,7 @@ configured from a helper level:::
|
||||
Wimax Attributes
|
||||
****************
|
||||
|
||||
The WimaxNetDevice makes heavy use of the |ns3| :ref:`Attributes` subsystem for
|
||||
The WimaxNetDevice makes heavy use of the |ns3| attributes subsystem for
|
||||
configuration and default value management. Presently, approximately 60 values
|
||||
are stored in this system.
|
||||
|
||||
@@ -213,6 +213,8 @@ models.
|
||||
.. _wimax-architecture:
|
||||
|
||||
.. figure:: figures/WimaxArchitecture.*
|
||||
|
||||
WiMAX architecture
|
||||
|
||||
Convergence Sublayer
|
||||
++++++++++++++++++++
|
||||
|
||||
10
src/wscript
10
src/wscript
@@ -24,7 +24,7 @@ except NameError:
|
||||
|
||||
all_modules = []
|
||||
for dirname in os.listdir('src'):
|
||||
if dirname.startswith('.') or dir == 'CVS':
|
||||
if dirname.startswith('.') or dirname == 'CVS':
|
||||
continue
|
||||
path = os.path.join('src', dirname)
|
||||
if not os.path.isdir(path):
|
||||
@@ -217,7 +217,7 @@ def ns3_python_bindings(bld):
|
||||
source=("bindings/%s.py" % (module_py_name,)),
|
||||
target=('%s/%s.py' % (module_target_dir, module_py_name)))
|
||||
extension_name = '_%s' % (module_py_name,)
|
||||
bld.install_files('${PYTHONDIR}/ns', ["bindings/%s.py" % (module_py_name,)])
|
||||
bld.install_files('${PYTHONARCHDIR}/ns', ["bindings/%s.py" % (module_py_name,)])
|
||||
else:
|
||||
extension_name = module_py_name
|
||||
|
||||
@@ -275,7 +275,7 @@ def ns3_python_bindings(bld):
|
||||
pass
|
||||
pymod.env['DEFINES'] = defines
|
||||
pymod.includes = '# bindings'
|
||||
pymod.install_path = '${PYTHONDIR}/ns'
|
||||
pymod.install_path = '${PYTHONARCHDIR}/ns'
|
||||
return pymod
|
||||
|
||||
|
||||
@@ -379,7 +379,7 @@ class ns3pcfile_task(Task.Task):
|
||||
self._defines(dep) + self._includes(dep)
|
||||
if dep.startswith('ns3-'):
|
||||
requires.append("lib"+dep)
|
||||
print >> outfile, """
|
||||
print >> outfile, """\
|
||||
prefix=%s
|
||||
libdir=%s
|
||||
includedir=%s
|
||||
@@ -389,7 +389,7 @@ Description: ns-3 module %s
|
||||
Version: devel
|
||||
Libs: %s
|
||||
Cflags: %s
|
||||
Requires: %s
|
||||
Requires: %s\
|
||||
""" % (prefix, libdir, includedir,
|
||||
name, name, ' '.join(libs), ' '.join(cflags), ' '.join(requires))
|
||||
outfile.close()
|
||||
|
||||
2
test.py
2
test.py
@@ -500,7 +500,7 @@ def sigint_hook(signal, frame):
|
||||
# and use that result.
|
||||
#
|
||||
def read_waf_config():
|
||||
for line in open(".lock-wafbuild", "rt"):
|
||||
for line in open(".lock-waf_" + sys.platform + "_build", "rt"):
|
||||
if line.startswith("out_dir ="):
|
||||
key, val = line.split('=')
|
||||
out_dir = eval(val.strip())
|
||||
|
||||
@@ -1,502 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
# Thomas Nagy, 2007-2010 (ita)
|
||||
# Gustavo Carneiro (gjc), 2007
|
||||
|
||||
#
|
||||
# NS-3 Note: this python tool was added only for including a bug fix:
|
||||
# http://code.google.com/p/waf/issues/detail?id=1045
|
||||
# Once waf 1.6.8 comes out and ns-3 upgrades to it, this copy of the python tool can be removed
|
||||
#
|
||||
|
||||
"""
|
||||
Support for Python, detect the headers and libraries and provide
|
||||
*use* variables to link C/C++ programs against them::
|
||||
|
||||
def options(opt):
|
||||
opt.load('compiler_c python')
|
||||
def configure(conf):
|
||||
conf.load('compiler_c python')
|
||||
conf.check_python_version((2,4,2))
|
||||
conf.check_python_headers()
|
||||
def build(bld):
|
||||
bld.program(features='pyembed', source='a.c', target='myprog')
|
||||
bld.shlib(features='pyext', source='b.c', target='mylib')
|
||||
"""
|
||||
|
||||
import os, sys
|
||||
from waflib import Utils, Options, Errors
|
||||
from waflib.Logs import debug, warn, info, error
|
||||
from waflib.TaskGen import extension, before_method, after_method, feature
|
||||
from waflib.Configure import conf
|
||||
|
||||
FRAG = '''
|
||||
#include <Python.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void Py_Initialize(void);
|
||||
void Py_Finalize(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
int main()
|
||||
{
|
||||
Py_Initialize();
|
||||
Py_Finalize();
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
"""
|
||||
Piece of C/C++ code used in :py:func:`waflib.Tools.python.check_python_headers`
|
||||
"""
|
||||
|
||||
INST = '''
|
||||
import sys, py_compile
|
||||
py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3])
|
||||
'''
|
||||
"""
|
||||
Piece of Python code used in :py:func:`waflib.Tools.python.install_pyfile` for installing python files
|
||||
"""
|
||||
|
||||
@extension('.py')
|
||||
def process_py(self, node):
|
||||
"""
|
||||
Add a callback using :py:func:`waflib.Tools.python.install_pyfile` to install a python file
|
||||
"""
|
||||
try:
|
||||
if not self.bld.is_install:
|
||||
return
|
||||
except:
|
||||
return
|
||||
|
||||
try:
|
||||
if not self.install_path:
|
||||
return
|
||||
except AttributeError:
|
||||
self.install_path = '${PYTHONDIR}'
|
||||
|
||||
# i wonder now why we wanted to do this after the build is over
|
||||
# issue #901: people want to preserve the structure of installed files
|
||||
def inst_py(ctx):
|
||||
install_from = getattr(self, 'install_from', None)
|
||||
if install_from:
|
||||
install_from = self.path.find_dir(install_from)
|
||||
install_pyfile(self, node, install_from)
|
||||
self.bld.add_post_fun(inst_py)
|
||||
|
||||
def install_pyfile(self, node, install_from=None):
|
||||
"""
|
||||
Execute the installation of a python file
|
||||
|
||||
:param node: python file
|
||||
:type node: :py:class:`waflib.Node.Node`
|
||||
"""
|
||||
|
||||
from_node = install_from or node.parent
|
||||
tsk = self.bld.install_as(self.install_path + '/' + node.path_from(from_node), node, postpone=False)
|
||||
path = tsk.get_install_path()
|
||||
|
||||
if self.bld.is_install < 0:
|
||||
info("+ removing byte compiled python files")
|
||||
for x in 'co':
|
||||
try:
|
||||
os.remove(path + x)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
if self.bld.is_install > 0:
|
||||
try:
|
||||
st1 = os.stat(path)
|
||||
except:
|
||||
error('The python file is missing, this should not happen')
|
||||
|
||||
for x in ['c', 'o']:
|
||||
do_inst = self.env['PY' + x.upper()]
|
||||
try:
|
||||
st2 = os.stat(path + x)
|
||||
except OSError:
|
||||
pass
|
||||
else:
|
||||
if st1.st_mtime <= st2.st_mtime:
|
||||
do_inst = False
|
||||
|
||||
if do_inst:
|
||||
lst = (x == 'o') and [self.env['PYFLAGS_OPT']] or []
|
||||
(a, b, c) = (path, path + x, tsk.get_install_path(destdir=False) + x)
|
||||
argv = self.env['PYTHON'] + lst + ['-c', INST, a, b, c]
|
||||
info('+ byte compiling %r' % (path + x))
|
||||
ret = Utils.subprocess.Popen(argv).wait()
|
||||
if ret:
|
||||
raise Errors.WafError('py%s compilation failed %r' % (x, path))
|
||||
|
||||
@feature('py')
|
||||
def feature_py(self):
|
||||
"""
|
||||
Dummy feature which does nothing
|
||||
"""
|
||||
pass
|
||||
|
||||
@feature('pyext')
|
||||
@before_method('propagate_uselib_vars', 'apply_link')
|
||||
@after_method('apply_bundle')
|
||||
def init_pyext(self):
|
||||
"""
|
||||
Change the values of *cshlib_PATTERN* and *cxxshlib_PATTERN* to remove the
|
||||
*lib* prefix from library names.
|
||||
"""
|
||||
try:
|
||||
if not self.install_path:
|
||||
return
|
||||
except AttributeError:
|
||||
self.install_path = '${PYTHONARCHDIR}'
|
||||
self.uselib = self.to_list(getattr(self, 'uselib', []))
|
||||
if not 'PYEXT' in self.uselib:
|
||||
self.uselib.append('PYEXT')
|
||||
# override shlib_PATTERN set by the osx module
|
||||
self.env['cshlib_PATTERN'] = self.env['cxxshlib_PATTERN'] = self.env['macbundle_PATTERN'] = self.env['pyext_PATTERN']
|
||||
|
||||
@feature('pyext')
|
||||
@before_method('apply_link', 'apply_bundle')
|
||||
def set_bundle(self):
|
||||
if sys.platform.startswith('darwin'):
|
||||
self.mac_bundle = True
|
||||
|
||||
@before_method('propagate_uselib_vars')
|
||||
@feature('pyembed')
|
||||
def init_pyembed(self):
|
||||
"""
|
||||
Add the PYEMBED variable.
|
||||
"""
|
||||
self.uselib = self.to_list(getattr(self, 'uselib', []))
|
||||
if not 'PYEMBED' in self.uselib:
|
||||
self.uselib.append('PYEMBED')
|
||||
|
||||
@conf
|
||||
def get_python_variables(conf, variables, imports=['import sys']):
|
||||
"""
|
||||
Execute a python interpreter to dump configuration variables
|
||||
|
||||
:param variables: variables to print
|
||||
:type variables: list of string
|
||||
:param imports: one import by element
|
||||
:type imports: list of string
|
||||
:return: the variable values
|
||||
:rtype: list of string
|
||||
"""
|
||||
program = list(imports)
|
||||
program.append('')
|
||||
for v in variables:
|
||||
program.append("print(repr(%s))" % v)
|
||||
os_env = dict(os.environ)
|
||||
try:
|
||||
del os_env['MACOSX_DEPLOYMENT_TARGET'] # see comments in the OSX tool
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
out = conf.cmd_and_log(conf.env.PYTHON + ['-c', '\n'.join(program)], env=os_env)
|
||||
except Errors.WafError:
|
||||
conf.fatal('The distutils module is unusable: install "python-devel"?')
|
||||
return_values = []
|
||||
for s in out.split('\n'):
|
||||
s = s.strip()
|
||||
if not s:
|
||||
continue
|
||||
if s == 'None':
|
||||
return_values.append(None)
|
||||
elif s[0] == "'" and s[-1] == "'":
|
||||
return_values.append(s[1:-1])
|
||||
elif s[0].isdigit():
|
||||
return_values.append(int(s))
|
||||
else: break
|
||||
return return_values
|
||||
|
||||
@conf
|
||||
def check_python_headers(conf):
|
||||
"""
|
||||
Check for headers and libraries necessary to extend or embed python by using the module *distutils*.
|
||||
On success the environment variables xxx_PYEXT and xxx_PYEMBED are added:
|
||||
|
||||
* PYEXT: for compiling python extensions
|
||||
* PYEMBED: for embedding a python interpreter
|
||||
"""
|
||||
|
||||
# FIXME rewrite
|
||||
|
||||
if not conf.env['CC_NAME'] and not conf.env['CXX_NAME']:
|
||||
conf.fatal('load a compiler first (gcc, g++, ..)')
|
||||
|
||||
if not conf.env['PYTHON_VERSION']:
|
||||
conf.check_python_version()
|
||||
|
||||
env = conf.env
|
||||
pybin = conf.env.PYTHON
|
||||
if not pybin:
|
||||
conf.fatal('could not find the python executable')
|
||||
|
||||
v = 'prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS'.split()
|
||||
try:
|
||||
lst = conf.get_python_variables(["get_config_var('%s') or ''" % x for x in v],
|
||||
['from distutils.sysconfig import get_config_var'])
|
||||
except RuntimeError:
|
||||
conf.fatal("Python development headers not found (-v for details).")
|
||||
|
||||
vals = ['%s = %r' % (x, y) for (x, y) in zip(v, lst)]
|
||||
conf.to_log("Configuration returned from %r:\n%r\n" % (pybin, '\n'.join(vals)))
|
||||
|
||||
dct = dict(zip(v, lst))
|
||||
x = 'MACOSX_DEPLOYMENT_TARGET'
|
||||
if dct[x]:
|
||||
conf.env[x] = conf.environ[x] = dct[x]
|
||||
|
||||
env['pyext_PATTERN'] = '%s' + dct['SO'] # not a mistake
|
||||
|
||||
# Check for python libraries for embedding
|
||||
|
||||
all_flags = dct['LDFLAGS'] + ' ' + dct['CFLAGS']
|
||||
conf.parse_flags(all_flags, 'PYEMBED')
|
||||
|
||||
all_flags = dct['LDFLAGS'] + ' ' + dct['LDSHARED'] + ' ' + dct['CFLAGS']
|
||||
conf.parse_flags(all_flags, 'PYEXT')
|
||||
|
||||
result = None
|
||||
#name = 'python' + env['PYTHON_VERSION']
|
||||
|
||||
# TODO simplify this
|
||||
for name in ('python' + env['PYTHON_VERSION'], 'python' + env['PYTHON_VERSION'].replace('.', '')):
|
||||
|
||||
# LIBPATH_PYEMBED is already set; see if it works.
|
||||
if not result and env['LIBPATH_PYEMBED']:
|
||||
path = env['LIBPATH_PYEMBED']
|
||||
conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n" % path)
|
||||
result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in LIBPATH_PYEMBED' % name)
|
||||
|
||||
if not result and dct['LIBDIR']:
|
||||
path = [dct['LIBDIR']]
|
||||
conf.to_log("\n\n# try again with -L$python_LIBDIR: %r\n" % path)
|
||||
result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in LIBDIR' % name)
|
||||
|
||||
if not result and dct['LIBPL']:
|
||||
path = [dct['LIBPL']]
|
||||
conf.to_log("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n")
|
||||
result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in python_LIBPL' % name)
|
||||
|
||||
if not result:
|
||||
path = [os.path.join(dct['prefix'], "libs")]
|
||||
conf.to_log("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n")
|
||||
result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in $prefix/libs' % name)
|
||||
|
||||
if result:
|
||||
break # do not forget to set LIBPATH_PYEMBED
|
||||
|
||||
if result:
|
||||
env['LIBPATH_PYEMBED'] = path
|
||||
env.append_value('LIB_PYEMBED', [name])
|
||||
else:
|
||||
conf.to_log("\n\n### LIB NOT FOUND\n")
|
||||
|
||||
# under certain conditions, python extensions must link to
|
||||
# python libraries, not just python embedding programs.
|
||||
if (Utils.is_win32 or sys.platform.startswith('os2')
|
||||
or dct['Py_ENABLE_SHARED']):
|
||||
env['LIBPATH_PYEXT'] = env['LIBPATH_PYEMBED']
|
||||
env['LIB_PYEXT'] = env['LIB_PYEMBED']
|
||||
|
||||
# We check that pythonX.Y-config exists, and if it exists we
|
||||
# use it to get only the includes, else fall back to distutils.
|
||||
num = '.'.join(env['PYTHON_VERSION'].split('.')[:2])
|
||||
conf.find_program(['python%s-config' % num, 'python-config-%s' % num, 'python%sm-config' % num], var='PYTHON_CONFIG', mandatory=False)
|
||||
|
||||
includes = []
|
||||
if conf.env.PYTHON_CONFIG:
|
||||
for incstr in conf.cmd_and_log([ conf.env.PYTHON_CONFIG, '--includes']).strip().split():
|
||||
# strip the -I or /I
|
||||
if (incstr.startswith('-I') or incstr.startswith('/I')):
|
||||
incstr = incstr[2:]
|
||||
# append include path, unless already given
|
||||
if incstr not in includes:
|
||||
includes.append(incstr)
|
||||
conf.to_log("Include path for Python extensions "
|
||||
"(found via python-config --includes): %r\n" % (includes,))
|
||||
env['INCLUDES_PYEXT'] = includes
|
||||
env['INCLUDES_PYEMBED'] = includes
|
||||
else:
|
||||
conf.to_log("Include path for Python extensions "
|
||||
"(found via distutils module): %r\n" % (dct['INCLUDEPY'],))
|
||||
env['INCLUDES_PYEXT'] = [dct['INCLUDEPY']]
|
||||
env['INCLUDES_PYEMBED'] = [dct['INCLUDEPY']]
|
||||
|
||||
# Code using the Python API needs to be compiled with -fno-strict-aliasing
|
||||
if env['CC_NAME'] == 'gcc':
|
||||
env.append_value('CFLAGS_PYEMBED', ['-fno-strict-aliasing'])
|
||||
env.append_value('CFLAGS_PYEXT', ['-fno-strict-aliasing'])
|
||||
if env['CXX_NAME'] == 'gcc':
|
||||
env.append_value('CXXFLAGS_PYEMBED', ['-fno-strict-aliasing'])
|
||||
env.append_value('CXXFLAGS_PYEXT', ['-fno-strict-aliasing'])
|
||||
|
||||
if env.CC_NAME == "msvc":
|
||||
from distutils.msvccompiler import MSVCCompiler
|
||||
dist_compiler = MSVCCompiler()
|
||||
dist_compiler.initialize()
|
||||
env.append_value('CFLAGS_PYEXT', dist_compiler.compile_options)
|
||||
env.append_value('CXXFLAGS_PYEXT', dist_compiler.compile_options)
|
||||
env.append_value('LINKFLAGS_PYEXT', dist_compiler.ldflags_shared)
|
||||
|
||||
# See if it compiles
|
||||
try:
|
||||
conf.check(header_name='Python.h', define_name='HAVE_PYTHON_H',
|
||||
uselib='PYEMBED', fragment=FRAG,
|
||||
errmsg='Could not find the python development headers')
|
||||
except conf.errors.ConfigurationError:
|
||||
# python3.2, oh yeah
|
||||
conf.check_cfg(path=conf.env.PYTHON_CONFIG, package='', uselib_store='PYEMBED', args=['--cflags', '--libs'])
|
||||
conf.check(header_name='Python.h', define_name='HAVE_PYTHON_H', msg='Getting the python flags from python-config',
|
||||
uselib='PYEMBED', fragment=FRAG,
|
||||
errmsg='Could not find the python development headers elsewhere')
|
||||
|
||||
@conf
|
||||
def check_python_version(conf, minver=None):
|
||||
"""
|
||||
Check if the python interpreter is found matching a given minimum version.
|
||||
minver should be a tuple, eg. to check for python >= 2.4.2 pass (2,4,2) as minver.
|
||||
|
||||
If successful, PYTHON_VERSION is defined as 'MAJOR.MINOR'
|
||||
(eg. '2.4') of the actual python version found, and PYTHONDIR is
|
||||
defined, pointing to the site-packages directory appropriate for
|
||||
this python version, where modules/packages/extensions should be
|
||||
installed.
|
||||
|
||||
:param minver: minimum version
|
||||
:type minver: tuple of int
|
||||
"""
|
||||
assert minver is None or isinstance(minver, tuple)
|
||||
pybin = conf.env['PYTHON']
|
||||
if not pybin:
|
||||
conf.fatal('could not find the python executable')
|
||||
|
||||
# Get python version string
|
||||
cmd = pybin + ['-c', 'import sys\nfor x in sys.version_info: print(str(x))']
|
||||
debug('python: Running python command %r' % cmd)
|
||||
lines = conf.cmd_and_log(cmd).split()
|
||||
assert len(lines) == 5, "found %i lines, expected 5: %r" % (len(lines), lines)
|
||||
pyver_tuple = (int(lines[0]), int(lines[1]), int(lines[2]), lines[3], int(lines[4]))
|
||||
|
||||
# compare python version with the minimum required
|
||||
result = (minver is None) or (pyver_tuple >= minver)
|
||||
|
||||
if result:
|
||||
# define useful environment variables
|
||||
pyver = '.'.join([str(x) for x in pyver_tuple[:2]])
|
||||
conf.env['PYTHON_VERSION'] = pyver
|
||||
|
||||
if 'PYTHONDIR' in conf.environ:
|
||||
pydir = conf.environ['PYTHONDIR']
|
||||
else:
|
||||
if Utils.is_win32:
|
||||
(python_LIBDEST, pydir) = \
|
||||
conf.get_python_variables(
|
||||
["get_config_var('LIBDEST') or ''",
|
||||
"get_python_lib(standard_lib=0, prefix=%r) or ''" % conf.env['PREFIX']],
|
||||
['from distutils.sysconfig import get_config_var, get_python_lib'])
|
||||
else:
|
||||
python_LIBDEST = None
|
||||
(pydir,) = \
|
||||
conf.get_python_variables(
|
||||
["get_python_lib(standard_lib=0, prefix=%r) or ''" % conf.env['PREFIX']],
|
||||
['from distutils.sysconfig import get_python_lib'])
|
||||
if python_LIBDEST is None:
|
||||
if conf.env['LIBDIR']:
|
||||
python_LIBDEST = os.path.join(conf.env['LIBDIR'], "python" + pyver)
|
||||
else:
|
||||
python_LIBDEST = os.path.join(conf.env['PREFIX'], "lib", "python" + pyver)
|
||||
|
||||
|
||||
if 'PYTHONARCHDIR' in conf.environ:
|
||||
pyarchdir = conf.environ['PYTHONARCHDIR']
|
||||
else:
|
||||
(pyarchdir, ) = conf.get_python_variables(
|
||||
["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r) or ''" % conf.env['PREFIX']],
|
||||
['from distutils.sysconfig import get_python_lib'])
|
||||
if not pyarchdir:
|
||||
pyarchdir = pydir
|
||||
|
||||
if hasattr(conf, 'define'): # conf.define is added by the C tool, so may not exist
|
||||
conf.define('PYTHONDIR', pydir)
|
||||
conf.define('PYTHONARCHDIR', pyarchdir)
|
||||
|
||||
conf.env['PYTHONDIR'] = pydir
|
||||
conf.env['PYTHONARCHDIR'] = pyarchdir
|
||||
|
||||
# Feedback
|
||||
pyver_full = '.'.join(map(str, pyver_tuple[:3]))
|
||||
if minver is None:
|
||||
conf.msg('Checking for python version', pyver_full)
|
||||
else:
|
||||
minver_str = '.'.join(map(str, minver))
|
||||
conf.msg('Checking for python version', pyver_tuple, ">= %s" % (minver_str,) and 'GREEN' or 'YELLOW')
|
||||
|
||||
if not result:
|
||||
conf.fatal('The python version is too old, expecting %r' % (minver,))
|
||||
|
||||
PYTHON_MODULE_TEMPLATE = '''
|
||||
import %s
|
||||
print(1)
|
||||
'''
|
||||
|
||||
@conf
|
||||
def check_python_module(conf, module_name):
|
||||
"""
|
||||
Check if the selected python interpreter can import the given python module::
|
||||
|
||||
def configure(conf):
|
||||
conf.check_python_module('pygccxml')
|
||||
|
||||
:param module_name: module
|
||||
:type module_name: string
|
||||
"""
|
||||
conf.start_msg('Python module %s' % module_name)
|
||||
try:
|
||||
conf.cmd_and_log(conf.env['PYTHON'] + ['-c', PYTHON_MODULE_TEMPLATE % module_name])
|
||||
except:
|
||||
conf.end_msg(False)
|
||||
conf.fatal('Could not find the python module %r' % module_name)
|
||||
conf.end_msg(True)
|
||||
|
||||
def configure(conf):
|
||||
"""
|
||||
Detect the python interpreter
|
||||
"""
|
||||
try:
|
||||
conf.find_program('python', var='PYTHON')
|
||||
except conf.errors.ConfigurationError:
|
||||
warn("could not find a python executable, setting to sys.executable '%s'" % sys.executable)
|
||||
conf.env.PYTHON = sys.executable
|
||||
|
||||
if conf.env.PYTHON != sys.executable:
|
||||
warn("python executable '%s' different from sys.executable '%s'" % (conf.env.PYTHON, sys.executable))
|
||||
conf.env.PYTHON = conf.cmd_to_list(conf.env.PYTHON)
|
||||
|
||||
v = conf.env
|
||||
v['PYCMD'] = '"import sys, py_compile;py_compile.compile(sys.argv[1], sys.argv[2])"'
|
||||
v['PYFLAGS'] = ''
|
||||
v['PYFLAGS_OPT'] = '-O'
|
||||
|
||||
v['PYC'] = getattr(Options.options, 'pyc', 1)
|
||||
v['PYO'] = getattr(Options.options, 'pyo', 1)
|
||||
|
||||
def options(opt):
|
||||
"""
|
||||
Add the options ``--nopyc`` and ``--nopyo``
|
||||
"""
|
||||
opt.add_option('--nopyc',
|
||||
action='store_false',
|
||||
default=1,
|
||||
help = 'Do not install bytecode compiled .pyc files (configuration) [Default:install]',
|
||||
dest = 'pyc')
|
||||
opt.add_option('--nopyo',
|
||||
action='store_false',
|
||||
default=1,
|
||||
help='Do not install optimised compiled .pyo files (configuration) [Default:install]',
|
||||
dest='pyo')
|
||||
|
||||
Reference in New Issue
Block a user