This commit is contained in:
Nicola Baldo
2012-01-05 11:46:58 +01:00
46 changed files with 500 additions and 1034 deletions

View File

@@ -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]$

View File

@@ -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
View File

@@ -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)

View File

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

View File

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

View File

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

View File

@@ -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 \

View File

@@ -56,7 +56,6 @@
* - spectrum
* - stats
* - tap-bridge
* - template
* - test
* - tools
* - topology-read
@@ -66,7 +65,6 @@
* - wifi
* - wimax
*
*
*/
/**
* \namespace ns3

View File

@@ -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)

View File

@@ -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
+++++++++++++++++++++++++++++++++++++++++++

View File

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

View File

@@ -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.

View File

@@ -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
*******************************

View File

@@ -1,5 +1,7 @@
.. include:: replace.txt
.. _Object-names:
Object names
------------

View File

@@ -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
***********************

View File

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

View File

@@ -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 \

View File

@@ -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.

View File

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

View File

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

View File

@@ -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.

View File

@@ -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::

View File

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

View File

@@ -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
*/

View File

@@ -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
#

View File

@@ -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
*****************

View File

@@ -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:::

View File

@@ -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
{

View File

@@ -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
{

View File

@@ -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
{

View File

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

View File

@@ -1,5 +1,7 @@
.. include:: replace.txt
.. _Sockets-APIs:
Sockets APIs
------------

View File

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

View File

@@ -1,5 +1,7 @@
.. include:: replace.txt
.. _Propagation:
Propagation
-----------

View File

@@ -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'])

View File

@@ -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 = []

View File

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

View File

@@ -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')

View File

@@ -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(),))

View File

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

View File

@@ -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
++++++++++++++++++++

View File

@@ -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()

View File

@@ -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())

BIN
waf vendored

Binary file not shown.

View File

@@ -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')

View File

@@ -801,6 +801,7 @@ def build(bld):
for gen in bld.all_task_gen:
if type(gen).__name__ in ['ns3header_taskgen', 'ns3moduleheader_taskgen']:
gen.post()
bld.env['PRINT_BUILT_MODULES_AT_END'] = False
if Options.options.doxygen_no_build:
_doxygen(bld)