merge with trunk
commit
207976b5fe
|
@ -0,0 +1 @@
|
|||
56928998e05c9c11f5f3aefe79be8d2843e0db88 release ns-3.0.1
|
6
AUTHORS
6
AUTHORS
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
2
README
|
@ -1,3 +1,5 @@
|
|||
ns-3 uses the Mercurial software revision control system
|
||||
|
||||
Mercurial cheat sheet
|
||||
|
||||
clone this repository:
|
||||
|
|
|
@ -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)
|
|
@ -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',
|
||||
|
|
|
@ -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
|
||||
|
|
26
doc/main.txt
26
doc/main.txt
|
@ -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
|
||||
*/
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
|
@ -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 */
|
|
@ -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"
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#define ASSERT_H
|
||||
|
||||
/**
|
||||
* \defgroup assert
|
||||
* \defgroup assert Assert
|
||||
* \brief assert functions and macros
|
||||
*
|
||||
* The assert macros are used to verify
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#define DEBUG_H
|
||||
|
||||
/**
|
||||
* \defgroup debugging
|
||||
* \defgroup debugging Debugging
|
||||
* \brief Debugging functions and macros
|
||||
*
|
||||
* - DEBUG functionality: macros which allow developers to
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define FATAL_ERROR_H
|
||||
|
||||
#include "assert.h"
|
||||
#include <iostream>
|
||||
|
||||
/**
|
||||
* \defgroup error Error
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) { }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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&);
|
||||
};
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -53,6 +53,7 @@ NodeList::GetNodes (void)
|
|||
if (firstTime)
|
||||
{
|
||||
TraceRoot::Register ("nodes", MakeCallback (&NodeList::CreateTraceResolver));
|
||||
firstTime = false;
|
||||
}
|
||||
static std::vector<Node *> nodes;
|
||||
return &nodes;
|
||||
|
|
Loading…
Reference in New Issue