merge with trunk

Unknown 2007-04-18 19:17:13 +02:00
commit 207976b5fe
44 changed files with 1375 additions and 544 deletions

1
.hgtags Normal file
View File

@ -0,0 +1 @@
56928998e05c9c11f5f3aefe79be8d2843e0db88 release ns-3.0.1

View File

@ -1 +1,5 @@
Bilbo The Hobbit
Raj Bhattarcharjea (raj.b@gatech.edu)
Craig Dowell (craigdo@ee.washington.edu)
Tom Henderson (tomhend@u.washington.edu)
Mathieu Lacage (mathieu.lacage@sophia.inria.fr)
George F. Riley (riley@ece.gatech.edu)

35
INSTALL Normal file
View File

@ -0,0 +1,35 @@
ns-3.0.1 snapshot release, March 2007
1. Tested platforms:
- Windows XP 32-bit Cygwin
- Linux Fedora Core 5 x86
- OS X 10.4.7 or later with XCode 2.4 or later
2. Prerequisites:
- The SCons build system (http://www.scons.org) version 0.96.1 or later
- gcc (version 3.4 or later)
3. Installing into your current directory:
tar xvfz ns-3.0.1.tar.gz
cd ns-3.0.1
scons
cd build-dir/dbg-shared/bin/
./simple-p2p
The above steps will run a simple program whose source is found in
ns-3.0.1/examples/simple-p2p.cc
Some minimal trace output is found in simple-p2p.tr.
Note: OS X users may need to set the following env. variable from
the bin/ directory above:
setenv DYLD_LIBRARY_PATH `pwd`/../lib
4. For more information, read
ns-3.0.1-documentation.pdf

339
LICENSE Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

2
README
View File

@ -1,3 +1,5 @@
ns-3 uses the Mercurial software revision control system
Mercurial cheat sheet
clone this repository:

11
RELEASE_NOTES Normal file
View File

@ -0,0 +1,11 @@
ns-3 RELEASE NOTES
This file contains ns-3 release notes (most recent releases first).
Release 0.1 (2007/03/31)
========================
- First public release; not yet pre-alpha.
- Simple UDP-based simulation script (examples/simple-p2p.cc)

View File

@ -145,7 +145,6 @@ common.add_sources([
'packet.cc',
'tags.cc',
'pcap-writer.cc',
'trace-writer.cc',
'variable-tracer-test.cc',
'trace-context.cc',
'trace-resolver.cc',
@ -166,7 +165,6 @@ common.add_inst_headers([
'uv-trace-source.h',
'sv-trace-source.h',
'fv-trace-source.h',
'trace-writer.h',
'pcap-writer.h',
'callback-trace-source.h',
'trace-context.h',

1
VERSION Normal file
View File

@ -0,0 +1 @@
3.0.1

View File

@ -471,7 +471,10 @@ RECURSIVE = YES
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
EXCLUDE =
EXCLUDE = \
src/simulator/high-precision.h \
src/simulator/high-precision-128.h \
src/simulator/high-precision-double.h
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
# directories that are symbolic links (a Unix filesystem feature) are excluded

View File

@ -10,12 +10,18 @@
* - common: located in src/common and contains facilities specific
* to network simulations but shared by pretty much every model
* of a network component.
* - node: located in src/node. Contains an ipv4/udp model.
* - devices: located in src/devices. Contains a set of MAC-level models
*
* The "core" module contains:
* - a Functor class: ns3::Callback
* - an os-independent interface to get write-only access to a file: ns3::SystemFile
* - an os-independent interface to get access to the elapsed wall clock time: ns3::SystemWallClockMs
* - a class to register regression tests with the test manager: ns3::Test and ns3::TestManager
* - debugging facilities: \ref debugging, \ref assert, \ref error
* - \ref randomvariable
* - a class to handle automatic deletion of multiple sets of objects of different types:
* ns3::ObjectContainer
*
* The "simulator" module contains:
* - a time management class to hold a time and convert between various time units: ns3::Time
@ -26,8 +32,22 @@
* The "common" module contains:
* - a packet class to create and manipulate simulation packets: ns3::Packet, ns3::Header,
* and ns3::Trailer
* - a trace container class to hold lists of trace sources: ns3::TraceContainer
* - a Pcap file serializer which can generate pcap files from simulation packets: ns3::PcapWriter
* - a set of low-level trace facilities: \ref lowleveltracing
*
* The "node" module contains:
* - a ns3::Node base class and an ns3::InternetNode implementation which model
* network nodes.
* - a set of models contained in InternetNode: ns3::Ipv4, ns3::Udp, ns3::L3Demux,
* ns3::L3Protocol, ns3::Ipv4L4Demux, ns3::Ipv4L4Protocol, ns3::Ipv4Interface,
* ns3::DatagramSocket
* - models which abstract the MAC-layer from the IP layer protocols:
* ns3::NetDevice and ns3::Channel.
* - an Arp model if the underlying NetDevice object needs it: ns3::ArpIpv4Interface
* - a set of traffic generation models: ns3::OnOffApplication
*
* The "devices" module contains:
* - a PointToPoint MAC device: ns3::PointToPointNetDevice, ns3::PointToPointChannel,
* and ns3::PointToPointTopology.
*/
/**
* \namespace ns3
@ -35,6 +55,6 @@
* ns3 namespace.
*/
/**
* \defgroup constants
* \defgroup constants Constants
* \brief Constants you can change
*/

View File

@ -17,10 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#if 0
#include <list>
#include <cassert>
#endif
#include <fstream>
#include "ns3/debug.h"
#include "ns3/internet-node.h"
@ -29,7 +26,6 @@
#include "ns3/ipv4-address.h"
#include "ns3/p2p-channel.h"
#include "ns3/p2p-net-device.h"
#include "ns3/trace-writer.h"
#include "ns3/drop-tail.h"
#include "ns3/arp-ipv4-interface.h"
#include "ns3/ipv4.h"
@ -42,23 +38,13 @@
using namespace ns3;
class Logger : public TraceWriter{
class Logger {
public:
Logger ()
{
NS_DEBUG_UNCOND("**** Logger()");
}
Logger (std::string const &filename)
{
m_filestr.open (filename.c_str ());
NS_DEBUG_UNCOND("**** Logger(string const &)");
Open(filename);
}
Logger (char const *filename) : m_tracer(filename)
{
NS_DEBUG_UNCOND("**** Logger(char const *)");
Open(filename);
}
~Logger () {}
@ -89,7 +75,7 @@ public:
}
protected:
TraceWriter m_tracer;
std::ofstream m_filestr;;
};
static void
@ -139,16 +125,12 @@ int main (int argc, char *argv[])
PointToPointNetDevice neta(&a);
DropTailQueue dtqa;
neta.AddQueue(&dtqa);
neta.AddQueue(new DropTailQueue () );
neta.SetName("a.eth0");
PointToPointNetDevice netb(&b);
DropTailQueue dtqb;
netb.AddQueue(&dtqb);
neta.AddQueue(new DropTailQueue () );
netb.SetName("b.eth0");
// bind the two NetDevices together by using a simple Channel
@ -180,7 +162,8 @@ int main (int argc, char *argv[])
NS_DEBUG_UNCOND("Adding ARP Interface to InternetNode a");
ArpIpv4Interface* arpipv4interfacep = new ArpIpv4Interface(&a, &neta);
uint32_t indexA = (&a)->GetIpv4 ()->AddInterface (arpipv4interfacep);
uint32_t indexA;
indexA = (&a)->GetIpv4 ()->AddInterface (arpipv4interfacep);
NS_DEBUG_UNCOND("Adding Interface " << indexA);
@ -200,7 +183,8 @@ int main (int argc, char *argv[])
NS_DEBUG_UNCOND("Adding ARP Interface to InternetNode b");
ArpIpv4Interface* arpipv4interfacepb = new ArpIpv4Interface(&b, &netb);
uint32_t indexB = (&b)->GetIpv4 ()->AddInterface (arpipv4interfacepb);
uint32_t indexB;
indexB = (&b)->GetIpv4 ()->AddInterface (arpipv4interfacepb);
NS_DEBUG_UNCOND("Adding Interface " << indexB);

View File

@ -30,7 +30,7 @@ namespace ns3 {
/**
* \brief a helper class to offer trace resolution for an array of objects.
* \ingroup tracing
* \ingroup lowleveltracing
*/
template <typename T>
class ArrayTraceResolver : public TraceResolver

View File

@ -32,7 +32,7 @@ namespace ns3 {
/**
* \brief log arbitrary number of parameters to a matching ns3::Callback
* \ingroup tracing
* \ingroup lowleveltracing
*
* Whenever operator () is invoked on this class, the call and its arguments
* are forwarded to the internal matching ns3::Callback.

View File

@ -33,7 +33,7 @@ namespace ns3 {
/**
* \brief a helper class to aggregate contained TraceResolver and other trace sources.
* \ingroup tracing
* \ingroup lowleveltracing
*/
class CompositeTraceResolver : public TraceResolver
{

View File

@ -62,7 +62,7 @@ class UVTraceSource;
/**
* \brief trace variables of type "signed integer"
* \ingroup tracing
* \ingroup lowleveltracing
*
* This template class implements a POD type: it
* behaves like any other variable of type "signed integer"

View File

@ -29,7 +29,7 @@ namespace ns3 {
/**
* \brief Provide context to trace sources
* \ingroup tracing
* \ingroup lowleveltracing
*
* Instances of this class are used to hold context
* for each trace source. Each instance holds a list of

View File

@ -32,7 +32,7 @@ class CallbackBase;
/**
* \brief the base class which is used to incremental perform trace
* namespace resolution.
* \ingroup tracing
* \ingroup lowleveltracing
*
* This class provides a public API to the ns3::TraceRoot object:
* - ns3::TraceResolver::Connect

View File

@ -25,10 +25,9 @@
#include "ns3/callback.h"
/**
* \defgroup tracing Tracing
* \defgroup lowleveltracing Low-level tracing
*
* The low-level tracing framework is built around a few very simple
* concepts:
* This low-level API is built around a few concepts:
* - There can be any number of trace source objects. Each trace source
* object can generate any number of trace events. The current
* trace source objects are: ns3::CallbackTraceSourceSource, ns3::UVTraceSource,
@ -41,27 +40,78 @@
* a trace sink which is connected to multiple trace sources to identify
* from which source each event is coming from.
*
* To allow the user to connect his own trace sinks to each trace source
* defined by any of the models he is using, the tracing framework defines
* a hierarchical namespace. The root of this namespace is accessed through
* the ns3::TraceRoot class. The namespace is represented as a string made
* of multiple elements, each of which is separated from the other elements
* by the '/' character. A namespace string always starts with a '/'.
* To define new trace sources, a model author needs to instante one trace source
* object for each kind of tracing event he wants to export. The trace source objects
* currently defined are:
* - ns3::CallbackTraceSourceSource: this trace source can be used to convey any kind of
* trace event to the user. It is a functor, that is, it is a variable
* which behaves like a function which will forward every event to every
* connected trace sink (i.e., ns3::Callback). This trace source takes
* up to four arguments and forwards these 4 arguments together with the
* ns3::TraceContext which identifies this trace source to the connected
* trace sinks.
* - ns3::UVTraceSource: this trace source is used to convey key state variable
* changes to the user. It behaves like a normal integer unsigned variable:
* you can apply every normal arithmetic operator to it. It will forward
* every change in the value of the variable back to every connected trace
* sink by providing a TraceContext, the old value and the new value.
* - ns3::SVTraceSource: this is the signed integer equivalent of
* ns3::UVTraceSource.
* - ns3::FVTraceSource: this is the floating point equivalent of
* ns3::UVTraceSource and ns3::SVTraceSource.
*
* By default, the simulation models provide a '/nodes' tracing root. This
* '/nodes' namespace is structured as follows:
* For example, to define a trace source which notifies you of a new packet
* being transmitted, you would have to:
* \code
* class MyModel
* {
* public:
* void Tx (Packet const &p);
* private:
* CallbackTraceSource<Packet const &> m_txTrace;
* };
*
* void
* MyModel::Tx (Packet const &p)
* {
* // trace packet tx event.
* m_txTrace (p);
* // ... send the packet for real.
* }
* \endcode
*
* Once the model author has instantiated these objects and has wired them
* in his simulation code (that is, he calls them wherever he wants to trigger
* a trace event), he needs to make these trace sources available to users
* to allow them to connect any number of trace sources to any number
* of user trace sinks. While it would be possible to make each model
* export directly each of his trace source instances and request users to
* invoke a source->Connect (callback) method to perform the connection
* explicitely, it was felt that this was a bit cumbersome to do.
*
* As such, the ``connection'' between a set of sources and a sink is
* performed through a third-party class, the TraceResolver, which
* can be used to automate the connection of multiple matching trace sources
* to a single sink. This TraceResolver works by defining a hierarchical
* tracing namespace: the root of this namespace is accessed through the
* ns3::TraceRoot class. The namespace is represented as a string made of
* multiple elements, each of which is separated from the other elements
* by the '/' character. A namespace string always starts with a '/'.
*
* By default, the current simulation models provide a '/nodes' tracing root.
* This '/nodes' namespace is structured as follows:
* \code
* /nodes/n/arp
* /nodes/n/udp
* /nodes/n/ipv4
* /tx
* /rx
* /drop
* /interfaces/n/netdevice
* (NetDevice only) /queue/
* /enque
* /deque
* /drop
* /nodes/n/arp
* /queue/
* /enque
* /deque
* /drop
* \endcode
*
* The 'n' element which follows the /nodes and /interfaces namespace elements
@ -120,57 +170,73 @@
* }
* \endcode
*
* To define new trace sources, a model author needs to instante one trace source
* object for each kind of tracing event he wants to export. The trace source objects
* currently defined are:
* - ns3::CallbackTraceSourceSource: this trace source can be used to convey any kind of
* trace event to the user. It is a functor, that is, it is a variable
* which behaves like a function which will forward every event to every
* connected trace sink (i.e., ns3::Callback). This trace source takes
* up to four arguments and forwards these 4 arguments together with the
* ns3::TraceContext which identifies this trace source to the connected
* trace sinks.
* - ns3::UVTraceSource: this trace source is used to convey key state variable
* changes to the user. It behaves like a normal integer unsigned variable:
* you can apply every normal arithmetic operator to it. It will forward
* every change in the value of the variable back to every connected trace
* sink by providing a TraceContext, the old value and the new value.
* - ns3::SVTraceSource: this is the signed integer equivalent of
* ns3::UVTraceSource.
* - ns3::FVTraceSource: this is the floating point equivalent of
* ns3::UVTraceSource and ns3::SVTraceSource.
* The hierarchical global namespace described here is not implemented
* in a single central location: it was felt that doing this would make
* it too hard to introduce user-specific models which could hook
* automatically into the overal tracing system. If the tracing
* namespace was implemented in a single central location, every model
* author would have had to modify this central component to make
* his own model available to trace users.
*
* Once the model author has instantiated these objects and has wired them
* in his simulation code (that is, he calls them wherever he wants to
* trigger a trace event), he needs to hook these trace sources into the
* global tracing namespace. The first step to do this is to define a method
* which returns a pointer to a ns3::TraceResolver object and which takes
* as argument a reference to a const ns3::TraceContext. The name of this method
* depends on how you will hook into the global tracing namespace. Before
* we get there, you need to implement this method. To do this, you could
* attempt to do everything by hand: define a subclass of the
* ns3::TraceResolver base class and implement its DoConnect, DoDisconnect
* and DoLookup methods. Because doing this can be a bit tedious, our
* tracing framework provides a number of helper template classes which
* should save you from having to implement your own in most cases:
* - ns3::CompositeTraceResolver: this subclass of ns3::TraceResolver
* can be used to aggregate together multiple trace sources and
* multiple other ns3::TraceResolver instances.
* - ns3::ArrayTraceResolver: this subclass of ns3::TraceResolver
* can be used to match any number of elements within an array
* where every element is identified by its index.
* Instead, the handling of the namespace is distributed across every relevant
* model: every model implements only the part of the namespace it is
* really responsible for. To do this, every model is expected
* to provide an instance of a TraceResolver whose
* responsability is to recursively provide access to the trace sources
* defined in its model. Each TraceResolver instance should be a subclass
* of the TraceResolver base class which implements either the DoLookup
* or the DoConnect and DoDisconnect methods. Because implementing these
* methods can be a bit tedious, our tracing framework provides a number
* of helper template classes which should save the model author from
* having to implement his own in most cases:
* - ns3::CompositeTraceResolver: this subclass of ns3::TraceResolver can
* be used to aggregate together multiple trace sources and multiple other
* ns3::TraceResolver instances.
* - ns3::ArrayTraceResolver: this subclass of ns3::TraceResolver can be
* used to match any number of elements within an array where every element
* is identified by its index.
*
* Once you can instantiate your own ns3::TraceResolver object instance,
* you have to hook it up into the global namespace. There are two ways
* to do this:
* Once you can instantiate your own ns3::TraceResolver object instance, you
* have to hook it up into the global namespace. There are two ways to do this:
* - you can hook your ns3::TraceResolver creation method as a new trace
* root by using the ns3::TraceRoot::Register method
* - you can hook your new ns3::TraceResolver creation method into
* the container of your model.
* For example, if you wrote a new l3 protocol, all you have to do
* to hook into your container L3Demux class is to implement
* the pure virtual method inherited from the L3Protocol class
* whose name is ns3::L3protocol::CreateTraceResolver.
* - you can hook your new ns3::TraceResolver creation method into the
* container of your model. This step will obvsiouly depend on which model
* contains your own model but, if you wrote a new l3 protocol, all you
* would have to do to hook into your container L3Demux class is to implement
* the pure virtual method inherited from the L3Protocol class whose name is
* ns3::L3protocol::CreateTraceResolver.
*
* So, in most cases, exporting a model's trace sources is a matter of
* implementing a method CreateTraceResolver as shown below:
* \code
* class MyModel
* {
* public:
* enum TraceType {
* TX,
* RX,
* ...
* };
* TraceResolver *CreateTraceResolver (TraceContext const &context);
* void Tx (Packet const &p);
* private:
* CallbackTraceSource<Packet const &> m_txTrace;
* };
*
* TraceResolver *
* MyModel::CreateTraceResolver (TraceContext const &context)
* {
* CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
* resolver->Add ("tx", m_txTrace, MyModel::TX);
* return resolver;
* }
* void
* MyModel::Tx (Packet const &p)
* {
* m_txTrace (p);
* }
* \endcode
*
* If you really want to have fun and implement your own ns3::TraceResolver
* subclass, you need to understand the basic Connection and Disconnection
@ -189,38 +255,55 @@
* the following call traces:
*
* \code
* TraceRoot::Connect (/nodes/ * /ipv4/interfaces/ * /netdevice/queue/ *);
* resolver = NodeList::CreateTraceResolver ();
* resolver->Connect (/nodes/ * /ipv4/interfaces/ * /netdevice/queue/ *);
* list = CompositeTraceResolver::DoLookup ('nodes');
* resolver->Connect (/ * /ipv4/interfaces/ * /netdevice/queue/ *);
* list = ArrayTraceResolver::DoLookup ('*');
* resolver->Connect ('/ipv4/interfaces/ * /netdevice/queue/ *');
* list = CompositeTraceResolver::DoLookup ('ipv4');
* resolver->Connect ('/interfaces/ * /netdevice/queue/ *');
* list = CompositeTraceResolver::DoLookup ('interfaces');
* resolver->Connect ('/ * /netdevice/queue/ *');
* list = ArrayTraceResolver::DoLookup ('*');
* resolver->Connect ('/netdevice/queue/ *');
* list = CompositeTraceResolver::DoLookup ('netdevice');
* resolver->Connect ('/queue/ *');
* list = CompositeTraceResolver::DoLookup ('queue');
* resolver->Connect ('/ *');
* list = CompositeTraceResolver::DoLookup ('*');
* resolver->DoConnect ();
* TraceRoot::Connect ("/nodes/ * /ipv4/interfaces/ * /netdevice/queue/ *", callback);
* traceContext = TraceContext ();
* rootResolver = CompositeTraceResolver (traceContext);
* rootResolver->Connect ("/nodes/ * /ipv4/interfaces/ * /netdevice/queue/ *", callback);
* resolver = CompositeTraceResolver::DoLookup ("nodes");
* return NodeList::CreateTraceResolver (GetContext ());
* return ArrayTraceResolver (context);
* resolver->Connect ("/ * /ipv4/interfaces/ * /netdevice/queue/ *", callback);
* ArrayTraceResolver::DoLookup ("*");
* for (i = 0; i < n_nodes; i++)
* resolver = nodes[i]->CreateTraceResolver (GetContext ());
* return CompositeTraceResolver (context);
* resolvers.add (resolver);
* return resolvers;
* for resolver in (resolvers)
* resolver->Connect ("/ipv4/interfaces/ * /netdevice/queue/ *", callback);
* CompositeTraceResolver::DoLookup ("ipv4");
* resolver = ipv4->CreateTraceResolver (GetContext ());
* return CompositeTraceResolver (context);
* return resolver;
* resolver->Connect ("/interfaces/ * /netdevice/queue/ *", callback);
* CompositeTraceResolver::DoLookup ("interfaces");
* resolver = ArrayTraceResolver (GetContext ());
* resolver->Connect ("/ * /netdevice/queue/ *", callback);
* ArrayTraceResolver::DoLookup ("*");
* for (i = 0; i < n_interfaces; i++)
* resolver = interfaces[i]->CreateTraceResolver (GetContext ());
* return CompositeTraceResolver ()
* resolvers.add (resolver);
* return resolvers;
* resolver->Connect ("/netdevice/queue/ *", callback);
* CompositeTraceResolver::DoLookup ("netdevice");
* resolver = NetDevice::CreateTraceResolver (GetContext ());
* return CompositeTraceResolver ();
* return resolver;
* resolver->Connect ("/queue/ *", callback);
* CompositeTraceResolver::DoLookup ("queue");
* resolver = Queue::CreateTraceResolver (GetContext ());
* return CompositeTraceResolver ();
* return resolver
* resolver->Connect ("*", callback);
* CompositeTraceResolver::DoLookup ("*");
* for match in (matches)
* resolver = TerminalTraceResolver ("match");
* resolvers.add (resolver)
* return resolvers;
* for resolver in (resolvers)
* TerminalTraceResolver->DoConnect (callback);
* \endcode
*
* This namespace resolution algorithm makes sure that each subpart of the
* namespace is resolved separately by each component. It allows you to
* never have to know the entire namespace structure to resolve a namespace
* string. All namespace knowledge is local which makes it very easy to plug
* in new components and have them extend the global tracing namespace.
*
* What is central to this namespace parsing and resolution algorithm is the
* construction of an ns3::TraceContext for each trace source during the
* connection process. The root trace context is intialized to be empty and
* TraceResolver::DoLookup method is responsible for incrementally constructing
* the TraceContext assigned to each terminal TraceSource object.
*/
namespace ns3 {
@ -234,7 +317,7 @@ class CallbackBase;
* \brief The main class used to access tracing functionality for
* a user.
*
* \ingroup tracing
* \ingroup lowleveltracing
*/
class TraceRoot
{

View File

@ -1,112 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 University of Washington
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Craig Dowell <craigdo@ee.washingon.edu>
*
* Thu Feb 8 10:42:52 PST 2007 craigdo: Created from pcap-writer.c
*/
#include "ns3/debug.h"
#include "trace-writer.h"
NS_DEBUG_COMPONENT_DEFINE ("TraceWriter");
namespace ns3 {
TraceWriter::TraceWriter () :
m_filestr()
{
NS_DEBUG ("TraceWriter()::TraceWriter()");
std::streambuf *sb = m_filestr.rdbuf();
NS_DEBUG ("TraceWriter()::TraceWriter(): rdbuf ()");
rdbuf(sb);
NS_DEBUG ("TraceWriter()::TraceWriter(): done");
}
TraceWriter::TraceWriter (std::string const &filename) :
m_filestr()
{
NS_DEBUG ("TraceWriter()::TraceWriter (\"" << filename << "\")");
m_filestr.open (filename.c_str(), std::ios::out | std::ios::app);
std::streambuf *sb = m_filestr.rdbuf();
NS_DEBUG ("TraceWriter()::TraceWriter(): rdbuf ()");
rdbuf(sb);
NS_DEBUG ("TraceWriter()::TraceWriter(): done");
}
TraceWriter::TraceWriter (char const *filename) :
m_filestr()
{
NS_DEBUG ("TraceWriter()::TraceWriter (\"" << filename << "\")");
m_filestr.open (filename, std::ios::out | std::ios::app);
std::streambuf *sb = m_filestr.rdbuf();
NS_DEBUG ("TraceWriter()::TraceWriter(): rdbuf ()");
rdbuf(sb);
NS_DEBUG ("TraceWriter()::TraceWriter(): done");
}
TraceWriter::~TraceWriter ()
{
NS_DEBUG ("TraceWriter()::~TraceWriter()");
}
void
TraceWriter::Open (std::string const &filename)
{
NS_DEBUG ("TraceWriter()::Open (\"" << filename << "\")");
m_filestr.open (filename.c_str(), std::ios::out);
}
void
TraceWriter::Open (char const *filename)
{
NS_DEBUG ("TraceWriter()::Open (\"" << filename << "\")");
m_filestr.open (filename, std::ios::out);
}
void
TraceWriter::Close ()
{
NS_DEBUG ("TraceWriter()::Close ()");
m_filestr.close ();
}
void
TraceWriter::Write (std::string const &str)
{
NS_DEBUG ("TraceWriter()::Write (\"" << str << "\")");
m_filestr << str;
}
}; // namespace ns3

View File

@ -1,59 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 University of Washington
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Craig Dowell <craigdo@ee.washingon.edu>
*
* Thu Feb 8 10:41:40 PST 2007 craigdo: Created
*/
#ifndef TRACE_WRITER_H
#define TRACE_WRITER_H
#include <iostream>
#include <fstream>
#include <streambuf>
#include <string>
#include "ns3/callback.h"
namespace ns3 {
class TraceWriter : public std::ostream {
public:
TraceWriter ();
TraceWriter (std::string const &filename);
TraceWriter (char const *filename);
~TraceWriter ();
void Open (std::string const &filename);
void Open (char const *filename);
void Close ();
/**
* \param String to write to output file
*/
void Write (std::string const &str);
protected:
std::ofstream m_filestr;
void Init (const char *filename);
};
}; // namespace ns3
#endif /* TRACE_WRITER_H */

View File

@ -66,7 +66,7 @@ class SVTraceSource;
/**
* \brief trace variables of type "unsigned integer"
* \ingroup tracing
* \ingroup lowleveltracing
*
* This template class implements a POD type: it
* behaves like any other variable of type "unsigned integer"

View File

@ -22,7 +22,7 @@
#define ASSERT_H
/**
* \defgroup assert
* \defgroup assert Assert
* \brief assert functions and macros
*
* The assert macros are used to verify

View File

@ -458,6 +458,7 @@ Callback<R> MakeNullCallback (void) {
}
/**
* \ingroup MakeCallback
* \overload Callback<R> MakeNullCallback (void)
* \return a wrapper Callback
* Build a null callback which takes one argument
* and potentially return a value.
@ -468,6 +469,7 @@ Callback<R,T1> MakeNullCallback (void) {
}
/**
* \ingroup MakeCallback
* \overload Callback<R> MakeNullCallback (void)
* \return a wrapper Callback
* Build a null callback which takes two arguments
* and potentially return a value.
@ -478,6 +480,7 @@ Callback<R,T1,T2> MakeNullCallback (void) {
}
/**
* \ingroup MakeCallback
* \overload Callback<R> MakeNullCallback (void)
* \return a wrapper Callback
* Build a null callback which takes three arguments
* and potentially return a value.
@ -488,6 +491,7 @@ Callback<R,T1,T2,T3> MakeNullCallback (void) {
}
/**
* \ingroup MakeCallback
* \overload Callback<R> MakeNullCallback (void)
* \return a wrapper Callback
* Build a null callback which takes four arguments
* and potentially return a value.
@ -498,6 +502,7 @@ Callback<R,T1,T2,T3,T4> MakeNullCallback (void) {
}
/**
* \ingroup MakeCallback
* \overload Callback<R> MakeNullCallback (void)
* \return a wrapper Callback
* Build a null callback which takes five arguments
* and potentially return a value.

View File

@ -22,7 +22,7 @@
#define DEBUG_H
/**
* \defgroup debugging
* \defgroup debugging Debugging
* \brief Debugging functions and macros
*
* - DEBUG functionality: macros which allow developers to

View File

@ -22,6 +22,7 @@
#define FATAL_ERROR_H
#include "assert.h"
#include <iostream>
/**
* \defgroup error Error

View File

@ -29,18 +29,58 @@
namespace ns3 {
/**
* \brief Store objects for delayed deletion.
*
* This class can store any type of object provided it can be deleted.
* There is no requirement that the destructor of these objects be
* virtual. When the ObjectContainer::Cleanup method is invoked,
* all the objects still left in the container will be deleted.
* Alternatively, Cleanup is called automatically. when this object is
* destroyed.
*/
class ObjectContainer
{
public:
/**
* Invoke ObjectContainer::Cleanup if the user has not invoked it
* himself.
*/
~ObjectContainer ();
/**
* Delete all objects stored in this container.
*/
void Cleanup (void);
/**
* \param object object to store in the container.
*
* Take ownership of the input pointer: the object
* will be deleted when ObjectContainer::Cleanup is invoked.
*/
template <typename T>
void Acquire (T *object);
/**
* \param object template of the object to store in the
* container.
*
* Invoke the Copy method of the input object. This method is
* expected to return a pointer of similar type and that
* pointer will be returned. Furthermore, the pointer will
* be stored internally to delete it when ObjectContainer::Cleanup
* is invoked.
*/
template <typename T>
T *Add (T const &object);
/**
* \param object object to remove from container.
*
* Remove the object from the container: it will not
* be deleted when the ObjectContainer::Cleanup method
* is invoked.
*/
template <typename T>
void Remove (T *object);

View File

@ -130,39 +130,38 @@ Ptr<T>::DeallocCount (uint32_t *count)
template <typename T>
Ptr<T>::Ptr ()
: m_ptr (0),
m_count (Ptr::AllocCount ())
: m_ptr (0)
{}
template <typename T>
Ptr<T>::Ptr (T *ptr)
: m_ptr (ptr),
m_count (Ptr::AllocCount ())
: m_ptr (ptr)
{
if (m_ptr != 0)
{
m_count = Ptr::AllocCount ();
*m_count = 1;
}
}
template <typename T>
Ptr<T>::Ptr (Ptr const&o)
: m_ptr (o.m_ptr),
m_count (o.m_count)
: m_ptr (o.m_ptr)
{
if (m_ptr != 0)
{
m_count = o.m_count;
(*m_count)++;
}
}
template <typename T>
template <typename U>
Ptr<T>::Ptr (Ptr<U> const &o)
: m_ptr (o.m_ptr),
m_count (o.m_count)
: m_ptr (o.m_ptr)
{
if (m_ptr != 0)
{
m_count = o.m_count;
(*m_count)++;
}
}
@ -185,10 +184,8 @@ template <typename T>
Ptr<T> &
Ptr<T>::operator = (Ptr const& o)
{
if (o.m_ptr != 0)
{
(*(o.m_count))++;
}
if (&o == this)
return *this;
if (m_ptr != 0)
{
(*m_count)--;
@ -199,7 +196,11 @@ Ptr<T>::operator = (Ptr const& o)
}
}
m_ptr = o.m_ptr;
m_count = o.m_count;
if (m_ptr != 0)
{
m_count = o.m_count;
(*m_count)++;
}
return *this;
}
@ -246,10 +247,18 @@ template <typename T>
T *
Ptr<T>::Remove (void)
{
NS_ASSERT ((*m_count) == 1);
T *retval = m_ptr;
m_ptr = 0;
return retval;
if (m_ptr == 0)
{
return (T *) 0;
}
else
{
NS_ASSERT ((*m_count) == 1);
Ptr::DeallocCount (m_count);
T *retval = m_ptr;
m_ptr = 0;
return retval;
}
}
// non-member friend functions.

View File

@ -37,54 +37,7 @@
using namespace std;
namespace ns3{
// Seed methods
Seed::~Seed()
{
}
RandomSeed::RandomSeed()
{
}
RandomSeed::~RandomSeed()
{
}
bool RandomSeed::IsRandom() const
{
return true;
}
ConstantSeed::~ConstantSeed()
{
}
bool ConstantSeed::IsRandom() const
{
return false;
}
ConstantSeed::ConstantSeed(uint32_t s)
{
seeds[0] = s;
seeds[1] = s;
seeds[2] = s;
seeds[3] = s;
seeds[4] = s;
seeds[5] = s;
}
ConstantSeed::ConstantSeed(uint32_t s0, uint32_t s1, uint32_t s2,
uint32_t s3, uint32_t s4, uint32_t s5)
{
seeds[0] = s0;
seeds[1] = s1;
seeds[2] = s2;
seeds[3] = s3;
seeds[4] = s4;
seeds[5] = s5;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// RandomVariable methods
@ -133,7 +86,8 @@ void RandomVariable::GetSeed(uint32_t seed[6])
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// RandomVariable static methods
void RandomVariable::UseGlobalSeed(const Seed& s)
void RandomVariable::UseGlobalSeed(uint32_t s0, uint32_t s1, uint32_t s2,
uint32_t s3, uint32_t s4, uint32_t s5)
{
if (RandomVariable::globalSeedSet)
{
@ -141,16 +95,14 @@ void RandomVariable::UseGlobalSeed(const Seed& s)
cout << "Call to RandomVariable::UseGlobalSeed() ignored" << endl;
return;
}
if (s.IsRandom()) return; // Random seed is the default
const ConstantSeed& cs = (ConstantSeed&)s;
RandomVariable::globalSeed[0] = cs.seeds[0];
RandomVariable::globalSeed[1] = cs.seeds[1];
RandomVariable::globalSeed[2] = cs.seeds[2];
RandomVariable::globalSeed[3] = cs.seeds[3];
RandomVariable::globalSeed[4] = cs.seeds[4];
RandomVariable::globalSeed[5] = cs.seeds[5];
RandomVariable::globalSeed[0] = s0;
RandomVariable::globalSeed[1] = s1;
RandomVariable::globalSeed[2] = s2;
RandomVariable::globalSeed[3] = s3;
RandomVariable::globalSeed[4] = s4;
RandomVariable::globalSeed[5] = s5;
if (!RngStream::CheckSeed(RandomVariable::globalSeed))
NS_FATAL_ERROR("Invalid seed");
NS_FATAL_ERROR("Invalid seed");
RandomVariable::globalSeedSet = true;
}
@ -399,6 +351,7 @@ RandomVariable* WeibullVariable::Copy() const
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// NormalVariable methods
const double NormalVariable::INFINITE_VALUE = 1e307;
NormalVariable::NormalVariable()
: m_mean(0.0), m_variance(1.0), m_bound(INFINITE_VALUE), m_nextValid(false){}
@ -445,11 +398,11 @@ RandomVariable* NormalVariable::Copy() const
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// ValueCDF methods
ValueCDF::ValueCDF()
EmpiricalVariable::ValueCDF::ValueCDF()
: value(0.0), cdf(0.0){ }
ValueCDF::ValueCDF(double v, double c)
EmpiricalVariable::ValueCDF::ValueCDF(double v, double c)
: value(v), cdf(c) { }
ValueCDF::ValueCDF(const ValueCDF& c)
EmpiricalVariable::ValueCDF::ValueCDF(const ValueCDF& c)
: value(c.value), cdf(c.cdf) { }
//-----------------------------------------------------------------------------

View File

@ -25,48 +25,18 @@
#include <algorithm>
#define INFINITE_VALUE 1e307
/**
* \defgroup randomvariable Random Variable Distributions
*
*/
namespace ns3{
class RngStream;
/**
* \brief Pure virtual base class for RNG seeds
*/
class Seed {
// Seed is used to seed the random number generator(s)
// This is a base class for RandomSeed and ConstantSeed
public:
virtual ~Seed();
virtual bool IsRandom() const = 0;
};
/**
* \brief random RNG seeds
*/
class RandomSeed : public Seed {
public:
RandomSeed();
~RandomSeed();
bool IsRandom() const;
};
/**
* \brief constant RNG seeds
*/
class ConstantSeed : public Seed
{
public:
ConstantSeed(uint32_t); // Use six copies of the specified value
ConstantSeed(uint32_t,uint32_t,uint32_t,uint32_t,uint32_t,uint32_t); // Six seeds
bool IsRandom() const;
~ConstantSeed();
public:
uint32_t seeds[6];
};
/**
* \brief The basic RNG for NS-3.
* \ingroup randomvariable
*
* Note: The underlying random number generation method used
* by NS-3 is the RngStream code by Pierre L'Ecuyer at
@ -159,10 +129,16 @@ public:
* UniformVariable x(2,3); //these will give the same output everytime
* ExponentialVariable y(120); //as long as the seed stays the same
* \endcode
* \param s
* \param s0
* \param s1
* \param s2
* \param s3
* \param s4
* \param s5
* \return True if seed is valid.
*/
static void UseGlobalSeed(const Seed& s);
static void UseGlobalSeed(uint32_t s0, uint32_t s1, uint32_t s2,
uint32_t s3, uint32_t s4, uint32_t s5);
/**
* \brief Set the run number of this simulation
@ -178,7 +154,7 @@ public:
* after the global seed is set, and before the creation of any
* RandomVariables. For example:
* \code
* RandomVariable::UseGlobalSeed(ConstantSeed(1,2,3,4,5,6));
* RandomVariable::UseGlobalSeed(1,2,3,4,5,6);
* int N = atol(argv[1]); //read in run number from command line
* RandomVariable::SetRunNumber(N);
* UniformVariable x(0,10);
@ -214,6 +190,7 @@ protected:
/**
* \brief The uniform distribution RNG for NS-3.
* \ingroup randomvariable
*/
class UniformVariable : public RandomVariable {
public:
@ -244,6 +221,7 @@ private:
/**
* \brief A random variable that returns a constant
* \ingroup randomvariable
*
* Class ConstantVariable defines a random number generator that
* returns the same value every sample.
@ -284,6 +262,7 @@ private:
/**
* \brief Return a sequential list of values
* \ingroup randomvariable
*
* Class SequentialVariable defines a random number generator that
* returns a sequential sequence. The sequence monotonically
@ -337,6 +316,7 @@ private:
/**
* \brief Exponentially Distributed random var
* \ingroup randomvariable
*
* ExponentialVariable defines a random variable with an exponential distribution
*/
@ -381,6 +361,7 @@ private:
/**
* \brief ParetoVariable distributed random var
* \ingroup randomvariable
*/
class ParetoVariable : public RandomVariable { //
public:
@ -433,6 +414,7 @@ private:
/**
* \brief WeibullVariable distributed random var
* \ingroup randomvariable
*/
class WeibullVariable : public RandomVariable {
public:
@ -485,12 +467,14 @@ private:
};
/**
* Class NormalVariable defines a random variable with a
* \brief Class NormalVariable defines a random variable with a
* normal (Gaussian) distribution.
* \ingroup randomvariable
*/
class NormalVariable : public RandomVariable { // Normally Distributed random var
public:
static const double INFINITE_VALUE;
/**
* Constructs an normal random variable with a mean
* value of 0 and variance of 1.
@ -521,19 +505,9 @@ private:
double m_next; // The algorithm produces two values at a time
};
// Value/CDF pair class for Emiprical Distributions
//Doc:ClassXRef
class ValueCDF {
public:
ValueCDF();
ValueCDF(double v, double c);
ValueCDF(const ValueCDF& c);
double value;
double cdf;
};
/**
* \brief EmpiricalVariable distribution random var
* \ingroup randomvariable
*
* Defines a random variable that has a specified, empirical
* distribution. The distribution is specified by a
@ -566,6 +540,14 @@ public:
virtual void CDF(double v, double c); // Value, prob <= Value
private:
class ValueCDF {
public:
ValueCDF();
ValueCDF(double v, double c);
ValueCDF(const ValueCDF& c);
double value;
double cdf;
};
virtual void Validate(); // Insure non-decreasing emiprical values
virtual double Interpolate(double, double, double, double, double);
bool validated; // True if non-decreasing validated
@ -573,6 +555,9 @@ private:
};
/**
* \brief Integer-based empirical distribution
* \ingroup randomvariable
*
* Defines an empirical distribution where all values are integers.
* Indentical to EmpiricalVariable, but with slightly different
* interpolation between points.
@ -591,11 +576,14 @@ public:
};
/**
* Defines a random variable that has a specified, predetermined
* sequence. This would be useful when trying to force
* the RNG to return a known sequence, perhaps to
* compare NS-3 to some other simulator
*/
* \brief a non-random variable
* \ingroup randomvariable
*
* Defines a random variable that has a specified, predetermined
* sequence. This would be useful when trying to force
* the RNG to return a known sequence, perhaps to
* compare NS-3 to some other simulator
*/
class DeterministicVariable : public RandomVariable {
public:

View File

@ -61,6 +61,9 @@ PointToPointNetDevice::~PointToPointNetDevice()
m_channel->Unref ();
m_channel = 0;
}
delete m_queue;
m_queue = 0;
}
//
@ -136,7 +139,7 @@ PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest)
NS_DEBUG ("PointToPointNetDevice::SendTo (" << &p << ", " << &dest << ")");
NS_DEBUG ("PointToPointNetDevice::SendTo (): UID is " << p.GetUid () << ")");
assert (IsLinkUp ());
NS_ASSERT (IsLinkUp ());
#ifdef NOTYET
struct NetDevicePacketDestAddress tag;
@ -206,14 +209,15 @@ PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest)
PointToPointNetDevice::TransmitStart (Packet &p)
{
NS_DEBUG ("PointToPointNetDevice::TransmitStart (" << &p << ")");
NS_DEBUG ("PointToPointNetDevice::TransmitStart (): UID is " << p.GetUid () << ")");
NS_DEBUG (
"PointToPointNetDevice::TransmitStart (): UID is " << p.GetUid () << ")");
//
// This function is called to start the process of transmitting a packet.
// We need to tell the channel that we've started wiggling the wire and
// schedule an event that will be executed when it's time to tell the
// channel that we're done wiggling the wire.
//
NS_ASSERT(m_txMachineState == READY && "Must be READY to transmit");
NS_ASSERT_MSG(m_txMachineState == READY, "Must be READY to transmit");
m_txMachineState = BUSY;
Time tEvent = Seconds (m_bps.CalculateTxTime(p.GetSize()));
@ -237,11 +241,12 @@ PointToPointNetDevice::TransmitCompleteEvent (void)
// schedule an event that will be executed when it's time to re-enable
// the transmitter after the interframe gap.
//
NS_ASSERT(m_txMachineState == BUSY && "Must be BUSY if transmitting");
NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
m_txMachineState = GAP;
Packet p;
bool found = m_queue->Dequeue (p);
NS_ASSERT(found && "Packet must be on queue if transmitted");
bool found;
found = m_queue->Dequeue (p);
NS_ASSERT_MSG(found, "Packet must be on queue if transmitted");
NS_DEBUG ("PointToPointNetDevice::TransmitCompleteEvent (): Pkt UID is " <<
p.GetUid () << ")");
m_channel->TransmitEnd (p, this);
@ -265,7 +270,7 @@ PointToPointNetDevice::TransmitReadyEvent (void)
// gap has passed. If there are pending transmissions, we use this opportunity
// to start the next transmit.
//
NS_ASSERT(m_txMachineState == GAP && "Must be in interframe gap");
NS_ASSERT_MSG(m_txMachineState == GAP, "Must be in interframe gap");
m_txMachineState = READY;
if (m_queue->IsEmpty())
@ -275,8 +280,9 @@ PointToPointNetDevice::TransmitReadyEvent (void)
else
{
Packet p;
bool found = m_queue->Peek (p);
NS_ASSERT(found && "IsEmpty false but no Packet on queue?");
bool found;
found = m_queue->Peek (p);
NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
TransmitStart (p);
}
}
@ -348,8 +354,8 @@ PointToPointNetDevice::GetQueue(void) const
return m_queue;
}
PointToPointChannel*
PointToPointNetDevice::GetChannel(void) const
Channel*
PointToPointNetDevice::DoGetChannel(void) const
{
return m_channel;
}

View File

@ -33,57 +33,274 @@
namespace ns3 {
class PointToPointChannel;
class Queue;
class PointToPointChannel;
/**
* \class PointToPointNetDevice
* \brief A Device for a Point to Point Network Link.
*
* Ns-3 takes a four-layer view of a protocol stack. This is the same model
* that TCP uses. In this view, layers 5-7 of the OSI reference model are
* grouped together into an application layer; layer four (transport / TCP) is
* broken out; layer three (network / IP) is broken out; and layers 1-2 are
* grouped together. We call this grouping of layers one and two a NetDevice
* and represent it as a class in the system.
*
* The NetDevice class is specialized according to the needs of the specific
* kind of network link. In this case, the link is a PointToPoint link. The
* PointToPoint link is a family of classes that includes this class, the
* PointToPointNetDevice, a PointToPointChannel class that represents the
* actual medium across which bits are sent, a PointToPointIpv4Interface class
* that provides the hook to tie a general purpose node to this specific
* link, and finally, a PointToPointTopology object that is responsible for
* putting all of the pieces together.
*
* This is the PointToPointNetDevice class that represents, essentially, the
* PC card that is used to connect to the PointToPoint network.
*/
class PointToPointNetDevice : public NetDevice {
public:
/**
* Enumeration of the types of traces supported in the class.
*
*/
enum TraceType {
QUEUE,
RX,
QUEUE, /**< Trace queue events on the attached queue */
RX, /**< Trace packet reception events (from the channel) */
};
/**
* Construct a PointToPointNetDevice
*
* This is the constructor for the PointToPointNetDevice. It takes as a
* parameter the Node to which this device is connected. Ownership of the
* Node pointer is not implied and the node must not be deleded.
*
* @see PointToPointTopology::AddPointToPointLink ()
* @param node the Node to which this device is connected.
*/
PointToPointNetDevice (Node* node);
/**
* Copy Construct a PointToPointNetDevice
*
* This is the copy constructor for the PointToPointNetDevice. This is
* primarily used in topology creation.
*
* @see PointToPointTopology::AddPointToPointLink ()
* @param nd the object to be copied
*/
PointToPointNetDevice (const PointToPointNetDevice& nd);
/**
* Destroy a PointToPointNetDevice
*
* This is the destructor for the PointToPointNetDevice.
*/
virtual ~PointToPointNetDevice();
/**
* Assignment Operator for a PointToPointNetDevice
*
* This is the assignment operator for the PointToPointNetDevice. This is
* to allow
*
* @param nd the object to be copied
*/
PointToPointNetDevice& operator= (PointToPointNetDevice nd);
/**
* Set the Data Rate used for transmission of packets. The data rate is
* set in the Attach () method from the corresponding field in the channel
* to which the device is attached. It can be overridden using this method.
*
* @see Attach ()
* @param bps the data rate at which this object operates
*/
void SetDataRate(DataRate bps);
/**
* Set the inteframe gap used to separate packets. The interframe gap
* defines the minimum space required between packets sent by this device.
* It is usually set in the Attach () method based on the speed of light
* delay of the channel to which the device is attached. It can be
* overridden using this method if desired.
*
* @see Attach ()
* @param t the interframe gap time
*/
void SetInterframeGap(Time t);
public:
/**
* Attach the device to a channel.
*
* The PointToPointTopology object creates a PointToPointChannel and two
* PointtoPointNetDevices. In order to introduce these components to each
* other, the topology object calls Attach () on each PointToPointNetDevice.
* Inside this method, the Net Device calls out to the PointToPointChannel
* to introduce itself.
*
* @see PointToPointTopology::AddPointToPointLink ()
* @see SetDataRate ()
* @see SetInterframeGap ()
* @param ch a pointer to the channel to which this object is being attached.
*/
bool Attach(PointToPointChannel* ch);
void AddQueue(Queue*);
/**
* Attach a queue to the PointToPointNetDevice.
*
* The PointToPointNetDevice "owns" a queue. This queue is created by the
* PointToPointTopology object and implements a queueing method such as
* DropTail or RED. The PointToPointNetDevice assumes ownership of this
* queue and must delete it when the device is destroyed.
*
* @see PointToPointTopology::AddPointToPointLink ()
* @see Queue
* @see DropTailQueue
* @param queue a pointer to the queue for which object is assuming
* ownership.
*/
void AddQueue(Queue* queue);
/**
* Receive a packet from a connected PointToPointChannel.
*
* The PointToPointNetDevice receives packets from its connected channel
* and forwards them up the protocol stack. This is the public method
* used by the channel to indicate that the last bit of a packet has
* arrived at the device.
*
* @see PointToPointChannel
* @param p a reference to the received packet
*/
void Receive (Packet& p);
protected:
/**
* Get a copy of the attached Queue.
*
* This method is provided for any derived class that may need to get
* direct access to the underlying queue.
*
* @see PointToPointTopology
* @returns a pointer to the queue.
*/
Queue* GetQueue(void) const;
PointToPointChannel* GetChannel(void) const;
/**
* Get a copy of the attached Channel
*
* This method is provided for any derived class that may need to get
* direct access to the connected channel
*
* @see PointToPointChannel
* @returns a pointer to the channel
*/
virtual Channel *DoGetChannel(void) const;
private:
/**
* Send a Packet Down the Wire.
*
* The SendTo method is defined as the standard way that the level three
* protocol uses to tell a NetDevice to send a packet. SendTo is declared
* as abstract in the NetDevice class and we declare it here.
*
* @see NetDevice
* @param p a reference to the packet to send
* @param dest a reference to the MacAddress of the destination device
* @returns true if success, false on failure
*/
virtual bool SendTo (Packet& p, const MacAddress& dest);
/**
* Start Sending a Packet Down the Wire.
*
* The TransmitStart method is the method that is used internally in the
* PointToPointNetDevice to begin the process of sending a packet out on
* the channel. The corresponding method is called on the channel to let
* it know that the physical device this class represents has virually
* started sending signals. An event is scheduled for the time at which
* the bits have been completely transmitted.
*
* @see PointToPointChannel::TransmitStart ()
* @see TransmitCompleteEvent ()
* @param p a reference to the packet to send
* @returns true if success, false on failure
*/
bool TransmitStart (Packet &p);
/**
* Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
*
* The TransmitCompleteEvent method is used internally to finish the process
* of sending a packet out on the channel. During execution of this method
* the TransmitEnd method is called on the channel to let it know that the
* physical device this class represents has virually finished sending
* signals. The channel uses this event to begin its speed of light delay
* timer after which it notifies the Net Device at the other end of the
* link that the bits have arrived. During this method, the net device
* also schedules the TransmitReadyEvent at which time the transmitter
* becomes ready to send the next packet.
*
* @see PointToPointChannel::TransmitEnd ()
* @see TransmitReadyEvent ()
* @returns true if success, false on failure
*/
void TransmitCompleteEvent (void);
/**
* Cause the Transmitter to Become Ready to Send Another Packet.
*
* The TransmitReadyEvent method is used internally to re-enable the
* transmit machine of the net device. It is scheduled after a suitable
* interframe gap after the completion of the previous transmission.
* The queue is checked at this time, and if there is a packet waiting on
* the queue, the transmission process is begun.
*
* @see TransmitStart ()
*/
void TransmitReadyEvent (void);
/**
* Create a Trace Resolver for events in the net device.
*
* @see class TraceResolver
*/
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
/**
* Enumeration of the states of the transmit machine of the net device.
*/
enum TxMachineState
{
READY,
BUSY,
GAP
READY, /**< The transmitter is ready to begin transmission of a packet */
BUSY, /**< The transmitter is busy transmitting a packet */
GAP /**< The transmitter is in the interframe gap time */
};
/**
* The state of the Net Device transmit state machine.
* @see TxMachineState
*/
TxMachineState m_txMachineState;
/**
* The data rate that the Net Device uses to simulate packet transmission
* timing.
* @see class DataRate
*/
DataRate m_bps;
/**
* The interframe gap that the Net Device uses to throttle packet
* transmission
* @see class Time
*/
Time m_tInterframeGap;
/**
* The PointToPointChannel to which this PointToPointNetDevice has been
* attached.
* @see class PointToPointChannel
*/
PointToPointChannel* m_channel;
/**
* The Queue which this PointToPointNetDevice uses as a packet source.
* Management of this Queue has been delegated to the PointToPointNetDevice
* and it has the responsibility for deletion.
* @see class Queue
* @see class DropTailQueue
*/
Queue* m_queue;
/**
* The trace source for the packet reception events that the device can
* fire.
*
* @see class CallBackTraceSource
* @see class TraceResolver
*/
CallbackTraceSource<Packet &> m_rxTrace;
};

View File

@ -34,27 +34,43 @@ class IPAddr;
class DataRate;
class Queue;
//class Time;
/**
* \brief A helper class to create Topologies based on the ns3::PointToPointNetDevice and
* ns3::PointToPointChannel objects.
*
* XXX ??
* I think that some of the methods below are not implemented.
* If so, remove them.
*/
class PointToPointTopology {
public:
// Manage point to point links
// Add a full-duplex point-to-point link between two nodes
// with the specified IP addresses, with specified maximum transmission rate
// and propagation delay.
/**
* Add a full-duplex point-to-point link between two nodes
* with the specified IP addresses, with specified maximum transmission rate
* and propagation delay.
*/
static PointToPointChannel* AddPointToPointLink(
Node*, const Ipv4Address&,
Node*, const Ipv4Address&,
const DataRate&,
const Time&);
// Get the connecting node n1 to node n2
/**
* Get the connecting node n1 to node n2
*/
static PointToPointChannel* GetChannel(Node*, Node*);
// Get the NetDevice connecting node n1 to n2
/**
* Get the NetDevice connecting node n1 to n2
*/
static PointToPointNetDevice* GetNetDevice(Node*, Node*);
/// Get the queue associated with a link between two nodes
/**
* Get the queue associated with a link between two nodes
*/
static Queue* GetQueue(Node*, Node*);
// Set the queue associated with a link between two nodes
/**
* Set the queue associated with a link between two nodes
*/
static Queue* SetQueue(Node*, Node*, const Queue&);
};

View File

@ -28,6 +28,13 @@ namespace ns3 {
class Node;
/**
* \brief an Ipv4 Interface which uses ARP
*
* If you need to use ARP on top of a specific NetDevice, you
* can use this Ipv4Interface subclass to wrap it for the Ipv4 class
* when calling Ipv4::AddInterface.
*/
class ArpIpv4Interface : public Ipv4Interface
{
public:

View File

@ -45,7 +45,18 @@ public:
void SetName(std::string);
std::string GetName(void);
/**
* \returns the number of NetDevices connected to this Channel.
*
* This method must be implemented by subclasses.
*/
virtual uint32_t GetNDevices (void) const = 0;
/**
* \param i index of NetDevice to retrieve
* \returns one of the NetDevices connected to this channel.
*
* This method must be implemented by subclasses.
*/
virtual NetDevice *GetDevice (uint32_t i) const = 0;
protected:

View File

@ -53,7 +53,7 @@ public:
* bind this socket to this port number on all
* interfaces of this system.
*
* return 0 on success, -1 on failure.
* \returns 0 on success, -1 on failure.
*/
int Bind (void);
/**
@ -61,7 +61,8 @@ public:
* bind this socket to this port number on the
* specified interface.
*
* return 0 on success, -1 on failure.
* \param address address of interface to bind to.
* \returns 0 on success, -1 on failure.
*/
int Bind (Ipv4Address address);
@ -69,7 +70,8 @@ public:
* Bind this socket to this port number
* on all interfaces of this system.
*
* return 0 on success, -1 on failure.
* \param port port to bind to on all interfaces
* \returns 0 on success, -1 on failure.
*/
int Bind (uint16_t port);
@ -77,37 +79,66 @@ public:
* Bind this socket to this port number
* on the interface specified by address.
*
* return 0 on success, -1 on failure.
* \param address address of interface to bind to.
* \param port port to bind to on specified interface
* \returns 0 on success, -1 on failure.
*/
int Bind (Ipv4Address address, uint16_t port);
/**
* \param daddr destination address
* \param dport destination port
*
* Set the default destination address and port
* number for all packets outgoing from this socket.
*/
void SetDefaultDestination (Ipv4Address daddr, uint16_t dport);
/**
* \param size size of dummy data to send.
*
* Send dummy data to default destination
*/
void SendDummy (uint32_t size);
/**
* Send dummy data to specified destination
* \param size size of dummy data to send
* \param daddr destination address of dummy data
* \param dport destination port of dummy data
*
* Send dummy data to specified destination, ignore any default
* destination specified with DatagramSocket::SetDefaultDestination
*/
void SendDummyTo (uint32_t size, Ipv4Address daddr, uint16_t dport);
/**
* \param buffer data buffer to send
* \param size size of data buffer to send
*/
void Send (uint8_t const*buffer, uint32_t size);
/**
* \param buffer data buffer to send
* \param size size of data buffer to send
* \param daddr destination address
* \param dport destination port
*
* Send data to specified destination, ignore any default
* destination specified with DatagramSocket::SetDefaultDestination
*/
void SendTo (uint8_t const*buffer, uint32_t size,
Ipv4Address daddr, uint16_t dport);
/**
* \param cb callback to invoke
*
* When a packet is received by this socket, it invokes the "dummy callback" which
* forwards to the application the number of bytes received and from who they
* were received.
*/
void SetDummyRxCallback (Callback<void,DatagramSocket*,uint32_t,Ipv4Address,uint16_t> cb);
/**
* \param cb callback to invoke
*
* When a packet is received by this socket, it invokes the "normal callback" which
* forwards to the application the buffer of bytes received and from who they
* were received. The application is responsible for copying that buffer if it wants
@ -115,7 +146,7 @@ public:
*/
void SetRxCallback (Callback<void,DatagramSocket*,uint8_t const*,uint32_t,Ipv4Address,uint16_t> cb);
/**
* Return pointer to node
* \returns pointer to node
*/
Node* GetNode(void) const;

View File

@ -51,32 +51,70 @@ class TraceContext;
* subclass typically contains the Ipv4 <-> MAC address
* translation logic which will use most of the time the
* ARP/RARP protocols.
*
* By default, Ipv4 interface are created in the "down" state
* with ip address 192.168.0.1 and a matching mask. Before
* becoming useable, the user must invoke SetUp on them
* once the final Ipv4 address and mask has been set.
*
* Subclasses must implement the two methods:
* - Ipv4Interface::SendTo
* - Ipv4Interface::DoCreateTraceResolver
*/
class Ipv4Interface
{
public:
/**
* By default, Ipv4 interface are created in the "down" state
* with ip address 192.168.0.1 and a matching mask. Before
* becoming useable, the user must invoke SetUp on them
* once the final Ipv4 address and mask has been set.
* \param nd the NetDevice associated to this Ipv4Interface.
* This value can be zero in which case the MTU
* of this interface will be 2^(16-1).
*/
Ipv4Interface (NetDevice *nd);
virtual ~Ipv4Interface();
/**
* \param context the trace context to use to construct the
* TraceResolver to return
* \returns a TraceResolver which can resolve all traces
* performed in this object. The caller must
* delete the returned object.
*
* This method will delegate the work to the private DoCreateTraceResolver
* method which is supposed to be implemented by subclasses.
*/
TraceResolver *CreateTraceResolver (TraceContext const &context);
/**
* \returns the underlying NetDevice. This method can return
* zero if this interface has no associated NetDevice.
*/
NetDevice *GetDevice (void) const;
/**
* \param a set the ipv4 address of this interface.
*/
void SetAddress (Ipv4Address a);
/**
* \param mask set the ipv4 netmask of this interface.
*/
void SetNetworkMask (Ipv4Mask mask);
/**
* \returns the broadcast ipv4 address associated to this interface
*/
Ipv4Address GetBroadcast (void) const;
/**
* \returns the ipv4 netmask of this interface
*/
Ipv4Mask GetNetworkMask (void) const;
/**
* \returns the ipv4 address of this interface
*/
Ipv4Address GetAddress (void) const;
/**
* This function a pass-through to NetDevice GetMtu, modulo
* the LLC/SNAP header i.e., ipv4MTU = NetDeviceMtu - LLCSNAPSIZE
* \returns the Maximum Transmission Unit associated to this interface.
*/
uint16_t GetMtu (void) const;
@ -85,14 +123,29 @@ public:
* NetDevice states, such as found in real implementations
* (where the device may be down but IP interface state is still up).
*/
/**
* \returns true if this interface is enabled, false otherwise.
*/
bool IsUp (void) const;
/**
* \returns true if this interface is disabled, false otherwise.
*/
bool IsDown (void) const;
/**
* Enable this interface
*/
void SetUp (void);
/**
* Disable this interface
*/
void SetDown (void);
/**
* Packet typically received from above will require some
* handling before calling SendTo()
* \param p packet to send
* \param dest next hop address of packet.
*
* This method will eventually call the private
* SendTo method which must be implemented by subclasses.
*/
void Send(Packet p, Ipv4Address dest);

View File

@ -35,16 +35,57 @@ class Node;
class TraceResolver;
class TraceContext;
/**
* \brief L4 Ipv4 Demux
*/
class Ipv4L4Demux {
public:
typedef int Ipv4L4ProtocolTraceType;
Ipv4L4Demux (Node *node);
virtual ~Ipv4L4Demux();
/**
* \param node the node on which the returned copy will run.
* \returns a deep copy of this L4 Demux.
*/
Ipv4L4Demux* Copy(Node *node) const;
/**
* \param context the trace context to use to construct the
* TraceResolver to return
* \returns a TraceResolver which can resolve all traces
* performed in this object. The caller must
* delete the returned object.
*/
TraceResolver *CreateTraceResolver (TraceContext const &context);
Ipv4L4Protocol* Insert(const Ipv4L4Protocol&);
/**
* \param protocol a template for the protocol to add to this L4 Demux.
* \returns the L4Protocol effectively added.
*
* Invoke Copy on the input template to get a copy of the input
* protocol which can be used on the Node on which this L4 Demux
* is running. The new L4Protocol is registered internally as
* a working L4 Protocol and returned from this method.
* The caller does not get ownership of the returned pointer.
*/
Ipv4L4Protocol* Insert(const Ipv4L4Protocol&protocol);
/**
* \param protocolNumber number of protocol to lookup
* in this L4 Demux
* \returns a matching L4 Protocol
*
* This method is typically called by lower layers
* to forward packets up the stack to the right protocol.
* It is also called from InternetNode::GetUdp for example.
*/
Ipv4L4Protocol* Lookup(int protocolNumber);
void Erase(Ipv4L4Protocol*);
/**
* \param protocol protocol to remove from this demux.
*
* The input value to this method should be the value
* returned from the Ipv4L4Protocol::Insert method.
*/
void Erase(Ipv4L4Protocol*protocol);
private:
typedef std::list<Ipv4L4Protocol*> L4List_t;
L4List_t m_protocols;

View File

@ -33,18 +33,45 @@ class Packet;
class Ipv4Address;
class TraceResolver;
class TraceContext;
/**
* \brief L4 Protocol base class
*
* All subclasses must implement:
* - Ipv4L4Protocol::Copy
* - Ipv4L4Protocol::CreateTraceResolver
*
* If you want to implement a new L4 protocol, all you have to do is
* implement a subclass of this base class and add it to an L4Demux.
*/
class Ipv4L4Protocol {
public:
Ipv4L4Protocol(int protocolNumber, int version);
virtual ~Ipv4L4Protocol ();
/**
* \returns the protocol number of this protocol.
*/
int GetProtocolNumber (void) const;
/**
* \returns the version number of this protocol.
*/
int GetVersion() const;
/**
* \param node the node on which the copy should be running
* \returns a new instance of this L4 Protocol.
*
* Perform a deep copy of the L4 Protocol
*/
virtual Ipv4L4Protocol* Copy(Node *node) const = 0;
virtual TraceResolver *CreateTraceResolver (TraceContext const &context) = 0;
/**
* \param p packet to forward up
* \param source source address of packet received
* \param destination address of packet received
*
* Called from lower-level layers to send the packet up
* in the stack.
*/

View File

@ -27,40 +27,8 @@
namespace ns3 {
class Ipv4DummyNetDevice : public NetDevice
{
public:
Ipv4DummyNetDevice (Node *node);
Node *PeekNode (void) const;
private:
virtual bool SendTo (Packet& p, const MacAddress& dest);
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
};
Ipv4DummyNetDevice::Ipv4DummyNetDevice (Node *node)
: NetDevice (node, MacAddress ())
{
SetMtu (10000);
}
Node *
Ipv4DummyNetDevice::PeekNode (void) const
{
return GetNode ();
}
bool
Ipv4DummyNetDevice::SendTo (Packet& p, const MacAddress& dest)
{
return false;
}
TraceResolver *
Ipv4DummyNetDevice::DoCreateTraceResolver (TraceContext const &context)
{
return new EmptyTraceResolver (context);
}
Ipv4LoopbackInterface::Ipv4LoopbackInterface (Node *node)
: Ipv4Interface (new Ipv4DummyNetDevice (node)),
: Ipv4Interface (0),
m_node (node)
{
}

View File

@ -61,52 +61,131 @@ public:
Ipv4(Node *node);
virtual ~Ipv4 ();
/**
* \param context the trace context to use to construct the
* TraceResolver to return
* \returns a TraceResolver which can resolve all traces
* performed in this object. The caller must
* delete the returned object.
*/
virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
/**
* \param ttl default ttl to use
*
* When we need to send an ipv4 packet, we use this default
* ttl value.
*/
void SetDefaultTtl (uint8_t ttl);
/* add route to host dest through host nextHop
/**
* \param dest destination address
* \param nextHop address of next hop.
* \param interface interface of next hop.
*
* add route to host dest through host nextHop
* on interface.
*/
void AddHostRouteTo (Ipv4Address dest,
Ipv4Address nextHop,
uint32_t interface);
/* add route to host dest on interface.
/**
* \param dest destination address
* \param interface of next hop
*
* add route to host dest on interface.
*/
void AddHostRouteTo (Ipv4Address dest,
uint32_t interface);
/* add route to network dest with netmask
/**
* \param network destination network
* \param networkMask netmask of destination network
* \param nextHop address of next hop
* \param interface interface of next hop
*
* add route to network dest with netmask
* through host nextHop on interface
*/
void AddNetworkRouteTo (Ipv4Address network,
Ipv4Mask networkMask,
Ipv4Address nextHop,
uint32_t interface);
/* add route to network dest with netmask
/**
* \param network destination network
* \param networkMask netmask of destination network
* \param interface interface of next hop
*
* add route to network dest with netmask
* on interface
*/
void AddNetworkRouteTo (Ipv4Address network,
Ipv4Mask networkMask,
uint32_t interface);
/* set the default route to host nextHop on
/**
* \param nextHop address of default next hop
* \param interface interface of default next hop.
*
* set the default route to host nextHop on
* interface.
*/
void SetDefaultRoute (Ipv4Address nextHop,
uint32_t interface);
/**
* \param dest destination address
* \returns the route to the destination address
*
* Lookup the route for this destination address.
*/
Ipv4Route *Lookup (Ipv4Address dest);
/**
* \returns the number of entries in the routing table.
*/
uint32_t GetNRoutes (void);
/**
* \param i index of route to return
* \returns the route whose index is i
*/
Ipv4Route *GetRoute (uint32_t i);
/**
* \param i index of route to remove from routing table.
*/
void RemoveRoute (uint32_t i);
/**
* \param interface interface to add to the list of ipv4 interfaces
* which can be used as output interfaces during packet forwarding.
* \returns the index of the interface added.
*
* Once an interface has been added, it can never be removed: if you want
* to disable it, you can invoke Ipv4Interface::SetDown which will
* make sure that it is never used during packet forwarding.
*/
uint32_t AddInterface (Ipv4Interface *interface);
/**
* \param i index of interface to return
* \returns the requested interface
*/
Ipv4Interface * GetInterface (uint32_t i);
/**
* \returns the number of interfaces added by the user.
*/
uint32_t GetNInterfaces (void);
/**
* \param device the device to match
* \returns the matching interface, zero if not found.
*
* Try to find an Ipv4Interface whose NetDevice is equal to
* the input NetDevice.
*/
Ipv4Interface *FindInterfaceForDevice (NetDevice const*device);
virtual Ipv4* Copy(Node *node) const;
/**
* Lower layer calls this method after calling L3Demux::Lookup
* The ARP subclass needs to know from which NetDevice this
@ -116,6 +195,15 @@ public:
*/
virtual void Receive(Packet& p, NetDevice &device);
/**
* \param packet packet to send
* \param source source address of packet
* \param destination address of packet
* \param protocol number of packet
*
* Higher-level layers call this method to send a packet
* down the stack to the MAC and PHY layers.
*/
void Send (Packet const &packet, Ipv4Address source,
Ipv4Address destination, uint8_t protocol);

View File

@ -36,22 +36,60 @@ class Node;
class TraceResolver;
class TraceContext;
/**
* \brief L3 Demux
*/
class L3Demux
{
public:
typedef int ProtocolTraceType;
L3Demux(Node *node);
virtual ~L3Demux();
/**
* \param node the node on which the returned copy will run.
* \returns a deep copy of this L3 Demux.
*/
L3Demux* Copy(Node *node) const;
/**
* \param context the trace context to use to construct the
* TraceResolver to return
* \returns a TraceResolver which can resolve all traces
* performed in this object. The caller must
* delete the returned object.
*/
TraceResolver *CreateTraceResolver (TraceContext const &context);
// Insert a new protocol
ns3::L3Protocol* Insert(const ns3::L3Protocol&);
// Look up a protocol by protocol number
ns3::L3Protocol* Lookup(int);
// Erase an entry
void Erase(ns3::L3Protocol*);
/**
* \param protocol a template for the protocol to add to this L3 Demux.
* \returns the L3Protocol effectively added.
*
* Invoke Copy on the input template to get a copy of the input
* protocol which can be used on the Node on which this L3 Demux
* is running. The new L3Protocol is registered internally as
* a working L3 Protocol and returned from this method.
* The caller does not get ownership of the returned pointer.
*/
ns3::L3Protocol* Insert(const ns3::L3Protocol& protocol);
/**
* \param protocolNumber number of protocol to lookup
* in this L4 Demux
* \returns a matching L3 Protocol
*
* This method is typically called by lower layers
* to forward packets up the stack to the right protocol.
* It is also called from InternetNode::GetIpv4 for example.
*/
ns3::L3Protocol* Lookup(int protocolNumber);
/**
* \param protocol protocol to remove from this demux.
*
* The input value to this method should be the value
* returned from the L3Protocol::Insert method.
*/
void Erase(ns3::L3Protocol*protocol);
private:
typedef std::map<int, ns3::L3Protocol*> L3Map_t;

View File

@ -169,6 +169,12 @@ NetDevice::CreateTraceResolver (TraceContext const &context)
return DoCreateTraceResolver (context);
}
Channel *
NetDevice::GetChannel (void) const
{
return DoGetChannel ();
}
// Receive packet from below
bool
NetDevice::ForwardUp (Packet& packet)

View File

@ -29,10 +29,10 @@
namespace ns3 {
class Ipv4L4Demux;
class Node;
class TraceResolver;
class TraceContext;
class Channel;
/**
* \brief Network layer to device interface
@ -57,12 +57,27 @@ class NetDevice {
public:
/**
* \param node base class node pointer of device's node
* \param addr MAC address of this device.
*/
NetDevice(Node* node, const MacAddress& addr);
virtual ~NetDevice() {}
/**
* \param context the trace context to use to construct the
* TraceResolver to return
* \returns a TraceResolver which can resolve all traces
* performed in this object. The caller must
* delete the returned object.
*/
TraceResolver *CreateTraceResolver (TraceContext const &context);
/**
* \return the channel this NetDevice is connected to. The value
* returned can be zero if the NetDevice is not yet connected
* to any channel.
*/
Channel *GetChannel (void) const;
/**
* \return the current MacAddress of this interface.
*/
@ -186,7 +201,6 @@ class NetDevice {
/**
* \param p packet sent from below up to Network Device
* \param from source mac address of the sender
* \returns true if the packet was forwarded successfully,
* false otherwise.
*
@ -210,6 +224,7 @@ class NetDevice {
virtual bool SendTo (Packet& p, const MacAddress& dest) = 0;
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
virtual Channel *DoGetChannel (void) const = 0;
Node* m_node;
std::string m_name;
uint16_t m_ifIndex;

View File

@ -53,6 +53,7 @@ NodeList::GetNodes (void)
if (firstTime)
{
TraceRoot::Register ("nodes", MakeCallback (&NodeList::CreateTraceResolver));
firstTime = false;
}
static std::vector<Node *> nodes;
return &nodes;