--- a/.hgignore Thu Sep 06 15:18:14 2007 +0100
+++ b/.hgignore Tue Sep 11 14:52:15 2007 +0100
@@ -1,11 +1,10 @@
-.*.orig$
-.*\.o$
-.*~$
-build-dir
-build
-.*\.sconsign
-doc/html.*
-doc/latex.*
-.lock-wscript
-.waf*
-waf
+\.rej$
+\.orig$
+\.o$
+~$
+^build-dir
+^build
+^doc/html
+^doc/latex
+^\.lock-wscript
+^\.waf
--- a/doc/doxygen.conf Thu Sep 06 15:18:14 2007 +0100
+++ b/doc/doxygen.conf Tue Sep 11 14:52:15 2007 +0100
@@ -450,7 +450,7 @@
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = src doc/main.txt
+INPUT = src doc/main.txt doc/trace-source-list.h doc/tracing.h
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
@@ -517,7 +517,7 @@
# directories that contain image that are included in the documentation (see
# the \image command).
-IMAGE_PATH =
+IMAGE_PATH = doc
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
--- a/doc/main.txt Thu Sep 06 15:18:14 2007 +0100
+++ b/doc/main.txt Tue Sep 11 14:52:15 2007 +0100
@@ -23,6 +23,7 @@
* - \ref config
* - a base class for objects which need to support reference counting
* and QueryInterface: ns3::Object and ns3::InterfaceId
+ * - a set of low-level trace facilities integrated in the ns3::Object system: \ref tracing
* - a ns3::ComponentManager which can be used to manage the creation
* of any object which derives from ns3::Object through an ns3::ClassId
* - a smart-pointer class ns3::Ptr designed to work together with ns3::Object
@@ -33,11 +34,10 @@
* ns3::Scheduler and ns3::SchedulerFactory
* - a simulator class used to create, schedule and cancel events: ns3::Simulator
*
- * The "common" module contains:
+ * The "core" module contains:
* - a packet class to create and manipulate simulation packets: ns3::Packet, ns3::Header,
* and ns3::Trailer. This packet class also supports per-packet ns3::Tag which are
* globs of data which can be attached to any packet.
- * - a set of low-level trace facilities: \ref lowleveltracing
*
* The "node" module contains:
* - a ns3::Node base class which should be subclassed by any new type of
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/namespace-2.dia Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,1658 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
+ <dia:diagramdata>
+ <dia:attribute name="background">
+ <dia:color val="#ffffff"/>
+ </dia:attribute>
+ <dia:attribute name="pagebreak">
+ <dia:color val="#000099"/>
+ </dia:attribute>
+ <dia:attribute name="paper">
+ <dia:composite type="paper">
+ <dia:attribute name="name">
+ <dia:string>#A4#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="tmargin">
+ <dia:real val="2.8222000598907471"/>
+ </dia:attribute>
+ <dia:attribute name="bmargin">
+ <dia:real val="2.8222000598907471"/>
+ </dia:attribute>
+ <dia:attribute name="lmargin">
+ <dia:real val="2.8222000598907471"/>
+ </dia:attribute>
+ <dia:attribute name="rmargin">
+ <dia:real val="2.8222000598907471"/>
+ </dia:attribute>
+ <dia:attribute name="is_portrait">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="scaling">
+ <dia:real val="1.0929253101348877"/>
+ </dia:attribute>
+ <dia:attribute name="fitto">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="fitwidth">
+ <dia:int val="2"/>
+ </dia:attribute>
+ <dia:attribute name="fitheight">
+ <dia:int val="2"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ <dia:attribute name="grid">
+ <dia:composite type="grid">
+ <dia:attribute name="width_x">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="width_y">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="visible_x">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="visible_y">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:composite type="color"/>
+ </dia:composite>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#d8e5e5"/>
+ </dia:attribute>
+ <dia:attribute name="guides">
+ <dia:composite type="guides">
+ <dia:attribute name="hguides"/>
+ <dia:attribute name="vguides"/>
+ </dia:composite>
+ </dia:attribute>
+ </dia:diagramdata>
+ <dia:layer name="Background" visible="true">
+ <dia:object type="Flowchart - Box" version="0" id="O0">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-1,-27"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-1.05,-27.05;6.05,-24.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-1,-27"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="7"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/devices/[0-n]#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-0.65,-25.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O1">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-8,-39"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-8.05,-39.05;-0.95,-36.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-8,-39"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="7"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="inner_color">
+ <dia:color val="#e6c7c7"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#NodeList#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-4.5,-37.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O2">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-1,-29"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-1.05,-29.05;6.05,-26.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-1,-29"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="7"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="inner_color">
+ <dia:color val="#e6c7c7"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Node#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="2.5,-27.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O3">
+ <dia:attribute name="obj_pos">
+ <dia:point val="3,-16"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="2.95,-16.05;7.05,-13.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="3,-16"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="4"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/queue#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="3.35,-14.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O4">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-8,-37"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-8.05,-37.05;-0.95,-34.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-8,-37"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="7"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/nodes/[0-n]#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-7.65,-35.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O5">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-8,-31"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-8.05,-31.05;-3.95,-28.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-8,-31"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="4"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/udp#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-7.65,-29.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O6">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-16,-25"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-16.05,-25.05;-13.95,-22.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-16,-25"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/rx#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-15.65,-23.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O7">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-17,-19"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-17.05,-19.05;-9.95,-16.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-17,-19"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="7"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/netdevice#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-16.65,-17.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O8">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-4.5,-35"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-4.55754,-35.0575;3,-28.95"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="-4.5,-35"/>
+ <dia:point val="-4,-32"/>
+ <dia:point val="2.5,-31"/>
+ <dia:point val="2.5,-29"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O4" connection="13"/>
+ <dia:connection handle="3" to="O2" connection="2"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O9">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-4.5,-35"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-8.00142,-35.0606;-4.43937,-32.8685"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="-4.5,-35"/>
+ <dia:point val="-5,-33"/>
+ <dia:point val="-7,-36"/>
+ <dia:point val="-7.5,-33"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O4" connection="13"/>
+ <dia:connection handle="3" to="O18" connection="2"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O10">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-11,-31"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-11.05,-31.05;-7.95,-28.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-11,-31"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="3"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/ipv4#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-10.65,-29.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O11">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-14,-25"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-14.05,-25.05;-6.95,-22.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-14,-25"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="7"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/interfaces/[0-n]#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-13.65,-23.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O12">
+ <dia:attribute name="obj_pos">
+ <dia:point val="7,-16"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="6.95,-16.05;11.05,-13.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="7,-16"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="4"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/rx#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="7.35,-14.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O13">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-8,-16"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-8.05,-16.05;-3.95,-13.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-8,-16"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="4"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/queue#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-7.65,-14.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O14">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-4,-16"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-4.05,-16.05;2.05,-13.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-4,-16"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="6"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/rx#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-3.65,-14.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O15">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-7,-9"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-7.05,-9.05;-1.95,-6.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-7,-9"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="5"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/enqueue#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-6.65,-7.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O16">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-7,-7"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-7.05,-7.05;-1.95,-4.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-7,-7"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="5"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/dequeue#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-6.65,-5.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O17">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-7,-5"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-7.05,-5.05;-1.95,-2.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-7,-5"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="5"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/drop#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-6.65,-3.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O18">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-11,-33"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-11.05,-33.05;-3.95,-30.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-11,-33"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="7"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="inner_color">
+ <dia:color val="#e6c7c7"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#InternetNode#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-7.5,-31.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O19">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-8,-18"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-8.05,-18.05;2.05,-15.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-8,-18"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="10"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2.0000000000000018"/>
+ </dia:attribute>
+ <dia:attribute name="inner_color">
+ <dia:color val="#e6c7c7"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#PointToPointNetDevice#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-3,-16.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O20">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-7,-11"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-7.05,-11.05;-1.95,-8.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-7,-11"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="5"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="inner_color">
+ <dia:color val="#e6c7c7"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Queue#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-4.5,-9.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O21">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-16,-27"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-16.05,-27.05;-6.95,-24.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-16,-27"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="9"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="inner_color">
+ <dia:color val="#e6c7c7"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Ipv4L3Protocol#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-11.5,-25.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O22">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-17,-21"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-17.05,-21.05;-9.95,-18.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="-17,-21"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="7"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="inner_color">
+ <dia:color val="#e6c7c7"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Ipv4Interface#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="-13.5,-19.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O23">
+ <dia:attribute name="obj_pos">
+ <dia:point val="3,-18"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="2.95,-18.05;11.05,-15.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="3,-18"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="8.0000000000000071"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="inner_color">
+ <dia:color val="#e6c7c7"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#CsmaNetDevice#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="7,-16.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O24">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-9.5,-29"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-12,-29.0606;-9.38388,-26.95"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="-9.5,-29"/>
+ <dia:point val="-9,-27"/>
+ <dia:point val="-11.5,-29"/>
+ <dia:point val="-11.5,-27"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O10" connection="13"/>
+ <dia:connection handle="3" to="O21" connection="2"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O25">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-10.5,-23"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-13.9972,-23.0606;-10.4066,-20.8302"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="-10.5,-23"/>
+ <dia:point val="-10,-21"/>
+ <dia:point val="-14,-23"/>
+ <dia:point val="-13.5,-21"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O11" connection="13"/>
+ <dia:connection handle="3" to="O22" connection="2"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O26">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-6,-14"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-6.05,-14.05;-4.0028,-10.8302"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="-6,-14"/>
+ <dia:point val="-6,-11"/>
+ <dia:point val="-5,-13"/>
+ <dia:point val="-4.5,-11"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O13" connection="13"/>
+ <dia:connection handle="3" to="O20" connection="2"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O27">
+ <dia:attribute name="obj_pos">
+ <dia:point val="5,-14"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="4.95,-14.05;7,-10.95"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="5,-14"/>
+ <dia:point val="5,-12"/>
+ <dia:point val="6.5,-13"/>
+ <dia:point val="6.5,-11"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O3" connection="13"/>
+ <dia:connection handle="3" to="O33" connection="2"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O28">
+ <dia:attribute name="obj_pos">
+ <dia:point val="2.5,-25"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-3.5,-25.05;2.55,-17.95"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="2.5,-25"/>
+ <dia:point val="2.5,-23"/>
+ <dia:point val="-3,-20"/>
+ <dia:point val="-3,-18"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O0" connection="13"/>
+ <dia:connection handle="3" to="O19" connection="2"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O29">
+ <dia:attribute name="obj_pos">
+ <dia:point val="2.5,-25"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="2.45,-25.05;7.5,-17.95"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="2.5,-25"/>
+ <dia:point val="2.5,-23"/>
+ <dia:point val="7,-20"/>
+ <dia:point val="7,-18"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O0" connection="13"/>
+ <dia:connection handle="3" to="O23" connection="2"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O30">
+ <dia:attribute name="obj_pos">
+ <dia:point val="4,-9"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="3.95,-9.05;9.05,-6.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="4,-9"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="5"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/enqueue#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="4.35,-7.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O31">
+ <dia:attribute name="obj_pos">
+ <dia:point val="4,-7"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="3.95,-7.05;9.05,-4.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="4,-7"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="5"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/dequeue#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="4.35,-5.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O32">
+ <dia:attribute name="obj_pos">
+ <dia:point val="4,-5"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="3.95,-5.05;9.05,-2.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="4,-5"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="5"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#/drop#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="4.35,-3.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O33">
+ <dia:attribute name="obj_pos">
+ <dia:point val="4,-11"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="3.95,-11.05;9.05,-8.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="4,-11"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="5"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="inner_color">
+ <dia:color val="#e6c7c7"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="corner_radius">
+ <dia:real val="0.40000000000000002"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.10000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Queue#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font family="sans" style="0" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="1.1000000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="6.5,-9.75"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O34">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-10,-18"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-10.0693,-20.6883;-5.0028,-17.8302"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="-10,-18"/>
+ <dia:point val="-8,-21"/>
+ <dia:point val="-6.5,-22"/>
+ <dia:point val="-5.5,-18"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O7" connection="8"/>
+ <dia:connection handle="3" to="O19" connection="1"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - BezierLine" version="0" id="O35">
+ <dia:attribute name="obj_pos">
+ <dia:point val="-10,-18"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-10.0702,-22.2491;5.4972,-17.8302"/>
+ </dia:attribute>
+ <dia:attribute name="bez_points">
+ <dia:point val="-10,-18"/>
+ <dia:point val="-1,-25"/>
+ <dia:point val="4,-22"/>
+ <dia:point val="5,-18"/>
+ </dia:attribute>
+ <dia:attribute name="corner_types">
+ <dia:enum val="0"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="22"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O7" connection="8"/>
+ <dia:connection handle="3" to="O23" connection="1"/>
+ </dia:connections>
+ </dia:object>
+ </dia:layer>
+</dia:diagram>
Binary file doc/namespace-2.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/trace-source-list.h Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,204 @@
+///
+/// \ingroup TraceSourceList
+/// \brief send ipv4 packet to outgoing interface
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet sent.
+/// \param arg3 index of output ipv4 interface.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/ipv4/tx.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback0 (const TraceContext & arg1, const Packet & arg2, uint32_t arg3);
+
+///
+/// \ingroup TraceSourceList
+/// \brief receive ipv4 packet from incoming interface
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet received.
+/// \param arg3 index of input ipv4 interface.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/ipv4/rx.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback1 (const TraceContext & arg1, const Packet & arg2, uint32_t arg3);
+
+///
+/// \ingroup TraceSourceList
+/// \brief drop ipv4 packet
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet dropped.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/ipv4/drop.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback2 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief store packet in queue
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet queued.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/queue/enqueue.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::NodeNetDeviceIndex
+/// - ns3::QueueTraceType
+void TraceSinkCallback3 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief remove packet from queue
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet dequeued.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/queue/dequeue.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::NodeNetDeviceIndex
+/// - ns3::QueueTraceType
+void TraceSinkCallback4 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief drop packet from queue
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet dropped.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/queue/drop.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::NodeNetDeviceIndex
+/// - ns3::QueueTraceType
+void TraceSinkCallback5 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief receive MAC packet
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet received.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/rx.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::NodeNetDeviceIndex
+/// - ns3::PointToPointTraceType
+void TraceSinkCallback6 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief receive MAC packet
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet received.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/rx.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::NodeNetDeviceIndex
+/// - ns3::CsmaTraceType
+void TraceSinkCallback7 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief drop MAC packet
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet dropped.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/drop.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::NodeNetDeviceIndex
+/// - ns3::CsmaTraceType
+void TraceSinkCallback8 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief The value of the speed vector changed
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 the mobility model whose course changed.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/$MobilityModelNotifier/course-change.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+void TraceSinkCallback9 (const TraceContext & arg1, Ptr<const MobilityModel> arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief send ipv4 packet to outgoing interface
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet sent.
+/// \param arg3 index of output ipv4 interface.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/$Ipv4L3Protocol/tx.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback10 (const TraceContext & arg1, const Packet & arg2, uint32_t arg3);
+
+///
+/// \ingroup TraceSourceList
+/// \brief receive ipv4 packet from incoming interface
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet received.
+/// \param arg3 index of input ipv4 interface.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/$Ipv4L3Protocol/rx.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback11 (const TraceContext & arg1, const Packet & arg2, uint32_t arg3);
+
+///
+/// \ingroup TraceSourceList
+/// \brief drop ipv4 packet
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet dropped.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/$Ipv4L3Protocol/drop.
+///
+/// The following classes can be extracted from \p arg1 with
+/// ns3::TraceContext::GetElement:
+/// - ns3::NodeListIndex
+/// - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback12 (const TraceContext & arg1, const Packet & arg2);
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tracing.h Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,576 @@
+/**
+ * \defgroup TraceSourceList List of trace sources
+ */
+
+/**
+ * \defgroup tracing Tracing
+ *
+ * The flexibility of the ns-3 tracing system comes at the cost of quite
+ * a bit of complexity so, before trying to use the low-level aspects
+ * of the tracing API, it is important to focus on some basic definitions:
+ *
+ * - A trace source is an object instance which can report trace events
+ * to a set of listening trace sinks.
+ *
+ * - A trace sink is a user-provided callback (a function) which can
+ * be connected to a set of trace sources to receive the events generated
+ * by each trace source.
+ *
+ * - A trace resolver is an object which allows users to establish
+ * connections between a set of trace sources and a set of trace sinks.
+ *
+ * \section TraceSource Generating Trace Events
+ *
+ * So, what does it look like in practice ? First, let's look at trace
+ * sources. We have two types of trace sources: numeric, and, normal
+ * trace sources. Numeric trace sources behave as normal c++ integers
+ * or c++ floating point numbers except that they report as trace events
+ * each change of their value. For example:
+ * \code
+ * class MyModel
+ * {
+ * public:
+ * void DoSomething (void)
+ * {
+ * // use the "int" trace source just
+ * // like any other "int" variable.
+ * m_cwnd *= 2;
+ * m_cwnd += 4;
+ * if (m_cwnd > 100)
+ * {
+ * // do something.
+ * }
+ * }
+ * private:
+ * // declare an instance of a "int" trace source
+ * SVTraceSource<int> m_cwnd;
+ * };
+ * \endcode
+ * Normal trace sources, on the other hand, allow you to trace the
+ * call of arbitrary functions and methods, as shown below. They are
+ * typically used to track "rx", "tx", or "drop" events but could
+ * also be used to track route change events, or position change
+ * events:
+ * \code
+ * class MyModel
+ * {
+ * public:
+ * void DoSomething (Packet packet)
+ * {
+ * // report this event on packet
+ * m_doSomething (packet);
+ * // do something
+ * }
+ * private:
+ * // report every "something" function call.
+ * CallbackTraceSource<Packet> m_doSomething;
+ * };
+ * \endcode
+ * Every type of trace source derives from the ns3::TraceSource base class.
+ * As of today, the set of concrete subclasses is relatively short:
+ * ns3::CallbackTraceSource, ns3::SvTraceSource, ns3::UvTraceSource, and,
+ * ns3::FvTraceSource.
+ *
+ * \section TraceSink Receiving Trace Events
+ *
+ * To receive these trace events, a user should specify a set of trace sinks.
+ * For example, to receive the "int" and the "something" events shown in the
+ * examples above, a user would declare the following functions:
+ * \code
+ * // oldValue and newValue contain the previous and new values of
+ * // the connected SVTraceSource<int> trace source.
+ * void
+ * CwndTraceSink (const TraceContext &context, int64_t oldValue, int64_t newValue)
+ * {
+ * // for example, print the new value:
+ * std::cout << "cwnd=" << newValue << std::endl;
+ * }
+ * void
+ * DoSomethingTraceSink (const TraceContext &context, Packet packet)
+ * {
+ * // for example, print the arguments
+ * std::cout << "packet " << packet << std::endl;
+ * }
+ * \endcode
+ * Each of these sink function takes, as a first argument, a reference to a
+ * const TraceContext object. This context object contains information which
+ * describes the instance of the connected trace source: that information is
+ * setup during the connection process and does not change afterwards
+ * The type and the number of the other arguments to each trace sink depends
+ * on the type of the connected trace source: it conveys per-event information
+ * from the trace source to the trace sink. For example, UVTraceSource and
+ * SVTraceSource trace sources require two extra arguments. The former requires
+ * two unsigned 64 bit integers while the latter requires two signed 64 bit
+ * integers. More generally, users can consult the \ref TraceSourceList
+ * to figure out the arguments which a trace sink is required to receive
+ * for each trace source: a signature of the user trace sink must match
+ * _exactly_ the signature documented in the \ref TraceSourceList.
+ *
+ *
+ * \section TraceSourceSimpleExport A simple way to connect Trace Sources with Trace Sinks
+ *
+ * The crux of the complexity of the ns-3 tracing system comes from its
+ * flexible system used to connect trace sources to trace sinks but what is really
+ * nice about it is that it is not necessary to use it to setup simple traces.
+ *
+ * The simplest way to export a set of trace sources to a user, for example,
+ * during the early prototyping phases of a system, is to add a set of public methods
+ * to give to your users access to the trace source object instances you use to generate
+ * trace events:
+ * \code
+ * class MyModel
+ * {
+ * public:
+ * void DoSomething (Packet packet)
+ * {
+ * // report this event on packet
+ * m_doSomething (packet);
+ * // do something
+ * }
+ * CallbackTraceSource<Packet> *PeekSomethingTraceSource (void) const
+ * {
+ * return &m_doSomething
+ * }
+ * private:
+ * // report every "something" function call.
+ * CallbackTraceSource<Packet> m_doSomething;
+ * };
+ * \endcode
+ * If your users hold a pointer to an instance of MyModel, and if they want to connect
+ * a MySomethingSink, they can simply do the following which invokes the
+ * TraceSource::AddCallback method and creates a Callback object from the user's
+ * sink with the MakeCallback function.
+ * \code
+ * void
+ * MySomethingSink (const TraceContext &context, Packet packet)
+ * {
+ * // do whatever you want.
+ * }
+ * MyModel *model = ...;
+ * CallbackTraceSource<Packet> *source = model->PeekSomethingTraceSource ();
+ * source->AddCallback (MakeCallback (&MySomethingSink));
+ * \endcode
+ *
+ * The full power of the tracing system comes however from its ns3::NodeList::Connect
+ * method which is described in the following sections.
+ *
+ * \section TraceConnection Connecting Trace Sources to Trace Sinks
+ *
+ * If a trace source is integrated in the ns-3 trace connection facility, a user
+ * should call the ns3::NodeList::Connect method to establish a connection between
+ * a trace sink and a set of matching trace sources. The second argument to that
+ * method is a callback to the user's trace sink.
+ * That callback is easy to construct: call ns3::MakeCallback and you are done. The
+ * first argument is a string whose format is similar to a unix path and which is
+ * used to uniquely identify the set of trace sources you want to connect to.
+ * The set of acceptable path strings is also documented in the \ref TraceSourceList.
+ *
+ * So, what does this look like from the perspective of a user ? If we wanted to
+ * connect to a trace source defined somewhere deep into the a set of NetDevice objects
+ * located in some nodes of the system, we could write the following:
+ * \code
+ * void
+ * DoSomethingTraceSink (const TraceContext &context, Packet packet)
+ * {
+ * // for example, print the arguments
+ * std::cout << "packet: " << packet << std::endl;
+ * }
+ * // connect the above sink to a matching trace source
+ * NodeList::Connect ("/nodes/* /devices/* /rx", MakeCallback &DoSomethingTraceSink);
+ * \endcode
+ *
+ * The connection path string "/nodes/* /devices/* /rx" matches the "rx" trace source
+ * located in every netdevice located in every node. The syntax of that path string
+ * is loosely based on regular expressions so, a user could conceivably connect
+ * to the trace sources present in only one node identified by node index:
+ * "/nodex/3/devices/* /rx".
+ *
+ * The matching algorithm used here is very useful since it allows you to connect
+ * at once a large set of trace sources to a single sink but it introduces another
+ * problem: it becomes impossible when you receive an event in your trace sink to
+ * know from _which_ trace source the event is coming from. In our example, the
+ * trace source might be coming from the NetDevice number 2 of Node 10 or Netdevice
+ * number 0 of Node 5. In both cases, you might need to know which of these NetDevice
+ * is generating this event, if only to generate some ascii trace dump. Another
+ * similar use-case is that you might have connected the same trace sink to
+ * multiple types of events which have the same signature: it is quite common
+ * to receive all tx, rx, and drop events in the same trace sink and that would be
+ * quite trivial to achieve with a string such as: "/nodes/* /devices/* /*"
+ *
+ * The source of a trace event can be retrieved from a trace sink using
+ * different means: the simplest
+ * way to get this information is to use the builtin printing facility of
+ * the TraceContext object:
+ * \code
+ * void
+ * DoSomethingTraceSink (const TraceContext &context, Packet packet)
+ * {
+ * // for example, print the arguments
+ * std::cout << "context=\"" << context << "\" packet: " << packet << std::endl;
+ * }
+ * \endcode
+ * The above code is going to generate output which looks like the following:
+ * \code
+ * context="nodeid=2 device=0 dev-rx" packet: IPV4(tos 0x0 ttl 64 id 0 offset ...
+ * context="nodeid=1 device=0 dev-rx" packet: IPV4(tos 0x0 ttl 64 id 0 offset ...
+ * ...
+ * \endcode
+ *
+ * Another more advanced way to get information out of a TraceContext is to call its
+ * ns3::TraceContext::GetElement method. This method takes as its first and only
+ * argument an instance of the object we want to read and the list of available
+ * object instances we can read from a TraceContext is documented, once again,
+ * in the \ref TraceSourceList. For example, we could write the following to
+ * generate adhoc trace output:
+ * \code
+ * void DeviceRxSink (const TraceContext &context, const Packet &packet)
+ * {
+ * NodeListIndex nodeIndex;
+ * NodeNetDeviceIndex deviceIndex;
+ * context.GetElement (nodeIndex);
+ * context.GetElement (deviceIndex);
+ * std::cout << "node-index=" << nodeIndex.Get ();
+ * std::cout << ", device-index=" << deviceIndex.Get ();
+ * std::cout << ", packet: " << packet;
+ * std::cout << std::endl;
+ * }
+ * \endcode
+ *
+ * \section ExportingTraceSources Exporting new Trace Sources
+ *
+ * Using existing trace sources to connect them to a set of adhoc trace sinks
+ * is not really complicated but, setting up new trace sources which can hook
+ * in this automatic connection system is a bit more complicated.
+ *
+ * So far, we know that a model author can generate trace events really easily:
+ * \code
+ * class MyModel
+ * {
+ * public:
+ * void DoSomething (Packet packet)
+ * {
+ * // report this event on packet with value
+ * m_doSomething (packet);
+ * // do something
+ * }
+ * private:
+ * // report every "something" function call.
+ * CallbackTraceSource<Packet> m_doSomething;
+ * };
+ * \endcode
+ *
+ * To make these new trace sources available to the rest of the connection system,
+ * the first step is to make sure that your model object derives from the ns3::Object
+ * base class either directly (as shown below) or indirectly through another base class:
+ * \code
+ * class MyModel : public Object {...};
+ * // or:
+ * class SomeOtherObject : public Object {...};
+ * class MyModel : public SomeOtherObject {...};
+ * \endcode
+ *
+ * This is pretty trivial and lays the ground for the second step: overriding the
+ * ns3::Object::GetTraceResolver method:
+ * \code
+ * class MyModel : public MyParent
+ * {
+ * public:
+ * // declare overriden method
+ * virtual Ptr<TraceResolver> GetTraceResolver (void) const;
+ * private:
+ * // the new trace source to export.
+ * CallbackTraceSource<Packet> m_rxSource;
+ * };
+ * \endcode
+ *
+ * To implement this method, you could attempt to implement a new subclass of
+ * the ns3::TraceResolver base class and return an instance from this method but
+ * this would be very hard. Instead, you should use the helper class
+ * ns3::CompositeTraceResolver to register your trace sources and chain up to
+ * your parent:
+ * \code
+ * Ptr<TraceResolver>
+ * MyModel::GetTraceResolver (void) const
+ * {
+ * // create an empty trace resolver
+ * Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+ * // register m_rxSource
+ * resolver->AddSource ("rx", // the name of the trace source in the path string
+ * TraceDoc ("some help text to explain the purpose of this trace source",
+ * "Packet", // the type of the first argument to the trace source
+ * "the purpose of the first argument",
+ * "type-of-second-argument", "purpose-of-second-argument"),
+ * m_rxSource // the trace source itself is registered
+ * );
+ * // make sure we include the trace sources implemented in the parent.
+ * resolver->SetParentResolver (MyParent::GetTraceResolver ());
+ * return resolver;
+ * }
+ * \endcode
+ *
+ * Once you have written that code, you must make sure that this new method GetTraceResolver
+ * is going to be called at some point by the tracing system. If your model is located somewhere
+ * deep in MAC or PHY layer, that is, it is part of a NetDevice implementation, all you
+ * have to do is to make sure that your model is registered as a "composite" of your NetDevice
+ * subclass:
+ * \code
+ * class MyNetDevice : public NetDevice
+ * {
+ * public:
+ * Ptr<TraceResolver> GetTraceResolver (void) const;
+ * private:
+ * Ptr<MyModel> m_model;
+ * };
+ *
+ * Ptr<TraceResolver>
+ * MyNetDevice::GetTraceResolver (void) const
+ * {
+ * Ptr<CompositeTraceResolver> resolver = ...;
+ * // register other trace source
+ * ...
+ * // register now your model as a "composite"
+ * resolver->AddComposite ("my-model", m_model);
+ * // chain up to parent.
+ * resolver->SetParentResolver (NetDevice::GetTraceResolver ());
+ * return resolver;
+ * }
+ * \endcode
+ *
+ * The code above will make your "rx" trace source appear under the
+ * /nodes/xx/devices/xx/my-model/rx namespace path.
+ *
+ * If you have implemented a new layer 3 or 4 protocol object, the process to
+ * export your trace sources is quite similar. You need to subclass from
+ * ns3::Object, override the ns3::Object::GetTraceResolver method, make
+ * sure you chain up to your parent's GetTraceResolver method, and, finally,
+ * make sure that someone calls your new GetTraceResolver method. How to accomplish
+ * the latter should be documented in the node's API documentation which describes
+ * how to implement a new layer 3 or 4 protocol object.
+ *
+ * \section AdvancedTraceContext Creating new Trace Context Elements
+ *
+ * The last important feature which model developers need to understand
+ * is how to provide extra context information to trace sinks. For example,
+ * if your model exports both rx and tx trace sources which share the same
+ * signature, it is quite natural for a user to connect to a single trace sink
+ * to both of them with a trace path string such as "/nodes/* /devices/* /(rx|tx)".
+ * In this case, it becomes necessary to be able, from the trace sink function,
+ * to tell which event triggered the call to the trace sink: a rx or a tx event.
+ *
+ * That example is detailed below with a TX, a RX, and a DROP source:
+ * \code
+ * class MyModel
+ * {
+ * private:
+ * CallbackTraceSource<Packet> m_rxSource;
+ * CallbackTraceSource<Packet> m_txSource;
+ * CallbackTraceSource<Packet> m_dropSource;
+ * };
+ * \endcode
+ * When a single sink is connected to all 3 sources here, one might want
+ * to write code like the following:
+ * \code
+ * void DeviceRxSink (const TraceContext &context, const Packet &packet)
+ * {
+ * switch (type) {
+ * case RX:
+ * std::cout << "rx" << std::endl;
+ * break;
+ * case TX:
+ * std::cout << "tx" << std::endl;
+ * break;
+ * case DROP:
+ * std::cout << "drop" << std::endl;
+ * break;
+ * }
+ * \endcode
+ *
+ * \subsection AdvancedTraceContextSimpleSolution The simple solution
+ *
+ * The simplest way to do achieve the result shown above is to include
+ * in the trace source an extra explicit argument which describes the source event:
+ * - define a small enum with 3 values
+ * - change the signature of m_rxSource, m_txSource, and m_dropSource to include
+ * the enum
+ * - pass the enum value in each event
+ *
+ * The resulting code is shown below:
+ * \code
+ * class MyModel
+ * {
+ * public:
+ * // define the trace type enum.
+ * enum TraceType {
+ * RX,
+ * TX,
+ * DROP
+ * };
+ * private:
+ * // generate events
+ * void NotifyRxPacket (Packet p) {
+ * m_rxSource (p, MyModel::RX);
+ * }
+ * void NotifyTxPacket (Packet p) {
+ * m_rxSource (p, MyModel::TX);
+ * }
+ * void NotifyDropPacket (Packet p) {
+ * m_rxSource (p, MyModel::DROP);
+ * }
+ * CallbackTraceSource<Packet,enum TraceType> m_rxSource;
+ * CallbackTraceSource<Packet,enum TraceType> m_txSource;
+ * CallbackTraceSource<Packet,enum TraceType> m_dropSource;
+ * };
+ * \endcode
+ * These 3 new sources can be connected easily to a new trace sink:
+ * \code
+ * void ASimpleTraceSink (const TraceContext &context, const Packet &packet, enum MyModel::TraceType type)
+ * {
+ * // here, read the "type" argument
+ * }
+ * \endcode
+ *
+ * This solution works but it makes it impossible to connect a single trace sink to a set
+ * of trace sources which represent "rx" events in different NetDevice objects since
+ * each of them will define a different enum type with different values: since the
+ * trace sink signature must match exactly the trace source signature, it is impossible
+ * to connect at the same time to all "rx" events of different NetDevice.
+ *
+ * \subsection AdvancedTraceContextFancySolution The more complex and generic solution
+ *
+ * There is, hopefully, a way to get the best of both worlds, that is, to allow a
+ * user to connect to a lot of trace source events of the same kind but coming from different
+ * implementations and to allow the user to differentiate between these different
+ * implementations.
+ *
+ * Rather than define an adhoc enum type with a list of trace sources, you can also
+ * define a new ns3::TraceContextElement for your source sources. For example, if you
+ * define a new MyModelTraceType class which contains the type of trace, your users can
+ * then write trace sink code which looks like this:
+ * \code
+ * void AFancyTraceSink (const TraceContext &context, const Packet &packet)
+ * {
+ * MyModelTraceType type;
+ * if (context.GetElement (type))
+ * {
+ * switch (type.Get ())
+ * {
+ * case MyModelTraceType::RX:
+ * std::cout << "rx" << std::endl;
+ * break;
+ * case MyModelTraceType::TX:
+ * std::cout << "tx" << std::endl;
+ * break;
+ * case MyModelTraceType::DROP:
+ * std::cout << "drop" << std::endl;
+ * break;
+ * }
+ * }
+ * }
+ * \endcode
+ *
+ * Of course, since the type of trace is stored in the TraceContext, your users can
+ * also take the shortcut which uses the printing functionality of the TraceContext:
+ * \code
+ * void ALessFancyTraceSink (const TraceContext &context, const Packet &packet)
+ * {
+ * std::cout << "context=\"" << context << "\" packet: " << packet << std::endl;
+ * }
+ * \endcode
+ * which will generate something like the following when the trace source comes
+ * from MyModel:
+ * \code
+ * context="my-model-rx" packet: ...
+ * \endcode
+ *
+ * The first step to achieve this is to define and implement a new
+ * subclass of the ns3::TraceContextElement base class. The exact list of
+ * public methods which must be implemented is described in the API
+ * documentation of the ns3::TraceContextElement class.
+ * \code
+ * class MyModelTraceType : public TraceContextElement
+ * {
+ * public:
+ * enum Type {
+ * RX,
+ * TX,
+ * DROP
+ * };
+ * // called from MyModel::GetTraceResolver
+ * MyModelTraceType (enum Type type);
+ * // called from trace sink
+ * enum Type Get (void) const;
+ * // needed by the tracing subsystem
+ * static uint16_t GetUid (void);
+ * // needed by the tracing subsystem to
+ * // print the content of a TraceContext
+ * void Print (std::ostream &os) const;
+ * // needed by the tracing subsystem to
+ * // generate the doxygen documentation.
+ * std::string GetTypeName (void) const;
+ * private:
+ * enum Type m_type;
+ * };
+ * \endcode
+ * The implementation does not require much thinking:
+ * \code
+ * MyModelTraceType::MyModelTraceType (enum Type type)
+ * : m_type (type)
+ * {}
+ * enum Type
+ * MyModelTraceType::Get (void) const
+ * {
+ * return m_type;
+ * }
+ * uint16_t
+ * MyModelTraceType::GetUid (void)
+ * {
+ * // use protected TraceContextElement::AllocateUid method
+ * // the input string is used to uniquely identify this new subclass
+ * static uint16_t uid = AllocateUid<MyModelTraceType> ("ns3::MyModelTraceType");
+ * return uid;
+ * }
+ * void
+ * MyModelTraceType::Print (std::ostream &os) const
+ * (
+ * // this method is invoked by the print function of a TraceContext
+ * // if it contains an instance of this TraceContextElement.
+ * switch (m_type) {
+ * case RX: os << "rx"; break;
+ * // ...
+ * }
+ * )
+ * std::string
+ * MyModelTraceType::GetTypeName (void) const
+ * {
+ * // This method should return a fully-qualified c++ typename
+ * // This method is used only for documentation purposes to
+ * // generate the content of the Trace Source List.
+ * return "ns3::MyModelTraceType";
+ * }
+ * \endcode
+ *
+ * Once this subclass is implemented, the work is almost completed: you
+ * just need to pass an instance of that class as the last argument of
+ * the ns3::CompositeTraceResolver::AddSource method as shown below:
+ * \code
+ * Ptr<TraceResolver>
+ * MyModel::GetTraceResolver (void) const
+ * {
+ * // create an empty trace resolver
+ * Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+ * // register m_rxSource
+ * resolver->AddSource ("rx", // the name of the trace source in the path string
+ * TraceDoc ("some help text to explain the purpose of this trace source",
+ * "Packet", // the type of the first argument to the trace source
+ * "the purpose of the first argument",
+ * "type-of-second-argument", "purpose-of-second-argument"),
+ * m_rxSource, // the trace source itself is registered
+ * // the TraceContextElement associated to this trace source.
+ * MyModelTraceType (MyModelTraceType::RX)
+ * );
+ * // make sure we include the trace sources implemented in the parent.
+ * resolver->SetParentResolver (MyParent::GetTraceResolver ());
+ * return resolver;
+ * }
+ * \endcode
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/csma-broadcast.cc Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,159 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+//
+// Example of the sending of a datagram to a broadcast address
+//
+// Network topology
+// ==============
+// | |
+// n0 n1 n2
+// | |
+// ==========
+//
+// n0 originates UDP broadcast to 255.255.255.255, which is replicated
+// and received on both n1 and n2
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/command-line.h"
+#include "ns3/default-value.h"
+#include "ns3/ptr.h"
+#include "ns3/random-variable.h"
+#include "ns3/debug.h"
+
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+
+#include "ns3/ascii-trace.h"
+#include "ns3/pcap-trace.h"
+#include "ns3/internet-node.h"
+#include "ns3/csma-channel.h"
+#include "ns3/csma-net-device.h"
+#include "ns3/csma-topology.h"
+#include "ns3/csma-ipv4-topology.h"
+#include "ns3/eui48-address.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/ipv4.h"
+#include "ns3/socket.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/onoff-application.h"
+
+
+using namespace ns3;
+
+
+int main (int argc, char *argv[])
+{
+
+ // Users may find it convenient to turn on explicit debugging
+ // for selected modules; the below lines suggest how to do this
+#if 0
+ DebugComponentEnable("CsmaNetDevice");
+ DebugComponentEnable("Ipv4L3Protocol");
+ DebugComponentEnable("NetDevice");
+ DebugComponentEnable("Channel");
+ DebugComponentEnable("CsmaChannel");
+ DebugComponentEnable("PacketSocket");
+#endif
+
+ // Set up some default values for the simulation. Use the Bind()
+ // technique to tell the system what subclass of Queue to use,
+ // and what the queue limit is
+
+ // The below Bind command tells the queue factory which class to
+ // instantiate, when the queue factory is invoked in the topology code
+ DefaultValue::Bind ("Queue", "DropTailQueue");
+
+ // Allow the user to override any of the defaults and the above
+ // Bind()s at run-time, via command-line arguments
+ CommandLine::Parse (argc, argv);
+
+ // Here, we will explicitly create four nodes. In more sophisticated
+ // topologies, we could configure a node factory.
+ Ptr<Node> n0 = Create<InternetNode> ();
+ Ptr<Node> n1 = Create<InternetNode> ();
+ Ptr<Node> n2 = Create<InternetNode> ();
+
+ // We create the channels first without any IP addressing information
+ Ptr<CsmaChannel> channel0 =
+ CsmaTopology::CreateCsmaChannel(
+ DataRate(5000000), MilliSeconds(2));
+
+ // We create the channels first without any IP addressing information
+ Ptr<CsmaChannel> channel1 =
+ CsmaTopology::CreateCsmaChannel(
+ DataRate(5000000), MilliSeconds(2));
+
+ uint32_t n0ifIndex0 = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0,
+ Eui48Address("10:54:23:54:0:50"));
+ uint32_t n0ifIndex1 = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel1,
+ Eui48Address("10:54:23:54:0:51"));
+ uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0,
+ Eui48Address("10:54:23:54:23:51"));
+ uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channel1,
+ Eui48Address("10:54:23:54:23:52"));
+
+ // Later, we add IP addresses.
+ CsmaIpv4Topology::AddIpv4Address (
+ n0, n0ifIndex0, Ipv4Address("10.1.0.1"), Ipv4Mask("255.255.0.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (
+ n1, n1ifIndex, Ipv4Address("10.1.0.2"), Ipv4Mask("255.255.0.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (
+ n0, n0ifIndex1, Ipv4Address("192.168.1.1"), Ipv4Mask("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (
+ n2, n2ifIndex, Ipv4Address("192.168.1.2"), Ipv4Mask("255.255.255.0"));
+
+ // Create the OnOff application to send UDP datagrams of size
+ // 210 bytes at a rate of 448 Kb/s
+ // from n0 to n1
+ Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
+ n0,
+ InetSocketAddress ("255.255.255.255", 80),
+ "Udp",
+ ConstantVariable(1),
+ ConstantVariable(0));
+ // Start the application
+ ooff->Start(Seconds(1.0));
+ ooff->Stop (Seconds(10.0));
+
+
+ // Configure tracing of all enqueue, dequeue, and NetDevice receive events
+ // Trace output will be sent to the csma-broadcast.tr file
+ AsciiTrace asciitrace ("csma-broadcast.tr");
+ asciitrace.TraceAllNetDeviceRx ();
+ asciitrace.TraceAllQueues ();
+
+ // Also configure some tcpdump traces; each interface will be traced
+ // The output files will be named
+ // simple-point-to-point.pcap-<nodeId>-<interfaceId>
+ // and can be read by the "tcpdump -r" command (use "-tt" option to
+ // display timestamps correctly)
+ PcapTrace pcaptrace ("csma-broadcast.pcap");
+ pcaptrace.TraceAllIp ();
+
+ Simulator::Run ();
+
+ Simulator::Destroy ();
+}
--- a/examples/simple-global-routing.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/examples/simple-global-routing.cc Tue Sep 11 14:52:15 2007 +0100
@@ -65,6 +65,7 @@
#include "ns3/ipv4-route.h"
#include "ns3/point-to-point-topology.h"
#include "ns3/onoff-application.h"
+#include "ns3/packet-sink.h"
#include "ns3/global-route-manager.h"
using namespace ns3;
@@ -151,6 +152,17 @@
ooff->Start (Seconds (1.0));
ooff->Stop (Seconds (10.0));
+ // Create a packet sink to receive these packets
+ // The last argument "true" disables output from the Receive callback
+ Ptr<PacketSink> sink = Create<PacketSink> (
+ n3,
+ InetSocketAddress (Ipv4Address::GetAny (), 80),
+ "Udp",
+ true);
+ // Start the sink
+ sink->Start (Seconds (1.0));
+ sink->Stop (Seconds (10.0));
+
// Create a similar flow from n3 to n1, starting at time 1.1 seconds
ooff = Create<OnOffApplication> (
n3,
@@ -162,6 +174,16 @@
ooff->Start (Seconds (1.1));
ooff->Stop (Seconds (10.0));
+ // Create a packet sink to receive these packets
+ sink = Create<PacketSink> (
+ n1,
+ InetSocketAddress (Ipv4Address::GetAny (), 80),
+ "Udp",
+ true);
+ // Start the sink
+ sink->Start (Seconds (1.1));
+ sink->Stop (Seconds (10.0));
+
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
// Trace output will be sent to the simple-global-routing.tr file
AsciiTrace asciitrace ("simple-global-routing.tr");
--- a/examples/simple-point-to-point-olsr.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/examples/simple-point-to-point-olsr.cc Tue Sep 11 14:52:15 2007 +0100
@@ -64,6 +64,7 @@
#include "ns3/ipv4-route.h"
#include "ns3/point-to-point-topology.h"
#include "ns3/onoff-application.h"
+#include "ns3/packet-sink.h"
#include "ns3/olsr.h"
@@ -155,6 +156,15 @@
ooff->Start(Seconds(1.0));
ooff->Stop (Seconds(10.0));
+ // Create an optional packet sink to receive these packets
+ Ptr<PacketSink> sink = Create<PacketSink> (
+ n3,
+ InetSocketAddress (Ipv4Address::GetAny (), 80),
+ "Udp");
+ // Start the sink
+ sink->Start (Seconds (1.0));
+ sink->Stop (Seconds (10.0));
+
// Create a similar flow from n3 to n1, starting at time 1.1 seconds
ooff = Create<OnOffApplication> (
n3,
@@ -166,8 +176,23 @@
ooff->Start(Seconds(1.1));
ooff->Stop (Seconds(10.0));
- // Start OLSR in all nodes
- olsr::EnableAllNodes ();
+ // Create a packet sink to receive these packets
+ sink = Create<PacketSink> (
+ n1,
+ InetSocketAddress (Ipv4Address::GetAny (), 80),
+ "Udp");
+ // Start the sink
+ sink->Start (Seconds (1.1));
+ sink->Stop (Seconds (10.0));
+ sink->SetQuiet (); // disable output from the Receive callback
+
+ // Here, finish off packet routing configuration
+ // This will likely set by some global StaticRouting object in the future
+ Ptr<Ipv4> ipv4;
+ ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
+ ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1);
+ ipv4 = n3->QueryInterface<Ipv4> (Ipv4::iid);
+ ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.1"), 1);
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
// Trace output will be sent to the simple-point-to-point.tr file
--- a/examples/simple-point-to-point.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/examples/simple-point-to-point.cc Tue Sep 11 14:52:15 2007 +0100
@@ -64,6 +64,7 @@
#include "ns3/ipv4-route.h"
#include "ns3/point-to-point-topology.h"
#include "ns3/onoff-application.h"
+#include "ns3/packet-sink.h"
using namespace ns3;
@@ -153,6 +154,15 @@
ooff->Start(Seconds(1.0));
ooff->Stop (Seconds(10.0));
+ // Create an optional packet sink to receive these packets
+ Ptr<PacketSink> sink = Create<PacketSink> (
+ n3,
+ InetSocketAddress (Ipv4Address::GetAny (), 80),
+ "Udp");
+ // Start the sink
+ sink->Start (Seconds (1.0));
+ sink->Stop (Seconds (10.0));
+
// Create a similar flow from n3 to n1, starting at time 1.1 seconds
ooff = Create<OnOffApplication> (
n3,
@@ -164,6 +174,16 @@
ooff->Start(Seconds(1.1));
ooff->Stop (Seconds(10.0));
+ // Create a packet sink to receive these packets
+ sink = Create<PacketSink> (
+ n1,
+ InetSocketAddress (Ipv4Address::GetAny (), 80),
+ "Udp");
+ // Start the sink
+ sink->Start (Seconds (1.1));
+ sink->Stop (Seconds (10.0));
+ sink->SetQuiet (); // disable output from the Receive callback
+
// Here, finish off packet routing configuration
// This will likely set by some global StaticRouting object in the future
Ptr<Ipv4> ipv4;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/waf Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../waf "$@"
--- a/examples/wscript Thu Sep 06 15:18:14 2007 +0100
+++ b/examples/wscript Tue Sep 11 14:52:15 2007 +0100
@@ -14,6 +14,10 @@
['csma', 'internet-node'])
obj.source = 'csma-one-subnet.cc'
+ obj = bld.create_ns3_program('csma-broadcast',
+ ['csma', 'internet-node'])
+ obj.source = 'csma-broadcast.cc'
+
obj = bld.create_ns3_program('csma-packet-socket',
['csma', 'internet-node'])
obj.source = 'csma-packet-socket.cc'
--- a/samples/main-random-topology.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/samples/main-random-topology.cc Tue Sep 11 14:52:15 2007 +0100
@@ -15,7 +15,7 @@
using namespace ns3;
static void
-CourseChange (Ptr<const MobilityModel> position)
+CourseChange (const TraceContext &context, Ptr<const MobilityModel> position)
{
Position pos = position->Get ();
std::cout << Simulator::Now () << ", pos=" << position << ", x=" << pos.x << ", y=" << pos.y
@@ -39,7 +39,7 @@
for (uint32_t i = 0; i < 10000; i++)
{
Ptr<MobilityModelNotifier> notifier = Create<MobilityModelNotifier> ();
- notifier->RegisterListener (MakeCallback (&CourseChange));
+ notifier->TraceConnect ("/course-change", MakeCallback (&CourseChange));
objects.push_back (notifier);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/waf Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../waf "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/packet-sink.cc Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#include "ns3/address.h"
+#include "ns3/debug.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/node.h"
+#include "ns3/socket.h"
+#include "ns3/simulator.h"
+#include "ns3/socket-factory.h"
+#include "ns3/packet.h"
+#include "packet-sink.h"
+
+using namespace std;
+
+namespace ns3 {
+
+// Constructors
+
+PacketSink::PacketSink (Ptr<Node> n,
+ const Address &local,
+ std::string iid,
+ bool quiet)
+ : Application(n)
+{
+ Construct (n, local, iid, quiet);
+}
+
+void
+PacketSink::Construct (Ptr<Node> n,
+ const Address &local,
+ std::string iid,
+ bool quiet)
+{
+ m_socket = 0;
+ m_local = local;
+ m_iid = iid;
+ m_quiet = quiet;
+}
+
+PacketSink::~PacketSink()
+{}
+
+void
+PacketSink::SetQuiet()
+{
+ m_quiet = true;
+}
+
+void
+PacketSink::DoDispose (void)
+{
+ m_socket = 0;
+
+ // chain up
+ Application::DoDispose ();
+}
+
+
+// Application Methods
+void PacketSink::StartApplication() // Called at time specified by Start
+{
+ // Create the socket if not already
+ if (!m_socket)
+ {
+ InterfaceId iid = InterfaceId::LookupByName (m_iid);
+ Ptr<SocketFactory> socketFactory =
+ GetNode ()->QueryInterface<SocketFactory> (iid);
+ m_socket = socketFactory->CreateSocket ();
+ m_socket->Bind (m_local);
+ }
+ m_socket->SetRecvCallback((Callback<void, Ptr<Socket>, const Packet &,
+ const Address &>) MakeCallback(&PacketSink::Receive, this));
+}
+
+void PacketSink::StopApplication() // Called at time specified by Stop
+{
+ if (!m_socket)
+ {
+ m_socket->SetRecvCallback((Callback<void, Ptr<Socket>, const Packet &,
+ const Address &>) NULL);
+
+ }
+}
+
+// This callback body suggested by Joe Kopena's wiki
+void PacketSink::Receive(Ptr<Socket> socket, const Packet &packet,
+ const Address &from)
+{
+ if (!m_quiet)
+ {
+ if (InetSocketAddress::IsMatchingType (from))
+ {
+ InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
+ NS_DEBUG_UNCOND ( __PRETTY_FUNCTION__ << ": Received " <<
+ packet.GetSize() << " bytes from " << address.GetIpv4() << " ["
+ << address << "]---'" << packet.PeekData() << "'");
+ }
+ }
+}
+
+} // Namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/packet-sink.h Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+//
+
+#ifndef __packet_sink_h__
+#define __packet_sink_h__
+
+#include "ns3/application.h"
+#include "ns3/event-id.h"
+#include "ns3/ptr.h"
+
+namespace ns3 {
+
+class Address;
+class Socket;
+class Packet;
+
+/**
+ * \brief Receive and consume traffic generated to an IP address and port
+ *
+ * This Application can be used as a receiver for packets generated by
+ * traffic sourcing applications such as OnOffApplication. The constructor
+ * specifies the Address (IP address and port) and the transport protocol
+ * to use. A virtual Receive () method is installed as a callback on
+ * the receiving socket. By default, it prints out the size of packets
+ * and their address.
+ */
+class PacketSink : public Application
+{
+public:
+ /**
+ * \param n node associated to this application
+ * \param local local ip address
+ * \param iid
+ * \param ontime on time random variable
+ * \param offtime off time random variable
+ */
+ PacketSink (Ptr<Node> n,
+ const Address &local,
+ std::string iid, bool quiet=false);
+
+ virtual ~PacketSink ();
+
+ /**
+ * \brief Turn off the logging output for the receive callback
+ */
+ void SetQuiet (void);
+
+protected:
+ virtual void DoDispose (void);
+private:
+ // inherited from Application base class.
+ virtual void StartApplication (void); // Called at time specified by Start
+ virtual void StopApplication (void); // Called at time specified by Stop
+
+ void Construct (Ptr<Node> n,
+ const Address &local,
+ std::string iid,
+ bool quiet);
+
+ virtual void Receive (Ptr<Socket> socket, const Packet& packet, const Address& from);
+
+ Ptr<Socket> m_socket; // Associated socket
+ Address m_local; // Local address to bind to
+ std::string m_iid; // Protocol name (e.g., "Udp")
+ bool m_quiet; // Governs whether receive callback is quiet
+
+};
+
+} // namespace ns3
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/waf Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../waf "$@"
\ No newline at end of file
--- a/src/applications/wscript Thu Sep 06 15:18:14 2007 +0100
+++ b/src/applications/wscript Tue Sep 11 14:52:15 2007 +0100
@@ -4,9 +4,11 @@
obj = bld.create_ns3_module('applications', ['node'])
obj.source = [
'onoff-application.cc',
+ 'packet-sink.cc',
]
headers = bld.create_obj('ns3header')
headers.source = [
'onoff-application.h',
+ 'packet-sink.h',
]
--- a/src/common/array-trace-resolver.h Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef ARRAY_TRACE_RESOLVER_H
-#define ARRAY_TRACE_RESOLVER_H
-
-#include <stdint.h>
-#include <string>
-#include "ns3/callback.h"
-#include "trace-resolver.h"
-
-namespace ns3 {
-
-/**
- * \brief a helper class to offer trace resolution for an array of objects.
- * \ingroup lowleveltracing
- */
-template <typename T, typename INDEX>
-class ArrayTraceResolver : public TraceResolver
-{
-public:
- /**
- * \param context trace context associated to this trace resolver
- * \param getSize callback which returns dynamically the size of underlying array
- * \param get callback which returns any element in the underlying array
- *
- * Construct a trace resolver which can match any input integer
- * against an element in an array. The array is accessed using a
- * pair of callbacks. It is the responsability of the user to
- * provide two such callbacks whose job is to adapt the array
- * API to the resolver needs. Each element of the array is expected
- * to provide a method named CreateTraceResolver which takes as
- * only argument a reference to a const TraceContext and returns
- * a pointer to a TraceResolver. i.e. the signature is:
- * TraceResolver * (*) (TraceContext const &)
- */
- ArrayTraceResolver (TraceContext const &context,
- Callback<uint32_t> getSize,
- Callback<T, uint32_t> get);
-private:
- virtual TraceResolverList DoLookup (std::string id) const;
- Callback<uint32_t> m_getSize;
- Callback<T, uint32_t> m_get;
-};
-}//namespace ns3
-
-namespace ns3 {
-
-template <typename T, typename INDEX>
-ArrayTraceResolver<T,INDEX>::ArrayTraceResolver (TraceContext const &context,
- Callback<uint32_t> getSize,
- Callback<T, uint32_t> get)
- : TraceResolver (context),
- m_getSize (getSize),
- m_get (get)
-{}
-template <typename T, typename INDEX>
-TraceResolver::TraceResolverList
-ArrayTraceResolver<T,INDEX>::DoLookup (std::string id) const
-{
- TraceResolverList list;
- if (id == "*")
- {
- for (uint32_t i = 0; i < m_getSize (); i++)
- {
- TraceContext context = GetContext ();
- INDEX index = i;
- context.Add (index);
- list.push_back (m_get (i)->CreateTraceResolver (context));
- }
- }
- return list;
-}
-
-
-}//namespace ns3
-
-#endif /* ARRAY_TRACE_RESOLVER_H */
--- a/src/common/buffer.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/common/buffer.h Tue Sep 11 14:52:15 2007 +0100
@@ -69,7 +69,7 @@
* to the same underlying buffer. Debug builds ensure
* this with an assert.
*/
- inline int32_t GetDistanceFrom (Iterator const &o) const;
+ inline uint32_t GetDistanceFrom (Iterator const &o) const;
/**
* \return true if this iterator points to the end of the byte array.
@@ -502,13 +502,21 @@
NS_ASSERT (m_current >= delta);
m_current -= delta;
}
-int32_t
+uint32_t
Buffer::Iterator::GetDistanceFrom (Iterator const &o) const
{
NS_ASSERT (m_data == o.m_data);
int32_t start = m_current;
int32_t end = o.m_current;
- return end - start;
+ int32_t diff = end - start;
+ if (diff < 0)
+ {
+ return -diff;
+ }
+ else
+ {
+ return diff;
+ }
}
bool
--- a/src/common/callback-trace-source.cc Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "callback-trace-source.h"
-#include "ns3/test.h"
-
-namespace ns3 {
-
-class CallbackTraceSourceTest : public Test
-{
-public:
- CallbackTraceSourceTest ();
- virtual ~CallbackTraceSourceTest ();
- virtual bool RunTests (void);
-private:
- void CbOne (TraceContext const &context, uint8_t a, double b);
- void CbTwo (TraceContext const &context, uint8_t a, double b);
-
- bool m_one;
- bool m_two;
-};
-
-CallbackTraceSourceTest::CallbackTraceSourceTest ()
- : Test ("CallbackTraceSource")
-{}
-CallbackTraceSourceTest::~CallbackTraceSourceTest ()
-{}
-void
-CallbackTraceSourceTest::CbOne (TraceContext const &context, uint8_t a, double b)
-{
- m_one = true;
-}
-void
-CallbackTraceSourceTest::CbTwo (TraceContext const &context, uint8_t a, double b)
-{
- m_two = true;
-}
-bool
-CallbackTraceSourceTest::RunTests (void)
-{
- bool ok = true;
- TraceContext ctx;
-
- CallbackTraceSource<uint8_t,double> trace;
- trace.AddCallback (MakeCallback (&CallbackTraceSourceTest::CbOne, this), ctx);
- trace.AddCallback (MakeCallback (&CallbackTraceSourceTest::CbTwo, this), ctx);
- m_one = false;
- m_two = false;
- trace (1, 2);
- if (!m_one || !m_two)
- {
- ok = false;
- }
- trace.RemoveCallback (MakeCallback (&CallbackTraceSourceTest::CbOne, this));
- m_one = false;
- m_two = false;
- trace (1, 2);
- if (m_one || !m_two)
- {
- ok = false;
- }
- trace.RemoveCallback (MakeCallback (&CallbackTraceSourceTest::CbTwo, this));
- m_one = false;
- m_two = false;
- trace (1, 2);
- if (m_one || m_two)
- {
- ok = false;
- }
-
- return ok;
-}
-
-CallbackTraceSourceTest g_callbackTraceTest;
-
-
-
-}//namespace ns3
--- a/src/common/callback-trace-source.h Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef CALLBACK_TRACE_H
-#define CALLBACK_TRACE_H
-
-#include <list>
-#include "ns3/callback.h"
-#include "ns3/fatal-error.h"
-#include "trace-context.h"
-
-namespace ns3 {
-
-
-/**
- * \brief log arbitrary number of parameters to a matching ns3::Callback
- * \ingroup lowleveltracing
- *
- * Whenever operator () is invoked on this class, the call and its arguments
- * are forwarded to the internal matching ns3::Callback.
- */
-template<typename T1 = empty, typename T2 = empty,
- typename T3 = empty, typename T4 = empty>
-class CallbackTraceSource {
-public:
- CallbackTraceSource ();
- void AddCallback (CallbackBase const & callback, TraceContext const & context);
- void RemoveCallback (CallbackBase const & callback);
- void operator() (void);
- void operator() (T1 a1);
- void operator() (T1 a1, T2 a2);
- void operator() (T1 a1, T2 a2, T3 a3);
- void operator() (T1 a1, T2 a2, T3 a3, T4 a4);
-
-private:
- typedef std::list<Callback<void,TraceContext const &,T1,T2,T3,T4> > CallbackList;
- TraceContext m_context;
- CallbackList m_callbackList;
-};
-
-}; // namespace ns3
-
-// implementation below.
-
-namespace ns3 {
-
-template<typename T1, typename T2,
- typename T3, typename T4>
-CallbackTraceSource<T1,T2,T3,T4>::CallbackTraceSource ()
- : m_callbackList ()
-{}
-template<typename T1, typename T2,
- typename T3, typename T4>
-void
-CallbackTraceSource<T1,T2,T3,T4>::AddCallback (CallbackBase const & callback,
- TraceContext const &context)
-{
- Callback<void,TraceContext const &,T1,T2,T3,T4> cb;
- cb.Assign (callback);
- m_context.Add (context);
- m_callbackList.push_back (cb);
-}
-template<typename T1, typename T2,
- typename T3, typename T4>
-void
-CallbackTraceSource<T1,T2,T3,T4>::RemoveCallback (CallbackBase const & callback)
-{
- for (typename CallbackList::iterator i = m_callbackList.begin ();
- i != m_callbackList.end (); /* empty */)
- {
- if ((*i).IsEqual (callback))
- {
- i = m_callbackList.erase (i);
- }
- else
- {
- i++;
- }
- }
-}
-template<typename T1, typename T2,
- typename T3, typename T4>
-void
-CallbackTraceSource<T1,T2,T3,T4>::operator() (void)
-{
- for (typename CallbackList::iterator i = m_callbackList.begin ();
- i != m_callbackList.end (); i++)
- {
- (*i) (m_context);
- }
-}
-template<typename T1, typename T2,
- typename T3, typename T4>
-void
-CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1)
-{
- for (typename CallbackList::iterator i = m_callbackList.begin ();
- i != m_callbackList.end (); i++)
- {
- (*i) (m_context, a1);
- }
-}
-template<typename T1, typename T2,
- typename T3, typename T4>
-void
-CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1, T2 a2)
-{
- for (typename CallbackList::iterator i = m_callbackList.begin ();
- i != m_callbackList.end (); i++)
- {
- (*i) (m_context, a1, a2);
- }
-}
-template<typename T1, typename T2,
- typename T3, typename T4>
-void
-CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1, T2 a2, T3 a3)
-{
- for (typename CallbackList::iterator i = m_callbackList.begin ();
- i != m_callbackList.end (); i++)
- {
- (*i) (m_context, a1, a2, a3);
- }
-}
-template<typename T1, typename T2,
- typename T3, typename T4>
-void
-CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1, T2 a2, T3 a3, T4 a4)
-{
- for (typename CallbackList::iterator i = m_callbackList.begin ();
- i != m_callbackList.end (); i++)
- {
- (*i) (m_context, a1, a2, a3, a4);
- }
-}
-
-}//namespace ns3
-
-#endif /* CALLBACK_TRACE_H */
--- a/src/common/composite-trace-resolver.cc Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,375 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "composite-trace-resolver.h"
-
-namespace ns3 {
-
-CompositeTraceResolver::CompositeTraceResolver (TraceContext const &context)
- : TraceResolver (context)
-{}
-
-CompositeTraceResolver::~CompositeTraceResolver ()
-{}
-
-void
-CompositeTraceResolver::Add (std::string name,
- Callback<TraceResolver *,TraceContext const &> createResolver)
-{
- TraceContext traceContext = GetContext ();
- DoAdd (name, createResolver, traceContext);
-}
-
-void
-CompositeTraceResolver::DoAdd (std::string name,
- Callback<TraceResolver *,TraceContext const &> createResolver,
- TraceContext const &context)
-{
- struct CallbackTraceSourceItem item;
- item.name = name;
- item.createResolver = createResolver;
- item.context = context;
- m_items.push_back (item);
-}
-
-TraceResolver::TraceResolverList
-CompositeTraceResolver::DoLookup (std::string id) const
-{
- if (id == "*")
- {
- TraceResolver::TraceResolverList list;
- for (TraceItems::const_iterator i = m_items.begin (); i != m_items.end (); i++)
- {
- list.push_back (i->createResolver (i->context));
- }
- return list;
- }
- std::string::size_type start, end;
- start = id.find_first_of ("(", 0);
- end = id.find_first_of (")", 0);
- if (start != 0 || end != (id.size ()-1))
- {
- for (TraceItems::const_iterator i = m_items.begin (); i != m_items.end (); i++)
- {
- if (i->name == id)
- {
- TraceResolver::TraceResolverList list;
- list.push_back (i->createResolver (i->context));
- return list;
- }
- }
- }
- std::list<std::string> names;
- std::string alternatives = std::string (id, start+1, end-1);
- std::string::size_type next, cur;
- next = 0;
- cur = 0;
- while (true)
- {
- std::string element;
- next = alternatives.find ("|", cur);
- if (next == std::string::npos)
- {
- element = std::string (alternatives, cur, alternatives.size ());
- names.push_back (element);
- break;
- }
- element = std::string (alternatives, cur, next);
- names.push_back (element);
- cur = next + 1;
- }
- TraceResolver::TraceResolverList list;
- for (std::list<std::string>::const_iterator i = names.begin (); i != names.end (); i++)
- {
- for (TraceItems::const_iterator j = m_items.begin (); j != m_items.end (); j++)
- {
- if (j->name == *i)
- {
- list.push_back (j->createResolver (j->context));
- break;
- }
- }
- }
- return list;
-}
-
-}//namespace ns3
-
-#ifdef RUN_SELF_TESTS
-
-#include "ns3/test.h"
-#include "trace-context-element.h"
-
-namespace ns3 {
-
-class TraceSourceTest : public TraceContextElement
-{
-public:
- enum Sources {
- DOUBLEA,
- DOUBLEB,
- SUBRESOLVER,
- };
- static uint16_t GetUid (void)
- {static uint16_t uid = AllocateUid<TraceSourceTest> ("TraceSourceTest"); return uid;}
- void Print (std::ostream &os)
- {os << "tracesource=";
- if (m_sources == DOUBLEA) {os << "doubleA";}
- else if (m_sources == DOUBLEB) {os << "doubleB";}
- else if (m_sources == SUBRESOLVER) {os << "subresolver";}
- }
- TraceSourceTest () : m_sources (TraceSourceTest::DOUBLEA) {}
- TraceSourceTest (enum Sources sources) :m_sources (sources) {}
- bool IsDoubleA (void) {return m_sources == TraceSourceTest::DOUBLEA;}
- bool IsDoubleB (void) {return m_sources == TraceSourceTest::DOUBLEB;}
-private:
- enum TraceSourceTest::Sources m_sources;
-};
-
-class SubTraceSourceTest : public TraceContextElement
-{
-public:
- enum Sources {
- INT,
- };
- static uint16_t GetUid (void)
- {static uint16_t uid = AllocateUid<SubTraceSourceTest> ("SubTraceSourceTest"); return uid;}
- void Print (std::ostream &os)
- {os << "subtracesource=int";}
- SubTraceSourceTest () : m_sources (SubTraceSourceTest::INT) {}
- SubTraceSourceTest (enum Sources sources) : m_sources (sources) {}
-private:
- enum Sources m_sources;
-};
-
-class CompositeTraceResolverTest : public Test
-{
-public:
- CompositeTraceResolverTest ();
- virtual ~CompositeTraceResolverTest ();
- virtual bool RunTests (void);
-private:
- void TraceDouble (TraceContext const &context, double v);
- void TraceInt (TraceContext const &context, int v);
- TraceResolver *CreateSubResolver (TraceContext const &context);
-
-
- bool m_gotDoubleA;
- bool m_gotDoubleB;
- CallbackTraceSource<int> m_traceInt;
- bool m_gotInt;
-};
-
-CompositeTraceResolverTest::CompositeTraceResolverTest ()
- : Test ("CompositeTraceResolver")
-{}
-CompositeTraceResolverTest::~CompositeTraceResolverTest ()
-{}
-void
-CompositeTraceResolverTest::TraceDouble (TraceContext const &context, double v)
-{
- TraceSourceTest source;
- context.Get (source);
- if (source.IsDoubleA ())
- {
- m_gotDoubleA = true;
- }
- else if (source.IsDoubleB ())
- {
- m_gotDoubleB = true;
- }
- else
- {
- NS_FATAL_ERROR ("should not get any other trace source in this sink");
- }
-
-}
-
-void
-CompositeTraceResolverTest::TraceInt (TraceContext const &context, int v)
-{
- m_gotInt = true;
-}
-
-TraceResolver *
-CompositeTraceResolverTest::CreateSubResolver (TraceContext const &context)
-{
- CompositeTraceResolver *subresolver = new CompositeTraceResolver (context);
- subresolver->Add ("trace-int", m_traceInt,
- SubTraceSourceTest (SubTraceSourceTest::INT));
- return subresolver;
-}
-bool
-CompositeTraceResolverTest::RunTests (void)
-{
- bool ok = true;
-
- CallbackTraceSource<double> traceDoubleA;
- CallbackTraceSource<double> traceDoubleB;
- TraceContext context;
-
- CompositeTraceResolver resolver (context) ;
-
- resolver.Add ("trace-double-a", traceDoubleA,
- TraceSourceTest (TraceSourceTest::DOUBLEA));
- resolver.Add ("trace-double-b", traceDoubleB,
- TraceSourceTest (TraceSourceTest::DOUBLEB));
-
- resolver.Connect ("/*", MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-
- m_gotDoubleA = false;
- m_gotDoubleB = false;
- traceDoubleA (0);
- if (!m_gotDoubleA || m_gotDoubleB)
- {
- ok = false;
- }
- m_gotDoubleA = false;
- traceDoubleA (0);
- traceDoubleB (0);
- if (!m_gotDoubleA || !m_gotDoubleB)
- {
- ok = false;
- }
- m_gotDoubleA = false;
- m_gotDoubleB = false;
-
- resolver.Disconnect ("/*", MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-
- m_gotDoubleA = false;
- m_gotDoubleB = false;
- traceDoubleA (0);
- traceDoubleB (0);
- if (m_gotDoubleA || m_gotDoubleB)
- {
- ok = false;
- }
-
- resolver.Connect ("/trace-double-a",
- MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
- m_gotDoubleA = false;
- m_gotDoubleB = false;
- traceDoubleA (0);
- traceDoubleB (0);
- if (!m_gotDoubleA || m_gotDoubleB)
- {
- ok = false;
- }
- resolver.Disconnect ("/trace-double-a",
- MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-
- resolver.Connect ("/(trace-double-a)",
- MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
- m_gotDoubleA = false;
- m_gotDoubleB = false;
- traceDoubleA (0);
- traceDoubleB (0);
- if (!m_gotDoubleA || m_gotDoubleB)
- {
- ok = false;
- }
- resolver.Disconnect ("/trace-double-a",
- MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-
- resolver.Connect ("/(trace-double-a|trace-double-b)",
- MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
- m_gotDoubleA = false;
- m_gotDoubleB = false;
- traceDoubleA (0);
- traceDoubleB (0);
- if (!m_gotDoubleA || !m_gotDoubleB)
- {
- ok = false;
- }
- resolver.Disconnect ("/trace-double-a",
- MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
- m_gotDoubleA = false;
- m_gotDoubleB = false;
- traceDoubleA (0);
- traceDoubleB (0);
- if (m_gotDoubleA || !m_gotDoubleB)
- {
- ok = false;
- }
-
-
- resolver.Disconnect ("/(trace-double-a|trace-double-b)",
- MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
- m_gotDoubleA = false;
- m_gotDoubleB = false;
- traceDoubleA (0);
- traceDoubleB (0);
- if (m_gotDoubleA || m_gotDoubleB)
- {
- ok = false;
- }
-
- resolver.Add ("subresolver",
- MakeCallback (&CompositeTraceResolverTest::CreateSubResolver, this),
- TraceSourceTest (TraceSourceTest::SUBRESOLVER));
-
- resolver.Connect ("/subresolver/trace-int",
- MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
- m_gotInt = false;
- m_traceInt (1);
- if (!m_gotInt)
- {
- ok = false;
- }
-
- resolver.Disconnect ("/subresolver/trace-int",
- MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
- m_gotInt = false;
- m_traceInt (1);
- if (m_gotInt)
- {
- ok = false;
- }
-
- resolver.Connect ("/*/trace-int",
- MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
- m_gotInt = false;
- m_traceInt (1);
- if (!m_gotInt)
- {
- ok = false;
- }
-
- resolver.Disconnect ("/subresolver/trace-int",
- MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
- m_gotInt = false;
- m_traceInt (1);
- if (m_gotInt)
- {
- ok = false;
- }
-
-
-
-
- return ok;
-}
-
-static CompositeTraceResolverTest g_compositeTraceResolverTest;
-
-}//namespace ns3
-
-
-#endif /* RUN_SELF_TESTS */
--- a/src/common/composite-trace-resolver.h Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef COMPOSITE_TRACE_RESOLVER_H
-#define COMPOSITE_TRACE_RESOLVER_H
-
-#include "ns3/callback.h"
-#include "trace-resolver.h"
-#include "callback-trace-source.h"
-#include "uv-trace-source.h"
-#include "sv-trace-source.h"
-#include "fv-trace-source.h"
-#include "terminal-trace-resolver.h"
-
-namespace ns3 {
-
-/**
- * \brief a helper class to aggregate contained TraceResolver and other trace sources.
- * \ingroup lowleveltracing
- */
-class CompositeTraceResolver : public TraceResolver
-{
-public:
- CompositeTraceResolver (TraceContext const &context);
- virtual ~CompositeTraceResolver ();
- /**
- * \param name name of trace source
- * \param trace a callback trace source
- * \param context the context associated to this trace source
- *
- * Add a callback trace source in this resolver. This trace
- * source will match the name specified during namespace
- * resolution. The TraceContext of this trace source will also
- * be automatically extended to contain the input context.
- */
- template <typename T1, typename T2,
- typename T3, typename T4,
- typename T>
- void Add (std::string name,
- CallbackTraceSource<T1,T2,T3,T4> &trace, T const &context);
- /**
- * \param name name of trace source
- * \param trace a signed variable trace source
- * \param context the context associated to this trace source
- *
- * Add a signed variable trace source in this resolver.
- * This trace source will match the name specified during namespace
- * resolution. The TraceContext of this trace source will also
- * be automatically extended to contain the input context.
- */
- template <typename T>
- void Add (std::string name,
- SVTraceSource<T> &trace, T const &context);
- /**
- * \param name name of trace source
- * \param trace an unsigned variable trace source
- * \param context the context associated to this trace source
- *
- * Add an unsigned variable trace source in this resolver.
- * This trace source will match the name specified during namespace
- * resolution. The TraceContext of this trace source will also
- * be automatically extended to contain the input context.
- */
- template <typename T>
- void Add (std::string name,
- UVTraceSource<T> &trace, T const &context);
- /**
- * \param name name of trace source
- * \param trace a floating-point variable trace source
- * \param context the context associated to this trace source
- *
- * Add a floating-point variable trace source in this resolver.
- * This trace source will match the name specified during namespace
- * resolution. The TraceContext of this trace source will also
- * be automatically extended to contain the input context.
- */
- template <typename T>
- void Add (std::string name,
- FVTraceSource<T> &trace, T const &context);
-
- /**
- * \param name name of child trace resolver
- * \param createResolver a trace resolver constructor
- * \param context the context associated to this entry
- *
- * Add a child trace resolver to this resolver. This child
- * trace resolver will match the name specified during
- * namespace resolution. When this happens, the constructor
- * will be invoked to create the child trace resolver and
- * the associated TraceContext will be automatically extended
- * to contain the input context.
- */
- template <typename T>
- void Add (std::string name,
- Callback<TraceResolver *,TraceContext const &> createResolver,
- T const &context);
-
- /**
- * \param name name of child trace resolver
- * \param createResolver a trace resolver constructor
- *
- * Add a child trace resolver to this resolver. This child
- * trace resolver will match the name specified during
- * namespace resolution. When this happens, the constructor
- * will be invoked to create the child trace resolver.
- */
- void Add (std::string name,
- Callback<TraceResolver *,TraceContext const &> createResolver);
-private:
- template <typename SOURCE, typename CONTEXT>
- void DoAddTraceSource (std::string name,
- SOURCE &traceSource, CONTEXT const &context);
- template <typename SOURCE>
- static TraceResolver *CreateTerminalTraceResolver (SOURCE *trace,
- TraceContext const &context);
- void DoAdd (std::string name,
- Callback<TraceResolver *,TraceContext const &> createResolver,
- TraceContext const &context);
- virtual TraceResolverList DoLookup (std::string id) const;
-
- struct CallbackTraceSourceItem
- {
- std::string name;
- Callback<TraceResolver *,TraceContext const &> createResolver;
- TraceContext context;
- };
-
- typedef std::list<struct CallbackTraceSourceItem> TraceItems;
- TraceItems m_items;
-};
-
-}//namespace ns3
-
-namespace ns3 {
-
-template <typename SOURCE, typename CONTEXT>
-void
-CompositeTraceResolver::DoAddTraceSource (std::string name,
- SOURCE &traceSource, CONTEXT const &context)
-{
- TraceContext traceContext = GetContext ();
- traceContext.Add (context);
- TraceResolver *(*create) (SOURCE *trace, TraceContext const &context);
- create = &CompositeTraceResolver::CreateTerminalTraceResolver<SOURCE>;
- Callback<TraceResolver *,TraceContext const &> createResolver =
- MakeBoundCallback (create, &traceSource);
- DoAdd (name, createResolver, traceContext);
-}
-
-template <typename SOURCE>
-TraceResolver *
-CompositeTraceResolver::CreateTerminalTraceResolver (SOURCE *traceSource,
- TraceContext const &context)
-{
- return new TerminalTraceResolver<SOURCE> (*traceSource, context);
-}
-
-
-
-
-template <typename T1, typename T2,
- typename T3, typename T4,
- typename T>
-void
-CompositeTraceResolver::Add (std::string name,
- CallbackTraceSource<T1,T2,T3,T4> &trace,
- T const &context)
-{
- DoAddTraceSource (name, trace, context);
-}
-template <typename T>
-void
-CompositeTraceResolver::Add (std::string name,
- SVTraceSource<T> &trace, T const &context)
-{
- DoAddTraceSource (name, trace, context);
-}
-template <typename T>
-void
-CompositeTraceResolver::Add (std::string name,
- UVTraceSource<T> &trace, T const &context)
-{
- DoAddTraceSource (name, trace, context);
-}
-template <typename T>
-void
-CompositeTraceResolver::Add (std::string name,
- FVTraceSource<T> &trace, T const &context)
-{
- DoAddTraceSource (name, trace, context);
-}
-template <typename T>
-void
-CompositeTraceResolver::Add (std::string name,
- Callback<TraceResolver *,TraceContext const &> createResolver,
- T const &context)
-{
- TraceContext traceContext = GetContext ();
- traceContext.Add (context);
- DoAdd (name, createResolver, traceContext);
-}
-
-}//namespace ns3
-
-#endif /* COMPOSITE_TRACE_RESOLVER_H */
--- a/src/common/empty-trace-resolver.cc Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "empty-trace-resolver.h"
-
-ns3::EmptyTraceResolver::EmptyTraceResolver (TraceContext const &context)
- : TraceResolver (context)
-{}
--- a/src/common/empty-trace-resolver.h Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef EMPTY_TRACE_RESOLVER_H
-#define EMPTY_TRACE_RESOLVER_H
-
-#include "trace-resolver.h"
-
-namespace ns3 {
-
-class TraceContext;
-
-/**
- * \brief a TraceResolver instance which does not resolve anything.
- * \ingroup tracing
- *
- * Trying to resolve against this class will yield no matches and no
- * connections. Returning an instance of this class from a
- * CreateTraceResolver method is a hand way of not implementing
- * any Tracing code.
- */
-class EmptyTraceResolver : public TraceResolver
-{
-public:
- /**
- * \param o necessary context for this class.
- *
- * The only constructor exported by this class.
- */
- EmptyTraceResolver (TraceContext const &o);
-};
-
-}//namespace ns3
-
-#endif /* EMPTY_TRACE_RESOLVER_H */
--- a/src/common/fv-trace-source.h Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef F_VARIABLE_TRACER_H
-#define F_VARIABLE_TRACER_H
-
-#include "callback-trace-source.h"
-#include <stdint.h>
-
-namespace ns3 {
-
-class FVTraceSourceBase {
-public:
- typedef CallbackTraceSource<double, double> ChangeNotifyCallback;
-
- FVTraceSourceBase () {}
- FVTraceSourceBase (FVTraceSourceBase const &o) {}
- FVTraceSourceBase &operator = (FVTraceSourceBase const &o) {
- return *this;
- }
-
- ~FVTraceSourceBase () {}
-
- void AddCallback (CallbackBase const & callback, TraceContext const & context) {
- m_callback.AddCallback (callback, context);
- }
- void RemoveCallback (CallbackBase const & callback) {
- m_callback.RemoveCallback (callback);
- }
-protected:
- void notify (double oldVal, double newVal) {
- if (oldVal != newVal)
- {
- m_callback (oldVal, newVal);
- }
- }
-private:
- ChangeNotifyCallback m_callback;
-};
-
-template <typename T>
-class FVTraceSource : public FVTraceSourceBase
-{
-public:
-};
-
-}; // namespace ns3
-
-#endif /* F_VARIABLE_TRACER_H */
--- a/src/common/packet.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/common/packet.cc Tue Sep 11 14:52:15 2007 +0100
@@ -199,6 +199,12 @@
buffer.RemoveAtStart (metadataDeserialized);
}
+std::ostream& operator<< (std::ostream& os, const Packet &packet)
+{
+ packet.Print (os);
+ return os;
+}
+
} // namespace ns3
--- a/src/common/packet.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/common/packet.h Tue Sep 11 14:52:15 2007 +0100
@@ -328,6 +328,8 @@
static uint32_t m_globalUid;
};
+std::ostream& operator<< (std::ostream& os, const Packet &packet);
+
/**
* \defgroup packetperf Packet Performance
* The current implementation of the byte buffers and tag list is based
--- a/src/common/stream-tracer-test.cc Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "stream-tracer.h"
-#include "ns3/test.h"
-#include <iostream>
-
-#ifdef RUN_SELF_TESTS
-
-namespace {
-
-class TestStreamTracer : public ns3::Test {
-public:
- TestStreamTracer ();
- virtual bool RunTests (void);
-};
-
-static TestStreamTracer gTestStream;
-
-TestStreamTracer::TestStreamTracer ()
- : Test ("StreamTracer")
-{}
-
-bool
-TestStreamTracer::RunTests (void)
-{
- bool ok = true;
- ns3::StreamTracer trace;
- //trace.setStream (&std::cout);
- trace << 1;
- trace << " X ";
- trace << 1.0;
- trace << std::endl;
- trace << "test ";
- trace << 1 << " test";
- trace << "test "
- << 1.0 << " "
- << 0xdeadbead
- << std::endl;
- trace << "0x" << std::hex
- << 0xdeadbeaf
- << std::dec << " "
- << 0xdeadbeaf
- << std::endl;
- return ok;
-}
-
-
-}; // namespace ns3
-
-#endif /* RUN_SELF_TESTS */
--- a/src/common/stream-tracer.h Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef STREAM_TRACER_H
-#define STREAM_TRACER_H
-
-#include <ostream>
-
-namespace ns3 {
-
-/**
- * \brief log arbitrary data to std::ostreams
- *
- * Whenever operator << is invoked on this class,
- * it is forwarded to the stored std::ostream output
- * stream (if there is one).
- */
-class StreamTracer {
-public:
- StreamTracer ()
- : m_os (0) {}
- template <typename T>
- StreamTracer &operator << (T const&v) {
- if (m_os != 0)
- {
- (*m_os) << v;
- }
- return *this;
- }
- template <typename T>
- StreamTracer &operator << (T &v) {
- if (m_os != 0)
- {
- (*m_os) << v;
- }
- return *this;
- }
- StreamTracer &operator << (std::ostream &(*v) (std::ostream &)) {
- if (m_os != 0)
- {
- (*m_os) << v;
- }
- return *this;
- }
-
- /**
- * \param os the output stream to store
- */
- void SetStream (std::ostream * os) {
- m_os = os;
- }
-private:
- std::ostream *m_os;
-};
-
-}; // namespace ns3
-
-
-#endif /* TRACER_STREAM_H */
--- a/src/common/sv-trace-source.h Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,242 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef SV_TRACE_SOURCE_H
-#define SV_TRACE_SOURCE_H
-
-#include "callback-trace-source.h"
-#include <stdint.h>
-
-namespace ns3 {
-
-class SVTraceSourceBase {
-public:
- typedef CallbackTraceSource<int64_t, int64_t> ChangeNotifyCallback;
-
- SVTraceSourceBase () {}
- SVTraceSourceBase (SVTraceSourceBase const &o) {}
- SVTraceSourceBase &operator = (SVTraceSourceBase const &o) {
- return *this;
- }
-
- ~SVTraceSourceBase () {}
-
- void AddCallback (CallbackBase const & callback, TraceContext const & context) {
- m_callback.AddCallback (callback, context);
- }
- void RemoveCallback (CallbackBase const & callback) {
- m_callback.RemoveCallback (callback);
- }
-protected:
- void Notify (int64_t oldVal, int64_t newVal) {
- if (oldVal != newVal)
- {
- m_callback (oldVal, newVal);
- }
- }
-private:
- ChangeNotifyCallback m_callback;
-};
-
-template <typename T>
-class UVTraceSource;
-
-
-/**
- * \brief trace variables of type "signed integer"
- * \ingroup lowleveltracing
- *
- * This template class implements a POD type: it
- * behaves like any other variable of type "signed integer"
- * except that it also reports any changes to its
- * value with its internal callback.
- *
- * To instantiate a 32-bit signed variable (to store
- * a TCP counter for example), you would create a variable of type
- * ns3::UVTraceSource<int32_t> :
- \code
- #include <stdint.h>
- #include "ns3/sv-trace-source.h"
-
- ns3::SVTraceSource<uint16_t> var;
- \endcode
- * and you would use it like any other variable of type int32_t:
- \code
- var += 12;
- var = 10;
- var = -10;
- \endcode
- */
-template <typename T>
-class SVTraceSource : public SVTraceSourceBase {
-public:
- SVTraceSource ()
- : m_var (0)
- {}
- SVTraceSource (T const &var)
- : m_var (var)
- {}
-
- SVTraceSource &operator = (SVTraceSource const &o) {
- Assign (o.Get ());
- return *this;
- }
- template <typename TT>
- SVTraceSource &operator = (SVTraceSource<TT> const &o) {
- Assign (o.Get ());
- return *this;
- }
- template <typename TT>
- SVTraceSource &operator = (UVTraceSource<TT> const &o) {
- Assign (o.Get ());
- return *this;
- }
- SVTraceSource &operator++ () {
- Assign (Get () + 1);
- return *this;
- }
- SVTraceSource &operator-- () {
- Assign (Get () - 1);
- return *this;
- }
- SVTraceSource operator++ (int) {
- SVTraceSource old (*this);
- ++*this;
- return old;
- }
- SVTraceSource operator-- (int) {
- SVTraceSource old (*this);
- --*this;
- return old;
- }
- operator T () const {
- return Get ();
- }
-
-
- void Assign (T var) {
- Notify (m_var, var);
- m_var = var;
- }
- T Get (void) const {
- return m_var;
- }
-
-private:
- T m_var;
-};
-
-template <typename T>
-SVTraceSource<T> &operator += (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () + rhs.Get ());
- return lhs;
-}
-template <typename T>
-SVTraceSource<T> &operator -= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () - rhs.Get ());
- return lhs;
-}
-template <typename T>
-SVTraceSource<T> &operator *= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () * rhs.Get ());
- return lhs;
-}
-template <typename T>
-SVTraceSource<T> &operator /= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () / rhs.Get ());
- return lhs;
-}
-template <typename T>
-SVTraceSource<T> &operator <<= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () << rhs.Get ());
- return lhs;
-}
-template <typename T>
-SVTraceSource<T> &operator >>= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () >> rhs.Get ());
- return lhs;
-}
-template <typename T>
-SVTraceSource<T> &operator &= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () & rhs.Get ());
- return lhs;
-}
-template <typename T>
-SVTraceSource<T> &operator |= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () | rhs.Get ());
- return lhs;
-}
-template <typename T>
-SVTraceSource<T> &operator ^= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () ^ rhs.Get ());
- return lhs;
-}
-
-
-template <typename T, typename U>
-SVTraceSource<T> &operator += (SVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () + rhs);
- return lhs;
-}
-template <typename T, typename U>
-SVTraceSource<T> &operator -= (SVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () - rhs);
- return lhs;
-}
-template <typename T, typename U>
-SVTraceSource<T> &operator *= (SVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () * rhs);
- return lhs;
-}
-template <typename T, typename U>
-SVTraceSource<T> &operator /= (SVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () / rhs);
- return lhs;
-}
-template <typename T, typename U>
-SVTraceSource<T> &operator <<= (SVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () << rhs);
- return lhs;
-}
-template <typename T, typename U>
-SVTraceSource<T> &operator >>= (SVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () >> rhs);
- return lhs;
-}
-template <typename T, typename U>
-SVTraceSource<T> &operator &= (SVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () & rhs);
- return lhs;
-}
-template <typename T, typename U>
-SVTraceSource<T> &operator |= (SVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () | rhs);
- return lhs;
-}
-template <typename T, typename U>
-SVTraceSource<T> &operator ^= (SVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () ^ rhs);
- return lhs;
-}
-
-}; // namespace ns3
-
-#endif /* SV_TRACE_SOURCE_H */
--- a/src/common/terminal-trace-resolver.h Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef TERMINAL_TRACE_RESOLVER_H
-#define TERMINAL_TRACE_RESOLVER_H
-
-#include "trace-resolver.h"
-
-namespace ns3 {
-
-class TraceContext;
-
-template <typename T>
-class TerminalTraceResolver : public TraceResolver
-{
- public:
- TerminalTraceResolver (T &traceSource, TraceContext const &context);
- private:
- virtual void DoConnect (CallbackBase const &cb);
- virtual void DoDisconnect (CallbackBase const &cb);
- T &m_traceSource;
-};
-
-}//namespace ns3
-
-namespace ns3 {
-
-template <typename T>
-TerminalTraceResolver<T>::TerminalTraceResolver (T &traceSource,
- TraceContext const &context)
- : TraceResolver (context),
- m_traceSource (traceSource)
-{}
-template <typename T>
-void
-TerminalTraceResolver<T>::DoConnect (CallbackBase const &cb)
-{
- m_traceSource.AddCallback (cb, GetContext ());
-}
-template <typename T>
-void
-TerminalTraceResolver<T>::DoDisconnect (CallbackBase const &cb)
-{
- m_traceSource.RemoveCallback (cb);
-}
-
-}//namespace ns3
-
-#endif /* TERMINAL_TRACE_RESOLVER_H */
--- a/src/common/trace-context-element.cc Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-#include "trace-context-element.h"
-
-namespace ns3 {
-
-uint32_t
-ElementRegistry::GetSize (uint16_t uid)
-{
- InfoVector *vec = GetInfoVector ();
- struct Info info = (*vec)[uid - 1];
- return info.size;
-}
-void
-ElementRegistry::Print (uint16_t uid, uint8_t *instance, std::ostream &os)
-{
- InfoVector *vec = GetInfoVector ();
- struct Info info = (*vec)[uid - 1];
- info.print (instance, os);
-}
-void
-ElementRegistry::Destroy (uint16_t uid, uint8_t *instance)
-{
- InfoVector *vec = GetInfoVector ();
- struct Info info = (*vec)[uid - 1];
- info.destroy (instance);
-}
-ElementRegistry::InfoVector *
-ElementRegistry::GetInfoVector (void)
-{
- static InfoVector vector;
- return &vector;
-}
-
-
-} // namespace ns3
--- a/src/common/trace-context-element.h Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-#ifndef TRACE_CONTEXT_ELEMENT_H
-#define TRACE_CONTEXT_ELEMENT_H
-
-#include <string>
-#include <vector>
-
-#define NS_TRACE_CONTEXT_ELEMENT_ENSURE_REGISTERED(x) \
-namespace { \
-static class thisisaveryverylongclassname ##x \
- { \
- public: \
- thisisaveryverylongclassname ##x () \
- { uint32_t uid; uid = x::GetUid ();} \
- } g_thisisanotherveryveryverylongname ##x ; \
-}
-
-namespace ns3 {
-
-/**
- * \brief an item stored in a TraceContext
- *
- * To store trace context information in a TraceContext instance,
- * users must subclass this base class and store subclass instances
- * in a TraceContext with TraceContext::Add.
- *
- * Each subclass should define and implement:
- * - a public default constructor: it is used by the internals
- * of the implementation of TraceContext.
- * - a public destructor: it is also used by the internals of
- * the implementation of TraceContext.
- * - a public static method named GetUid which returns a 16 bit
- * integer. The integer returned from this method should be
- * allocated with the protected AllocatedUid method.
- * - a public Print method: this method is used by the
- * TraceContext::Print method to print the content of each
- * of the trace context element stored in the trace context.
- * This method takes a c++ output stream and argument and is
- * expected to write an ascii string describing its content
- * in this output stream.
- *
- * A typical subclass should look like this:
- * \code
- * class MyContext : public TraceContextElement
- * {
- * public:
- * // the _required_ public API
- * static uint16_t GetUid (void);
- * MyContext ();
- * ~MyContext ();
- * void Print (std::ostream &os) const;
- *
- * // the user-specific API to manipulate the context.
- * void SetData (uint8_t data);
- * uint8_t GetData (void) const;
- * private:
- * uint8_t m_myContextData;
- * };
- *
- * uint16_t
- * MyContext::GetUid (void)
- * {
- * static uint16_t uid = AllocateUid<MyContext> ("MyContext");
- * return uid;
- * }
- * MyContext::MyContext ()
- * {}
- * MyContext::~MyContext ()
- * {}
- * void
- * MyContext::Print (std::ostream &os) const
- * {
- * os << "mycontext=" << (uint32_t) m_myContextData;
- * }
- * void
- * MyContext::SetData (uint8_t data)
- * {
- * m_myContextData = data;
- * }
- * uint8_t
- * MyContext::GetData (void) const
- * {
- * return m_myContextData;
- * }
- * \endcode
- */
-class TraceContextElement
-{
-protected:
- /**
- * \param name a string which uniquely identifies the type
- * of the subclass which is calling this method.
- * \returns a unique 32 bit integer associated to the
- * input string.
- *
- * Subclasses are expected to call this method from their
- * public static GetUid method.
- */
- template <typename T>
- static uint16_t AllocateUid (std::string name);
-};
-
-} // namespace ns3
-
-namespace ns3 {
-
-/**
- * \brief a registry of TraceContextElement subclasses
- * \internal
- */
-class ElementRegistry
-{
-public:
- template <typename T>
- static uint16_t AllocateUid (std::string name);
-
- static uint32_t GetSize (uint16_t uid);
- static void Print (uint16_t uid, uint8_t *instance, std::ostream &os);
- static void Destroy (uint16_t uid, uint8_t *instance);
-private:
- typedef void (*PrintCb) (uint8_t *instance, std::ostream &os);
- typedef void (*DestroyCb) (uint8_t *instance);
- struct Info {
- uint32_t size;
- std::string uidString;
- PrintCb print;
- DestroyCb destroy;
- };
- typedef std::vector<struct Info> InfoVector;
- static InfoVector *GetInfoVector (void);
- template <typename T>
- static void DoPrint (uint8_t *instance, std::ostream &os);
- template <typename T>
- static void DoDestroy (uint8_t *instance);
-};
-
-template <typename T>
-void
-ElementRegistry::DoPrint (uint8_t *instance, std::ostream &os)
-{
- static T obj;
- // make sure we are aligned.
- memcpy ((void*)&obj, instance, sizeof (T));
- obj.Print (os);
-}
-template <typename T>
-void
-ElementRegistry::DoDestroy (uint8_t *instance)
-{
- static T obj;
- // make sure we are aligned.
- memcpy ((void*)&obj, instance, sizeof (T));
- obj.~T ();
-}
-
-template <typename T>
-uint16_t
-ElementRegistry::AllocateUid (std::string name)
-{
- InfoVector *vec = GetInfoVector ();
- uint16_t uid = 1;
- for (InfoVector::iterator i = vec->begin (); i != vec->end (); i++)
- {
- if (i->uidString == name)
- {
- return uid;
- }
- uid++;
- }
- struct Info info;
- info.size = sizeof (T);
- info.uidString = name;
- info.print = &ElementRegistry::DoPrint<T>;
- info.destroy = &ElementRegistry::DoDestroy<T>;
- vec->push_back (info);
- return vec->size ();
-}
-
-
-
-template <typename T>
-uint16_t
-TraceContextElement::AllocateUid (std::string name)
-{
- return ElementRegistry::AllocateUid<T> (name);
-}
-
-} // namespace ns3
-
-#endif /* TRACE_CONTEXT_ELEMENT_H */
--- a/src/common/trace-context.cc Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,330 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "trace-context.h"
-#include "trace-context-element.h"
-#include "ns3/assert.h"
-
-namespace ns3 {
-
-TraceContext::TraceContext ()
- : m_data (0)
-{}
-TraceContext::TraceContext (TraceContext const &o)
- : m_data (o.m_data)
-{
- if (m_data != 0)
- {
- m_data->count++;
- }
-}
-TraceContext const &
-TraceContext::operator = (TraceContext const &o)
-{
- if (m_data != 0)
- {
- m_data->count--;
- if (m_data->count == 0)
- {
- uint8_t *buffer = (uint8_t *)m_data;
- delete [] buffer;
- }
- }
- m_data = o.m_data;
- if (m_data != 0)
- {
- m_data->count++;
- }
- return *this;
-}
-TraceContext::~TraceContext ()
-{
- if (m_data != 0)
- {
- m_data->count--;
- if (m_data->count == 0)
- {
- uint8_t *buffer = (uint8_t *)m_data;
- delete [] buffer;
- }
- }
-}
-
-void
-TraceContext::Add (TraceContext const &o)
-{
- if (o.m_data == 0)
- {
- return;
- }
- uint16_t currentUid;
- uint16_t i = 0;
- while (i < o.m_data->size)
- {
- currentUid = o.m_data->data[i];
- uint8_t size = ElementRegistry::GetSize (currentUid);
- uint8_t *selfBuffer = CheckPresent (currentUid);
- uint8_t *otherBuffer = &(o.m_data->data[i+1]);
- if (selfBuffer != 0)
- {
- if (memcmp (selfBuffer, otherBuffer, size) != 0)
- {
- NS_FATAL_ERROR ("You cannot add TraceContexts which "<<
- "have different values stored in them.");
- }
- }
- else
- {
- DoAdd (currentUid, otherBuffer);
- }
- i += 1 + size;
- }
-}
-
-uint8_t *
-TraceContext::CheckPresent (uint8_t uid) const
-{
- if (m_data == 0)
- {
- return false;
- }
- uint8_t currentUid;
- uint16_t i = 0;
- do {
- currentUid = m_data->data[i];
- uint8_t size = ElementRegistry::GetSize (currentUid);
- if (currentUid == uid)
- {
- return &m_data->data[i+1];
- }
- i += 1 + size;
- } while (i < m_data->size && currentUid != 0);
- return 0;
-}
-
-
-bool
-TraceContext::DoAdd (uint8_t uid, uint8_t const *buffer)
-{
- NS_ASSERT (uid != 0);
- uint8_t size = ElementRegistry::GetSize (uid);
- uint8_t *present = CheckPresent (uid);
- if (present != 0) {
- if (memcmp (present, buffer, size) == 0)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- if (m_data == 0)
- {
- uint16_t newSize = 1 + size;
- uint16_t allocatedSize;
- if (newSize > 4)
- {
- allocatedSize = sizeof (struct Data) + newSize - 4;
- }
- else
- {
- allocatedSize = sizeof (struct Data);
- }
- struct Data *data = (struct Data *) (new uint8_t [allocatedSize] ());
- data->size = newSize;
- data->count = 1;
- data->data[0] = uid;
- memcpy (data->data + 1, buffer, size);
- m_data = data;
- }
- else
- {
- uint16_t newSize = m_data->size + 1 + size;
- uint16_t allocatedSize;
- if (newSize > 4)
- {
- allocatedSize = sizeof (struct Data) + newSize - 4;
- }
- else
- {
- allocatedSize = sizeof (struct Data);
- }
- struct Data *data = (struct Data *) (new uint8_t [allocatedSize] ());
- data->size = newSize;
- data->count = 1;
- memcpy (data->data, m_data->data, m_data->size);
- data->data[m_data->size] = uid;
- memcpy (data->data + m_data->size + 1, buffer, size);
- m_data->count--;
- if (m_data->count == 0)
- {
- uint8_t *buffer = (uint8_t *)m_data;
- delete [] buffer;
- }
- m_data = data;
- }
- return true;
-}
-bool
-TraceContext::DoGet (uint8_t uid, uint8_t *buffer) const
-{
- if (m_data == 0)
- {
- return false;
- }
- uint8_t currentUid;
- uint16_t i = 0;
- do {
- currentUid = m_data->data[i];
- uint8_t size = ElementRegistry::GetSize (currentUid);
- if (currentUid == uid)
- {
- memcpy (buffer, &m_data->data[i+1], size);
- return true;
- }
- i += 1 + size;
- } while (i < m_data->size && currentUid != 0);
- return false;
-}
-
-void
-TraceContext::Print (std::ostream &os) const
-{
- if (m_data == 0)
- {
- return;
- }
- uint8_t currentUid;
- uint16_t i = 0;
- do {
- currentUid = m_data->data[i];
- uint8_t size = ElementRegistry::GetSize (currentUid);
- uint8_t *instance = &m_data->data[i+1];
- ElementRegistry::Print (currentUid, instance, os);
- i += 1 + size;
- if (i < m_data->size && currentUid != 0)
- {
- os << " ";
- }
- else
- {
- break;
- }
- } while (true);
-}
-
-}//namespace ns3
-
-#include "ns3/test.h"
-#include <sstream>
-
-namespace ns3 {
-
-template <int N>
-class Ctx : public TraceContextElement
-{
-public:
- static uint16_t GetUid (void) {static uint16_t uid = AllocateUid<Ctx<N> > (GetName ()); return uid;}
- static std::string GetName (void) {std::ostringstream oss; oss << "Ctx" << N; return oss.str ();}
- Ctx () : m_v (0) {}
- Ctx (int v) : m_v (v) {}
- void Print (std::ostream &os) {os << N;}
- int Get (void) const { return N;}
-private:
- int m_v;
-};
-
-class TraceContextTest : public Test
-{
-public:
- TraceContextTest ();
- virtual bool RunTests (void);
-};
-
-TraceContextTest::TraceContextTest ()
- : Test ("TraceContext")
-{}
-bool
-TraceContextTest::RunTests (void)
-{
- bool ok = true;
-
- TraceContext ctx;
- Ctx<0> v0;
- Ctx<0> v01 = Ctx<0> (1);
- Ctx<1> v1;
- Ctx<2> v2;
- Ctx<3> v3;
-
- if (ctx.SafeGet (v0))
- {
- ok = false;
- }
- ctx.Add (v0);
- ctx.Add (v0);
- if (ctx.SafeAdd (v01))
- {
- ok = false;
- }
- ctx.Get (v0);
- ctx.Add (v1);
- ctx.Get (v1);
- ctx.Get (v0);
- ctx.Get (v1);
-
- TraceContext copy = ctx;
- ctx.Get (v0);
- ctx.Get (v1);
- copy.Get (v0);
- copy.Get (v1);
- copy.Add (v2);
- copy.Get (v0);
- copy.Get (v1);
- copy.Get (v2);
- ctx.Add (v3);
- ctx.Get (v0);
- ctx.Get (v1);
- ctx.Get (v3);
-
- if (ctx.SafeGet (v2))
- {
- ok = false;
- }
- if (copy.SafeGet (v3))
- {
- ok = false;
- }
- ctx.Add (copy);
- ctx.Get (v2);
- if (copy.SafeGet (v3))
- {
- ok = false;
- }
- copy.Add (ctx);
- copy.Get (v3);
-
- return ok;
-}
-
-static TraceContextTest g_traceContextTest;
-
-
-}//namespace ns3
--- a/src/common/trace-context.h Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef TRACE_CONTEXT_H
-#define TRACE_CONTEXT_H
-
-#include <stdint.h>
-#include <vector>
-#include "ns3/fatal-error.h"
-#include "trace-context-element.h"
-
-namespace ns3 {
-
-/**
- * \brief Provide context to trace sources
- * \ingroup lowleveltracing
- *
- * Instances of this class are used to hold context
- * for each trace source. Each instance holds a list of
- * 'contexts'. Trace sinks can lookup these contexts
- * from this list with the ns3::TraceContext::Get method.
- *
- * This class is implemented
- * using Copy On Write which means that copying unmodified
- * versions of this class is very cheap. However, modifying
- * the content of this class through a call
- * to ns3::TraceContext::Add will trigger a costly memory
- * reallocation if needed.
- */
-class TraceContext
-{
-public:
- TraceContext ();
- TraceContext (TraceContext const &o);
- TraceContext const & operator = (TraceContext const &o);
- ~TraceContext ();
-
- /**
- * \param context add context to list of trace contexts.
- */
- template <typename T>
- void Add (T const &context);
-
- /**
- * \param o the other context
- *
- * Perform the Union operation (in the sense of set theory) on the
- * two input lists of elements. This method is used in the
- * ns3::CallbackTraceSourceSource class when multiple sinks are connected
- * to a single source to ensure that the source does not need
- * to store a single TraceContext instance per connected sink.
- * Instead, all sinks share the same TraceContext.
- */
- void Add (TraceContext const &o);
-
- /**
- * \param context context to get from this list of trace contexts.
- *
- * This method cannot fail. If the requested trace context is not
- * stored in this TraceContext, then, the program will halt.
- */
- template <typename T>
- void Get (T &context) const;
-
- void Print (std::ostream &os) const;
-private:
- friend class TraceContextTest;
- // used exclusively for testing code.
- template <typename T>
- bool SafeGet (T &context) const;
- template <typename T>
- bool SafeAdd (const T &context);
-
- uint8_t *CheckPresent (uint8_t uid) const;
- bool DoAdd (uint8_t uid, uint8_t const *buffer);
- bool DoGet (uint8_t uid, uint8_t *buffer) const;
-
- struct Data {
- uint16_t count;
- uint16_t size;
- uint8_t data[4];
- } * m_data;
-};
-
-}//namespace ns3
-
-namespace ns3 {
-
-template <typename T>
-void
-TraceContext::Add (T const &context)
-{
- const TraceContextElement *parent;
- // if the following assignment fails, it is because the input
- // to this function is not a subclass of the TraceContextElement class.
- parent = &context;
- uint8_t *data = (uint8_t *) &context;
- bool ok = DoAdd (T::GetUid (), data);
- if (!ok)
- {
- NS_FATAL_ERROR ("Trying to add twice the same type with different values is invalid.");
- }
-}
-template <typename T>
-void
-TraceContext::Get (T &context) const
-{
- TraceContextElement *parent;
- // if the following assignment fails, it is because the input
- // to this function is not a subclass of the TraceContextElement class.
- parent = &context;
- uint8_t *data = (uint8_t *) &context;
- bool found = DoGet (T::GetUid (), data);
- if (!found)
- {
- NS_FATAL_ERROR ("Type not stored in TraceContext");
- }
-}
-template <typename T>
-bool
-TraceContext::SafeGet (T &context) const
-{
- TraceContextElement *parent;
- // if the following assignment fails, it is because the input
- // to this function is not a subclass of the TraceContextElement class.
- parent = &context;
- uint8_t *data = (uint8_t *) &context;
- bool found = DoGet (T::GetUid (), data);
- return found;
-}
-template <typename T>
-bool
-TraceContext::SafeAdd (const T &context)
-{
- const TraceContextElement *parent;
- // if the following assignment fails, it is because the input
- // to this function is not a subclass of the TraceContextElement class.
- parent = &context;
- uint8_t *data = (uint8_t *) &context;
- bool ok = DoAdd (T::GetUid (), data);
- return ok;
-}
-}//namespace ns3
-
-#endif /* TRACE_CONTEXT_H */
--- a/src/common/trace-resolver.cc Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "trace-resolver.h"
-
-namespace ns3 {
-
-TraceResolver::TraceResolver (TraceContext const &context)
- : m_context (context)
-{}
-
-TraceResolver::~TraceResolver ()
-{}
-
-TraceContext const &
-TraceResolver::GetContext (void) const
-{
- return m_context;
-}
-
-void
-TraceResolver::Connect (std::string path, CallbackBase const &cb)
-{
- std::string::size_type cur = 1;
- // check that first char is "/"
- std::string::size_type next = path.find ("/", cur);
- std::string element = std::string (path, cur, next-1);
- TraceResolverList resolverList = DoLookup (element);
- for (TraceResolverList::iterator i = resolverList.begin (); i != resolverList.end (); i++)
- {
- TraceResolver *resolver = *i;
- if (next == std::string::npos)
- {
- // we really break the recursion here.
- resolver->DoConnect (cb);
- }
- else
- {
- std::string subpath = std::string (path, next, std::string::npos);
- resolver->Connect (subpath, cb);
- }
- delete resolver;
- }
- resolverList.erase (resolverList.begin (), resolverList.end ());
-}
-
-void
-TraceResolver::Disconnect (std::string path, CallbackBase const &cb)
-{
- std::string::size_type cur = 1;
- // check that first char is "/"
- std::string::size_type next = path.find ("/", cur);
- std::string element = std::string (path, cur, next-1);
- TraceResolverList resolverList = DoLookup (element);
- for (TraceResolverList::iterator i = resolverList.begin (); i != resolverList.end (); i++)
- {
- TraceResolver *resolver = *i;
- if (next == std::string::npos)
- {
- // we really break the recursion here.
- resolver->DoDisconnect (cb);
- }
- else
- {
- std::string subpath = std::string (path, next, std::string::npos);
- resolver->Disconnect (subpath, cb);
- }
- delete resolver;
- }
- resolverList.erase (resolverList.begin (), resolverList.end ());
-}
-
-TraceResolver::TraceResolverList
-TraceResolver::DoLookup (std::string id) const
-{
- return TraceResolverList ();
-}
-void
-TraceResolver::DoConnect (CallbackBase const &cb)
-{}
-
-void
-TraceResolver::DoDisconnect (CallbackBase const &cb)
-{}
-
-
-}//namespace ns3
--- a/src/common/trace-resolver.h Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef TRACE_RESOLVER_H
-#define TRACE_RESOLVER_H
-
-#include <string>
-#include <list>
-#include "trace-context.h"
-
-namespace ns3 {
-
-class CallbackBase;
-
-/**
- * \brief the base class which is used to incremental perform trace
- * namespace resolution.
- * \ingroup lowleveltracing
- *
- * This class provides a public API to the ns3::TraceRoot object:
- * - ns3::TraceResolver::Connect
- * - ns3::TraceResolver::Disconnect
- *
- * It also provides an API for its subclasses. Each subclass should
- * implement one of:
- * - ns3::TraceResolver::DoLookup
- * - ns3::TraceResolver::DoConnect and ns3::TraceResolver::DoDisconnect
- * Each subclass must also provide an ns3::TraceContext to the TraceResolver
- * constructor. Finally, each subclass can access the ns3::TraceContext
- * associated to this ns3::TraceResolver through the
- * ns3::TraceResolver::GetContext method.
- */
-class TraceResolver
-{
-public:
- virtual ~TraceResolver ();
- /**
- * \param path the namespace path to resolver
- * \param cb the callback to connect to the matching namespace
- *
- * This method is typically invoked by ns3::TraceRoot but advanced
- * users could also conceivably call it directly if they want to
- * skip the ns3::TraceRoot.
- */
- void Connect (std::string path, CallbackBase const &cb);
- /**
- * \param path the namespace path to resolver
- * \param cb the callback to disconnect in the matching namespace
- *
- * This method is typically invoked by ns3::TraceRoot but advanced
- * users could also conceivably call it directly if they want to
- * skip the ns3::TraceRoot.
- */
- void Disconnect (std::string path, CallbackBase const &cb);
-protected:
- /**
- * \param context the context used to initialize this TraceResolver.
- *
- * Every subclass must call this constructor
- */
- TraceResolver (TraceContext const &context);
- /**
- * \returns the ns3::TraceContext stored in this ns3::TraceResolver.
- *
- * Subclasses usually invoke this method to get access to the
- * TraceContext stored here to pass it down to the TraceResolver
- * constructors invoked from within the DoLookup method.
- */
- TraceContext const &GetContext (void) const;
- typedef std::list<TraceResolver *> TraceResolverList;
-private:
- TraceResolver ();
- /**
- * \param id the id to resolve. This is supposed to be
- * one element of the global tracing namespace.
- * \returns a list of reslvers which match the input namespace element
- *
- * A subclass which overrides this method should return a potentially
- * empty list of pointers to ns3::TraceResolver instances which match
- * the input namespace element. Each of these TraceResolver should be
- * instanciated with a TraceContext which holds enough context
- * information to identify the type of the TraceResolver.
- */
- virtual TraceResolverList DoLookup (std::string id) const;
- /**
- * \param cb callback to connect
- *
- * This method is invoked on leaf trace resolvers.
- */
- virtual void DoConnect (CallbackBase const &cb);
- /**
- * \param cb callback to disconnect
- *
- * This method is invoked on leaf trace resolvers.
- */
- virtual void DoDisconnect (CallbackBase const &cb);
- TraceContext m_context;
-};
-
-}//namespace ns3
-
-#endif /* TRACE_RESOLVER_H */
--- a/src/common/trace-root.cc Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "trace-root.h"
-#include "ns3/composite-trace-resolver.h"
-#include "ns3/trace-context.h"
-
-namespace ns3 {
-
-void
-TraceRoot::Connect (std::string path, CallbackBase const &cb)
-{
- TraceResolver *resolver = GetComposite ();
- resolver->Connect (path, cb);
-}
-void
-TraceRoot::Disconnect (std::string path, CallbackBase const &cb)
-{
- TraceResolver *resolver = GetComposite ();
- resolver->Disconnect (path, cb);
-}
-void
-TraceRoot::Register (std::string name,
- Callback<TraceResolver *,TraceContext const &> createResolver)
-{
- CompositeTraceResolver *resolver = GetComposite ();
- resolver->Add (name, createResolver);
-}
-
-CompositeTraceResolver *
-TraceRoot::GetComposite (void)
-{
- static CompositeTraceResolver resolver = CompositeTraceResolver (TraceContext ());
- return &resolver;
-}
-
-} // namespace ns3
--- a/src/common/trace-root.h Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,335 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef TRACE_ROOT_H
-#define TRACE_ROOT_H
-
-#include <string>
-#include "ns3/callback.h"
-
-/**
- * \defgroup lowleveltracing Low-level tracing
- *
- * 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,
- * ns3::SVTraceSource, and, ns3::FVTraceSource.
- * - Each trace source can be connected to any number of trace sinks.
- * A trace sink is a ns3::Callback with a very special signature. Its
- * first argument is always a ns3::TraceContext.
- * - Every trace source is uniquely identified by a ns3::TraceContext. Every
- * trace sink can query a ns3::TraceContext for information. This allows
- * a trace sink which is connected to multiple trace sources to identify
- * from which source each event is coming from.
- *
- * 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.
- *
- * 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
- * /queue/
- * /enque
- * /deque
- * /drop
- * \endcode
- *
- * The 'n' element which follows the /nodes and /interfaces namespace elements
- * identify a specific node and interface through their index within the
- * ns3::NodeList and ns3::Ipv4 objects respectively.
- *
- * To connect a trace sink to a trace source identified by a namespace string,
- * a user can call the ns3::TraceRoot::Connect method (the ns3::TraceRoot::Disconnect
- * method does the symmetric operation). This connection method can accept
- * fully-detailed namespace strings but it can also perform pattern matching
- * on the user-provided namespace strings to connect multiple trace sources
- * to a single trace sink in a single connection operation.
- *
- * The syntax of the pattern matching rules are loosely based on regular
- * expressions:
- * - the '*' character matches every element
- * - the (a|b) construct matches element 'a' or 'b'
- * - the [ss-ee] construct matches all numerical values which belong
- * to the interval which includes ss and ee
- *
- * For example, the user could use the following to connect a single sink
- * to the ipv4 tx, rx, and drop trace events:
- *
- * \code
- * void MyTraceSink (TraceContext const &context, Packet &packet);
- * TraceRoot::Connect ("/nodes/ * /ipv4/ *", MakeCallback (&MyTraceSink));
- * \endcode
- *
- * Of course, this code would work only if the signature of the trace sink
- * is exactly equal to the signature of all the trace sources which match
- * the namespace string (if one of the matching trace source does not match
- * exactly, a fatal error will be triggered at runtime during the connection
- * process). The ns3::TraceContext extra argument contains
- * information on where the trace source is located in the namespace tree.
- * In that example, if there are multiple nodes in this scenario, each
- * call to the MyTraceSink function would receive a different TraceContext,
- * each of which would contain a different NodeList::NodeIndex object.
- *
- * It is important to understand exactly what an ns3::TraceContext
- * is. It is a container for a number of type instances. Each instance of
- * a ns3::TraceContext contains one and only one instance of a given type.
- * ns3::TraceContext::Add can be called to add a type instance into a
- * TraceContext instance and ns3::TraceContext::Get can be called to get
- * a copy of a type instance stored into the ns3::TraceContext. If ::Get
- * cannot retrieve the requested type, a fatal error is triggered at
- * runtime. The values stored into an ns3::TraceContext attached to a
- * trace source are automatically determined during the namespace
- * resolution process. To retrieve a value from a ns3::TraceContext, the
- * code can be as simple as this:
- * \code
- * void MyTraceSink (TraceContext const &context, Packet &packet)
- * {
- * NodeList::NodeIndex index;
- * context.Get (index);
- * std::cout << "node id=" << NodeList::GetNode (index)->GetId () << std::endl;
- * }
- * \endcode
- *
- * 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.
- *
- * 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:
- * - 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. 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
- * algorithm. The code of that algorithm is wholy contained in the
- * ns3::TraceResolver::Connect and ns3::TraceResolver::Disconnect methods.
- * The idea is that we recursively parse the input namespace string by removing
- * the first namespace element. This element is 'resolved' is calling
- * the ns3::TraceResolver::DoLookup method which returns a list of
- * TraceResolver instances. Each of the returned TraceResolver instance is
- * then given what is left of the namespace by calling ns3::TraceResolver::Connect
- * until the last namespace element is processed. At this point, we invoke
- * the ns3::TraceResolver::DoConnect or ns3::TraceResolver::DoDisconnect
- * methods to break the recursion. A good way to understand this algorithm
- * is to trace its behavior. Let's say that you want to connect to
- * '/nodes/ * /ipv4/interfaces/ * /netdevice/queue/ *'. It would generate
- * the following call traces:
- *
- * \code
- * 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
- */
-
-namespace ns3 {
-
-class CompositeTraceResolver;
-class TraceResolver;
-class TraceContext;
-class CallbackBase;
-
-/**
- * \brief The main class used to access tracing functionality for
- * a user.
- *
- * \ingroup lowleveltracing
- */
-class TraceRoot
-{
-public:
- static void Connect (std::string path, CallbackBase const &cb);
- static void Disconnect (std::string path, CallbackBase const &cb);
- static void Register (std::string name,
- Callback<TraceResolver *,TraceContext const &> createResolver);
-private:
- static CompositeTraceResolver *GetComposite (void);
-};
-
-}// namespace ns3
-
-#endif /* TRACE_ROOT_H */
--- a/src/common/uv-trace-source.h Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,245 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef UV_TRACE_SOURCE_H
-#define UV_TRACE_SOURCE_H
-
-#include "callback-trace-source.h"
-#include <stdint.h>
-
-namespace ns3 {
-
-class UVTraceSourceBase {
-public:
- typedef CallbackTraceSource<uint64_t, uint64_t> ChangeNotifyCallback;
-
- UVTraceSourceBase ()
- : m_callback () {}
- /* We don't want to copy the base callback. Only setCallback on
- * a specific instance will do something to it. */
- UVTraceSourceBase (UVTraceSourceBase const &o)
- : m_callback () {}
- UVTraceSourceBase &operator = (UVTraceSourceBase const &o) {
- return *this;
- }
- ~UVTraceSourceBase () {}
-
- void AddCallback (CallbackBase const & callback, TraceContext const & context) {
- m_callback.AddCallback (callback, context);
- }
- void RemoveCallback (CallbackBase const & callback) {
- m_callback.RemoveCallback (callback);
- }
-
-protected:
- void Notify (uint64_t oldVal, uint64_t newVal) {
- if (oldVal != newVal)
- {
- m_callback (oldVal, newVal);
- }
- }
-private:
- ChangeNotifyCallback m_callback;
-};
-
-template <typename T>
-class SVTraceSource;
-
-
-/**
- * \brief trace variables of type "unsigned integer"
- * \ingroup lowleveltracing
- *
- * This template class implements a POD type: it
- * behaves like any other variable of type "unsigned integer"
- * except that it also reports any changes to its
- * value with its internal callback.
- *
- * To instantiate a 32-bit unsigned variable (to store
- * a TCP counter for example), you would create a variable of type
- * ns3::UVTraceSource<uint32_t> :
- \code
- #include <stdint.h>
- #include "ns3/uv-trace-source.h"
-
- ns3::UVTraceSource<uint32_t> var;
- \endcode
- * and you would use it like any other variable of type uint32_t:
- \code
- var += 12;
- var = 10;
- \endcode
- */
-template <typename T>
-class UVTraceSource : public UVTraceSourceBase {
-public:
- UVTraceSource ()
- : m_var ()
- {}
- UVTraceSource (T const &var)
- : m_var (var)
- {}
-
- UVTraceSource &operator = (UVTraceSource const &o) {
- Assign (o.Get ());
- return *this;
- }
- template <typename TT>
- UVTraceSource &operator = (UVTraceSource<TT> const &o) {
- Assign (o.Get ());
- return *this;
- }
- template <typename TT>
- UVTraceSource &operator = (SVTraceSource<TT> const &o) {
- Assign (o.Get ());
- return *this;
- }
- UVTraceSource &operator++ () {
- Assign (Get () + 1);
- return *this;
- }
- UVTraceSource &operator-- () {
- Assign (Get () - 1);
- return *this;
- }
- UVTraceSource operator++ (int) {
- UVTraceSource old (*this);
- ++*this;
- return old;
- }
- UVTraceSource operator-- (int) {
- UVTraceSource old (*this);
- --*this;
- return old;
- }
- operator T () const {
- return Get ();
- }
-
-
- void Assign (T var) {
- Notify (m_var, var);
- m_var = var;
- }
- T Get (void) const {
- return m_var;
- }
-
-private:
- T m_var;
-};
-
-template <typename T>
-UVTraceSource<T> &operator += (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () + rhs.Get ());
- return lhs;
-}
-template <typename T>
-UVTraceSource<T> &operator -= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () - rhs.Get ());
- return lhs;
-}
-template <typename T>
-UVTraceSource<T> &operator *= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () * rhs.Get ());
- return lhs;
-}
-template <typename T>
-UVTraceSource<T> &operator /= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () / rhs.Get ());
- return lhs;
-}
-template <typename T>
-UVTraceSource<T> &operator <<= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () << rhs.Get ());
- return lhs;
-}
-template <typename T>
-UVTraceSource<T> &operator >>= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () >> rhs.Get ());
- return lhs;
-}
-template <typename T>
-UVTraceSource<T> &operator &= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () & rhs.Get ());
- return lhs;
-}
-template <typename T>
-UVTraceSource<T> &operator |= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () | rhs.Get ());
- return lhs;
-}
-template <typename T>
-UVTraceSource<T> &operator ^= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
- lhs.Assign (lhs.Get () ^ rhs.Get ());
- return lhs;
-}
-
-
-template <typename T, typename U>
-UVTraceSource<T> &operator += (UVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () + rhs);
- return lhs;
-}
-template <typename T, typename U>
-UVTraceSource<T> &operator -= (UVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () - rhs);
- return lhs;
-}
-template <typename T, typename U>
-UVTraceSource<T> &operator *= (UVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () * rhs);
- return lhs;
-}
-template <typename T, typename U>
-UVTraceSource<T> &operator /= (UVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () / rhs);
- return lhs;
-}
-template <typename T, typename U>
-UVTraceSource<T> &operator <<= (UVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () << rhs);
- return lhs;
-}
-template <typename T, typename U>
-UVTraceSource<T> &operator >>= (UVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () >> rhs);
- return lhs;
-}
-template <typename T, typename U>
-UVTraceSource<T> &operator &= (UVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () & rhs);
- return lhs;
-}
-template <typename T, typename U>
-UVTraceSource<T> &operator |= (UVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () | rhs);
- return lhs;
-}
-template <typename T, typename U>
-UVTraceSource<T> &operator ^= (UVTraceSource<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () ^ rhs);
- return lhs;
-}
-
-}; // namespace ns3
-
-#endif /* UV_TRACE_SOURCE_H */
--- a/src/common/variable-tracer-test.cc Thu Sep 06 15:18:14 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,272 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "uv-trace-source.h"
-#include "sv-trace-source.h"
-#include "trace-context.h"
-#include "ns3/test.h"
-#include "ns3/callback.h"
-
-
-namespace ns3 {
-
-class Foo {
-public:
- void Notify (TraceContext const &contex, uint64_t oldVal, uint64_t newVal) {}
-};
-
-class VariableTracerTest: public Test {
-public:
- VariableTracerTest ();
- void RunUnsignedTests (void);
- void RunSignedUnsignedTests (void);
- virtual bool RunTests (void);
-};
-void
-VariableTracerTest::RunUnsignedTests (void)
-{
- UVTraceSource<uint32_t> var, ovar, tmp;
- uint32_t utmp;
- Foo *foo = new Foo ();
-
- var.AddCallback (MakeCallback (&Foo::Notify, foo), TraceContext ());
-
- var = 10;
- ovar = var;
-
- if (var == ovar)
- {
- }
- if (var != ovar)
- {
- }
- if (var > ovar)
- {
- }
- if (var >= ovar)
- {
- }
- if (var < ovar)
- {
- }
-
- if (var <= ovar)
-
- if (var == 1)
- {
- }
- if (var != 1)
- {
- }
- if (var > 1)
- {
- }
- if (var >= 1)
- {
- }
- if (var < 1)
- {
- }
- if (var <= 1)
- {
- }
-
- if (1 == ovar)
- {
- }
- if (1 != ovar)
- {
- }
- if (1 > ovar)
- {
- }
- if (1 >= ovar)
- {
- }
- if (1 < ovar)
- {
- }
- if (1 <= ovar)
- {
- }
-
- var++;
- ++var;
- var--;
- --var;
-
- tmp = var + ovar;
- tmp = var - ovar;
- tmp = var / ovar;
- tmp = var * ovar;
- tmp = var << ovar;
- tmp = var >> ovar;
- tmp = var & ovar;
- tmp = var | ovar;
- tmp = var ^ ovar;
-
- tmp = var + 1;
- tmp = var - 1;
- tmp = var / 1;
- tmp = var * 1;
- tmp = var << 1;
- tmp = var >> 1;
- tmp = var & 1;
- tmp = var | 1;
- tmp = var ^ 1;
-
- tmp = 1 + ovar;
- tmp = 1 - ovar;
- tmp = 1 / ovar;
- tmp = 1 * ovar;
- tmp = 1 << ovar;
- tmp = 1 >> ovar;
- tmp = 1 & ovar;
- tmp = 1 | ovar;
- tmp = 1 ^ ovar;
-
- tmp += var;
- tmp -= var;
- tmp /= var;
- tmp *= var;
- tmp <<= var;
- tmp >>= var;
- tmp &= var;
- tmp |= var;
- tmp ^= var;
-
- tmp += 1;
- tmp -= 1;
- tmp /= 1;
- tmp *= 1;
- tmp <<= 1;
- tmp >>= 1;
- tmp &= 1;
- tmp |= 1;
- tmp ^= 1;
-
-
- utmp = var + ovar;
- utmp = var - ovar;
- utmp = var / ovar;
- utmp = var * ovar;
- utmp = var << ovar;
- utmp = var >> ovar;
- utmp = var & ovar;
- utmp = var | ovar;
- utmp = var ^ ovar;
-
- utmp = var + 1;
- utmp = var - 1;
- utmp = var / 1;
- utmp = var * 1;
- utmp = var << 1;
- utmp = var >> 1;
- utmp = var & 1;
- utmp = var | 1;
- utmp = var ^ 1;
-
- utmp = 1 + ovar;
- utmp = 1 - ovar;
- utmp = 1 / ovar;
- utmp = 1 * ovar;
- utmp = 1 << ovar;
- utmp = 1 >> ovar;
- utmp = 1 & ovar;
- utmp = 1 | ovar;
- utmp = 1 ^ ovar;
-
- utmp += var;
- utmp -= var;
- utmp /= var;
- utmp *= var;
- utmp <<= var;
- utmp >>= var;
- utmp &= var;
- utmp |= var;
- utmp ^= var;
-
- utmp += 1;
- utmp -= 1;
- utmp /= 1;
- utmp *= 1;
- utmp <<= 1;
- utmp >>= 1;
- utmp &= 1;
- utmp |= 1;
- utmp ^= 1;
-
- delete foo;
-}
-
-void
-VariableTracerTest::RunSignedUnsignedTests (void)
-{
- unsigned short utmp = 10;
- unsigned int uitmp = 7;
- short stmp = 5;
- utmp = stmp;
- utmp += stmp;
- uitmp = utmp;
- utmp = uitmp;
-
- UVTraceSource<unsigned short> uvar = 10;
- UVTraceSource<unsigned int> uivar = 5;
- SVTraceSource<short> svar = 5;
- SVTraceSource<int> sivar = 5;
- uvar = svar;
- svar = uvar;
- uvar += svar;
- svar += uvar;
-
- uvar = sivar;
- sivar = uvar;
- uvar += sivar;
- sivar += uvar;
-
- uivar = uvar;
- uvar = uivar;
- uivar += uvar;
- uvar += uivar;
-
- sivar = svar;
- svar = sivar;
- sivar += svar;
- svar += sivar;
-}
-
-bool
-VariableTracerTest::RunTests (void)
-{
- RunUnsignedTests ();
- RunSignedUnsignedTests ();
-
- return true;
-}
-
-VariableTracerTest::VariableTracerTest ()
- : Test ("VariableTracer") {}
-
-static VariableTracerTest gVariableTracerTest;
-
-}; // namespace ns3
-
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/waf Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../waf "$@"
\ No newline at end of file
--- a/src/common/wscript Thu Sep 06 15:18:14 2007 +0100
+++ b/src/common/wscript Tue Sep 11 14:52:15 2007 +0100
@@ -12,14 +12,6 @@
'tags.cc',
'tag-registry.cc',
'pcap-writer.cc',
- 'variable-tracer-test.cc',
- 'trace-context.cc',
- 'trace-context-element.cc',
- 'trace-resolver.cc',
- 'callback-trace-source.cc',
- 'empty-trace-resolver.cc',
- 'composite-trace-resolver.cc',
- 'trace-root.cc',
'data-rate.cc',
]
@@ -35,18 +27,6 @@
'packet.h',
'packet-printer.h',
'packet-metadata.h',
- 'uv-trace-source.h',
- 'sv-trace-source.h',
- 'fv-trace-source.h',
'pcap-writer.h',
- 'callback-trace-source.h',
- 'trace-context.h',
- 'trace-context-element.h',
- 'trace-resolver.h',
- 'empty-trace-resolver.h',
- 'composite-trace-resolver.h',
- 'array-trace-resolver.h',
- 'trace-root.h',
- 'terminal-trace-resolver.h',
'data-rate.h',
]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/array-trace-resolver.h Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,205 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef ARRAY_TRACE_RESOLVER_H
+#define ARRAY_TRACE_RESOLVER_H
+
+#include <stdint.h>
+#include <string>
+#include "callback.h"
+#include "trace-resolver.h"
+#include "object.h"
+
+namespace ns3 {
+
+/**
+ * \brief a helper class to offer trace resolution for an array of objects.
+ * \ingroup tracing
+ *
+ * \class ArrayTraceResolver
+ *
+ * An ArrayTraceResolver is a resolver which can match any input integer
+ * against an element in an array. The array is accessed using a
+ * pair iterators. Each element of the array is expected
+ * to be a subclass of the Object base class.
+ *
+ * When the Connect method is called, this trace resolver will
+ * automatically store in the TraceContext of each resolved object
+ * its index through an object of type INDEX specified during the
+ * instanciation of the ArrayTraceResolver template.
+ */
+template <typename INDEX>
+class ArrayTraceResolver : public TraceResolver
+{
+public:
+ ArrayTraceResolver ();
+ ~ArrayTraceResolver ();
+
+ /**
+ * \param begin an iterator which points to the start of the array.
+ * \param end an iterator which points to the end of the array.
+ */
+ template <typename T>
+ void SetIterators (T begin, T end);
+
+ // inherited from TraceResolver
+ virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context);
+ virtual void Disconnect (std::string path, CallbackBase const &cb);
+ virtual void CollectSources (std::string path, const TraceContext &context,
+ SourceCollection *collection);
+ virtual void TraceAll (std::ostream &os, const TraceContext &context);
+
+private:
+ class IteratorBase
+ {
+ public:
+ virtual ~IteratorBase () {}
+ virtual void Next (void) = 0;
+ virtual bool HasNext (void) = 0;
+ virtual Ptr<Object> Get (void) = 0;
+ virtual void Rewind (void) = 0;
+ };
+ IteratorBase *m_iter;
+};
+}//namespace ns3
+
+
+// implementation
+namespace ns3 {
+
+template <typename INDEX>
+ArrayTraceResolver<INDEX>::ArrayTraceResolver ()
+ : m_iter (0)
+{}
+
+template <typename INDEX>
+ArrayTraceResolver<INDEX>::~ArrayTraceResolver ()
+{
+ delete m_iter;
+}
+
+template <typename INDEX>
+template <typename T>
+void
+ArrayTraceResolver<INDEX>::SetIterators (T begin, T end)
+{
+ class Iterator : public IteratorBase
+ {
+ public:
+ Iterator (T begin, T end)
+ : m_begin (begin), m_end (end), m_cur (begin)
+ {}
+ virtual void Next (void)
+ {m_cur++;}
+ virtual bool HasNext (void)
+ {return m_cur != m_end;}
+ virtual Ptr<Object> Get (void)
+ {return *m_cur;}
+ virtual void Rewind (void)
+ {m_cur = m_begin;}
+ private:
+ T m_begin;
+ T m_end;
+ T m_cur;
+ };
+ delete m_iter;
+ m_iter = new Iterator (begin, end);
+}
+
+template <typename INDEX>
+void
+ArrayTraceResolver<INDEX>::Connect (std::string path, CallbackBase const &cb, const TraceContext &context)
+{
+ if (path == "")
+ {
+ return;
+ }
+ std::string id = GetElement (path);
+ std::string subpath = GetSubpath (path);
+ if (id == "*")
+ {
+ uint32_t j = 0;
+ for (m_iter->Rewind (); m_iter->HasNext (); m_iter->Next ())
+ {
+ TraceContext tmp = context;
+ INDEX index = j;
+ tmp.AddElement (index);
+ Ptr<Object> obj = m_iter->Get ();
+ obj->GetTraceResolver ()->Connect (subpath, cb, tmp);
+ j++;
+ }
+ }
+}
+template <typename INDEX>
+void
+ArrayTraceResolver<INDEX>::Disconnect (std::string path, CallbackBase const &cb)
+{
+ if (path == "")
+ {
+ return;
+ }
+ std::string id = GetElement (path);
+ std::string subpath = GetSubpath (path);
+ if (id == "*")
+ {
+ for (m_iter->Rewind (); m_iter->HasNext (); m_iter->Next ())
+ {
+ Ptr<Object> obj = m_iter->Get ();
+ obj->TraceDisconnect (subpath, cb);
+ }
+ }
+}
+template <typename INDEX>
+void
+ArrayTraceResolver<INDEX>::CollectSources (std::string path, const TraceContext &context,
+ SourceCollection *collection)
+{
+ path.append ("/[0-n]");
+ uint32_t j = 0;
+ for (m_iter->Rewind (); m_iter->HasNext (); m_iter->Next ())
+ {
+ TraceContext tmp = context;
+ INDEX index = j;
+ tmp.AddElement (index);
+ Ptr<Object> obj = m_iter->Get ();
+ obj->GetTraceResolver ()->CollectSources (path, tmp, collection);
+ j++;
+ }
+}
+
+template <typename INDEX>
+void
+ArrayTraceResolver<INDEX>::TraceAll (std::ostream &os, const TraceContext &context)
+{
+ uint32_t j = 0;
+ for (m_iter->Rewind (); m_iter->HasNext (); m_iter->Next ())
+ {
+ TraceContext tmp = context;
+ INDEX index = j;
+ tmp.AddElement (index);
+ Ptr<Object> obj = m_iter->Get ();
+ obj->GetTraceResolver ()->TraceAll (os, tmp);
+ j++;
+ }
+}
+
+}//namespace ns3
+
+#endif /* ARRAY_TRACE_RESOLVER_H */
--- a/src/core/callback-test.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/core/callback-test.cc Tue Sep 11 14:52:15 2007 +0100
@@ -57,6 +57,21 @@
return a;
}
+void TestFZero (void) {}
+void TestFOne (int) {}
+void TestFTwo (int, int) {}
+void TestFThree (int, int, int) {}
+void TestFFour (int, int, int, int) {}
+void TestFFive (int, int, int, int, int) {}
+void TestFSix (int, int, int, int, int, int) {}
+
+void TestFROne (int &) {}
+void TestFRTwo (int &, int &) {}
+void TestFRThree (int &, int &, int &) {}
+void TestFRFour (int &, int &, int &, int &) {}
+void TestFRFive (int &, int &, int &, int &, int &) {}
+void TestFRSix (int &, int &, int &, int &, int &, int &) {}
+
class CallbackTest : public ns3::Test {
private:
bool m_test1;
@@ -73,6 +88,22 @@
void Test3 (double a);
int Test4 (double a, int b);
void Test8 (Callback<void, int> callback);
+
+ void TestZero (void) {}
+ void TestOne (int) {}
+ void TestTwo (int, int) {}
+ void TestThree (int, int, int) {}
+ void TestFour (int, int, int, int) {}
+ void TestFive (int, int, int, int, int) {}
+ void TestSix (int, int, int, int, int, int) {}
+
+ void TestCZero (void) const {}
+ void TestCOne (int) const {}
+ void TestCTwo (int, int) const {}
+ void TestCThree (int, int, int) const {}
+ void TestCFour (int, int, int, int) const {}
+ void TestCFive (int, int, int, int, int) const {}
+ void TestCSix (int, int, int, int, int, int) const {}
};
CallbackTest::CallbackTest ()
@@ -110,6 +141,7 @@
{
callback (3);
}
+
bool
CallbackTest::IsWrong (void)
{
@@ -216,6 +248,53 @@
MakeBoundCallback (&Test9, &v);
MakeBoundCallback (&Test10, &v);
+
+ MakeCallback (&CallbackTest::TestZero, this);
+ MakeCallback (&CallbackTest::TestOne, this);
+ MakeCallback (&CallbackTest::TestTwo, this);
+ MakeCallback (&CallbackTest::TestThree, this);
+ MakeCallback (&CallbackTest::TestFour, this);
+ MakeCallback (&CallbackTest::TestFive, this);
+ MakeCallback (&CallbackTest::TestSix, this);
+
+ MakeCallback (&CallbackTest::TestCZero, this);
+ MakeCallback (&CallbackTest::TestCOne, this);
+ MakeCallback (&CallbackTest::TestCTwo, this);
+ MakeCallback (&CallbackTest::TestCThree, this);
+ MakeCallback (&CallbackTest::TestCFour, this);
+ MakeCallback (&CallbackTest::TestCFive, this);
+ MakeCallback (&CallbackTest::TestCSix, this);
+
+ MakeCallback (&TestFZero);
+ MakeCallback (&TestFOne);
+ MakeCallback (&TestFTwo);
+ MakeCallback (&TestFThree);
+ MakeCallback (&TestFFour);
+ MakeCallback (&TestFFive);
+ MakeCallback (&TestFSix);
+
+ MakeCallback (&TestFROne);
+ MakeCallback (&TestFRTwo);
+ MakeCallback (&TestFRThree);
+ MakeCallback (&TestFRFour);
+ MakeCallback (&TestFRFive);
+ MakeCallback (&TestFRSix);
+
+
+ MakeBoundCallback (&TestFOne, 1);
+ MakeBoundCallback (&TestFTwo, 1);
+ MakeBoundCallback (&TestFThree, 1);
+ MakeBoundCallback (&TestFFour, 1);
+ MakeBoundCallback (&TestFFive, 1);
+
+ MakeBoundCallback (&TestFROne, 1);
+ MakeBoundCallback (&TestFRTwo, 1);
+ MakeBoundCallback (&TestFRThree, 1);
+ MakeBoundCallback (&TestFRFour, 1);
+ MakeBoundCallback (&TestFRFive, 1);
+
+
+
return ok;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/callback-trace-source.cc Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,101 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "callback-trace-source.h"
+
+#ifdef RUN_SELF_TESTS
+
+#include "test.h"
+
+namespace ns3 {
+
+class CallbackTraceSourceTest : public Test
+{
+public:
+ CallbackTraceSourceTest ();
+ virtual ~CallbackTraceSourceTest ();
+ virtual bool RunTests (void);
+private:
+ void CbOne (TraceContext const &context, uint8_t a, double b);
+ void CbTwo (TraceContext const &context, uint8_t a, double b);
+
+ bool m_one;
+ bool m_two;
+};
+
+CallbackTraceSourceTest::CallbackTraceSourceTest ()
+ : Test ("CallbackTraceSource")
+{}
+CallbackTraceSourceTest::~CallbackTraceSourceTest ()
+{}
+void
+CallbackTraceSourceTest::CbOne (TraceContext const &context, uint8_t a, double b)
+{
+ m_one = true;
+}
+void
+CallbackTraceSourceTest::CbTwo (TraceContext const &context, uint8_t a, double b)
+{
+ m_two = true;
+}
+bool
+CallbackTraceSourceTest::RunTests (void)
+{
+ bool result = true;
+ TraceContext ctx;
+
+ CallbackTraceSource<uint8_t,double> trace;
+ trace.AddCallback (MakeCallback (&CallbackTraceSourceTest::CbOne, this), ctx);
+ trace.AddCallback (MakeCallback (&CallbackTraceSourceTest::CbTwo, this), ctx);
+ m_one = false;
+ m_two = false;
+ trace (1, 2);
+ NS_TEST_ASSERT (m_one);
+ NS_TEST_ASSERT (m_two);
+
+ trace.RemoveCallback (MakeCallback (&CallbackTraceSourceTest::CbOne, this));
+ m_one = false;
+ m_two = false;
+ trace (1, 2);
+ NS_TEST_ASSERT (!m_one);
+ NS_TEST_ASSERT (m_two);
+ trace.RemoveCallback (MakeCallback (&CallbackTraceSourceTest::CbTwo, this));
+ m_one = false;
+ m_two = false;
+ trace (1, 2);
+ NS_TEST_ASSERT (!m_one);
+ NS_TEST_ASSERT (!m_two);
+
+ trace.AddCallback (MakeCallback (&CallbackTraceSourceTest::CbOne, this), ctx);
+ trace.AddCallback (MakeCallback (&CallbackTraceSourceTest::CbTwo, this), ctx);
+ m_one = false;
+ m_two = false;
+ trace (1, 2);
+ NS_TEST_ASSERT (m_one);
+ NS_TEST_ASSERT (m_two);
+
+ return result;
+}
+
+CallbackTraceSourceTest g_callbackTraceTest;
+
+}//namespace ns3
+
+#endif /* RUN_SELF_TESTS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/callback-trace-source.h Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,251 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef CALLBACK_TRACE_H
+#define CALLBACK_TRACE_H
+
+#include <list>
+#include "callback.h"
+#include "fatal-error.h"
+#include "trace-context.h"
+#include "trace-source.h"
+
+namespace ns3 {
+
+/**
+ * \brief log arbitrary number of parameters to a matching ns3::Callback
+ * \ingroup tracing
+ *
+ * Whenever operator () is invoked on this class, the call and its arguments
+ * are forwarded to the internal matching ns3::Callback.
+ */
+template<typename T1 = empty, typename T2 = empty,
+ typename T3 = empty, typename T4 = empty>
+class CallbackTraceSource : public TraceSource {
+public:
+ CallbackTraceSource ();
+ virtual void AddCallback (CallbackBase const & callback, TraceContext const & context);
+ virtual void RemoveCallback (CallbackBase const & callback);
+ virtual void ConnectPrinter (std::ostream &os, const TraceContext &context);
+ void operator() (void) const;
+ void operator() (T1 a1) const;
+ void operator() (T1 a1, T2 a2) const;
+ void operator() (T1 a1, T2 a2, T3 a3) const;
+ void operator() (T1 a1, T2 a2, T3 a3, T4 a4) const;
+
+private:
+ typedef std::list<Callback<void,TraceContext const &,T1,T2,T3,T4> > CallbackList;
+ TraceContext m_context;
+ CallbackList m_callbackList;
+};
+
+}; // namespace ns3
+
+// implementation below.
+
+namespace ns3 {
+
+namespace internal {
+
+template<typename T1, typename T2,
+ typename T3, typename T4>
+class TraceSinkPrint;
+
+template<typename T1, typename T2,
+ typename T3, typename T4>
+class TraceSinkPrint
+{
+public:
+ static Callback<void,const TraceContext &,T1,T2,T3,T4> Make (std::ostream &os)
+ {
+ return ns3::MakeBoundCallback (&DoPrint, &os);
+ }
+private:
+ static void DoPrint (std::ostream *os, const TraceContext &context, T1 a1, T2 a2, T3 a3, T4 a4)
+ {
+ *os << "context=\"" << context << "\" arg1=\"" << a1 << "\" arg2=\"" << a2 << "\" arg3=\"" << a3 << "\" arg4=\"" << a4 << "\"" << std::endl;
+ }
+};
+
+template<typename T1, typename T2,
+ typename T3>
+class TraceSinkPrint<T1,T2,T3,empty>
+{
+public:
+ static Callback<void,const TraceContext &,T1,T2,T3> Make (std::ostream &os)
+ {
+ return ns3::MakeBoundCallback (&DoPrint, &os);
+ }
+private:
+ static void DoPrint (std::ostream *os, const TraceContext &context, T1 a1, T2 a2, T3 a3)
+ {
+ *os << "context=\"" << context << "\" arg1=\"" << a1 << "\" arg2=\"" << a2 << "\" arg3=\"" << a3 << "\"" << std::endl;
+ }
+};
+
+template<typename T1, typename T2>
+class TraceSinkPrint<T1,T2,empty,empty>
+{
+public:
+ static Callback<void,const TraceContext &,T1,T2> Make (std::ostream &os)
+ {
+ return ns3::MakeBoundCallback (&DoPrint, &os);
+ }
+private:
+ static void DoPrint (std::ostream *os, const TraceContext &context, T1 a1, T2 a2)
+ {
+ *os << "context=\"" << context << "\" arg1=\"" << a1 << "\" arg2=\"" << a2 << "\"" << std::endl;
+ }
+};
+
+template<typename T1>
+class TraceSinkPrint<T1,empty,empty,empty>
+{
+public:
+ static Callback<void,const TraceContext &,T1> Make (std::ostream &os)
+ {
+ return ns3::MakeBoundCallback (&DoPrint, &os);
+ }
+private:
+ static void DoPrint (std::ostream *os, const TraceContext &context, T1 a1)
+ {
+ *os << "context=\"" << context << "\" arg1=\"" << a1 << "\"" << std::endl;
+ }
+};
+
+template <>
+class TraceSinkPrint<empty,empty,empty,empty>
+{
+public:
+ static Callback<void,const TraceContext &> Make (std::ostream &os)
+ {
+ return ns3::MakeBoundCallback (&DoPrint, &os);
+ }
+private:
+ static void DoPrint (std::ostream *os, const TraceContext &context)
+ {
+ *os << "context=\"" << context << std::endl;
+ }
+};
+
+} // namespace internal
+
+
+template<typename T1, typename T2,
+ typename T3, typename T4>
+CallbackTraceSource<T1,T2,T3,T4>::CallbackTraceSource ()
+ : m_callbackList ()
+{}
+template<typename T1, typename T2,
+ typename T3, typename T4>
+void
+CallbackTraceSource<T1,T2,T3,T4>::AddCallback (CallbackBase const & callback,
+ TraceContext const &context)
+{
+ Callback<void,TraceContext const &,T1,T2,T3,T4> cb;
+ cb.Assign (callback);
+ m_context.Union (context);
+ m_callbackList.push_back (cb);
+}
+template<typename T1, typename T2,
+ typename T3, typename T4>
+void
+CallbackTraceSource<T1,T2,T3,T4>::RemoveCallback (CallbackBase const & callback)
+{
+ for (typename CallbackList::iterator i = m_callbackList.begin ();
+ i != m_callbackList.end (); /* empty */)
+ {
+ if ((*i).IsEqual (callback))
+ {
+ i = m_callbackList.erase (i);
+ }
+ else
+ {
+ i++;
+ }
+ }
+}
+template<typename T1, typename T2,
+ typename T3, typename T4>
+void
+CallbackTraceSource<T1,T2,T3,T4>::ConnectPrinter (std::ostream &os, const TraceContext &context)
+{
+ AddCallback (ns3::internal::TraceSinkPrint<T1,T2,T3,T4>::Make (os), context);
+}
+template<typename T1, typename T2,
+ typename T3, typename T4>
+void
+CallbackTraceSource<T1,T2,T3,T4>::operator() (void) const
+{
+ for (typename CallbackList::const_iterator i = m_callbackList.begin ();
+ i != m_callbackList.end (); i++)
+ {
+ (*i) (m_context);
+ }
+}
+template<typename T1, typename T2,
+ typename T3, typename T4>
+void
+CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1) const
+{
+ for (typename CallbackList::const_iterator i = m_callbackList.begin ();
+ i != m_callbackList.end (); i++)
+ {
+ (*i) (m_context, a1);
+ }
+}
+template<typename T1, typename T2,
+ typename T3, typename T4>
+void
+CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1, T2 a2) const
+{
+ for (typename CallbackList::const_iterator i = m_callbackList.begin ();
+ i != m_callbackList.end (); i++)
+ {
+ (*i) (m_context, a1, a2);
+ }
+}
+template<typename T1, typename T2,
+ typename T3, typename T4>
+void
+CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1, T2 a2, T3 a3) const
+{
+ for (typename CallbackList::const_iterator i = m_callbackList.begin ();
+ i != m_callbackList.end (); i++)
+ {
+ (*i) (m_context, a1, a2, a3);
+ }
+}
+template<typename T1, typename T2,
+ typename T3, typename T4>
+void
+CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1, T2 a2, T3 a3, T4 a4) const
+{
+ for (typename CallbackList::const_iterator i = m_callbackList.begin ();
+ i != m_callbackList.end (); i++)
+ {
+ (*i) (m_context, a1, a2, a3, a4);
+ }
+}
+
+}//namespace ns3
+
+#endif /* CALLBACK_TRACE_H */
--- a/src/core/callback.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/core/callback.h Tue Sep 11 14:52:15 2007 +0100
@@ -25,6 +25,7 @@
#include "ptr.h"
#include "fatal-error.h"
#include "empty.h"
+#include "type-traits.h"
namespace ns3 {
@@ -89,55 +90,62 @@
};
// declare the CallbackImpl class
-template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
+template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
class CallbackImpl;
// define CallbackImpl for 0 params
template <typename R>
-class CallbackImpl<R,empty,empty,empty,empty,empty> : public CallbackImplBase {
+class CallbackImpl<R,empty,empty,empty,empty,empty,empty> : public CallbackImplBase {
public:
virtual ~CallbackImpl () {}
virtual R operator() (void) = 0;
};
// define CallbackImpl for 1 params
template <typename R, typename T1>
-class CallbackImpl<R,T1,empty,empty,empty,empty> : public CallbackImplBase {
+class CallbackImpl<R,T1,empty,empty,empty,empty,empty> : public CallbackImplBase {
public:
virtual ~CallbackImpl () {}
virtual R operator() (T1) = 0;
};
// define CallbackImpl for 2 params
template <typename R, typename T1, typename T2>
-class CallbackImpl<R,T1,T2,empty,empty,empty> : public CallbackImplBase {
+class CallbackImpl<R,T1,T2,empty,empty,empty,empty> : public CallbackImplBase {
public:
virtual ~CallbackImpl () {}
virtual R operator() (T1, T2) = 0;
};
// define CallbackImpl for 3 params
template <typename R, typename T1, typename T2, typename T3>
-class CallbackImpl<R,T1,T2,T3,empty,empty> : public CallbackImplBase {
+class CallbackImpl<R,T1,T2,T3,empty,empty,empty> : public CallbackImplBase {
public:
virtual ~CallbackImpl () {}
virtual R operator() (T1, T2, T3) = 0;
};
// define CallbackImpl for 4 params
template <typename R, typename T1, typename T2, typename T3, typename T4>
-class CallbackImpl<R,T1,T2,T3,T4,empty> : public CallbackImplBase {
+class CallbackImpl<R,T1,T2,T3,T4,empty,empty> : public CallbackImplBase {
public:
virtual ~CallbackImpl () {}
virtual R operator() (T1, T2, T3, T4) = 0;
};
// define CallbackImpl for 5 params
template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
-class CallbackImpl : public CallbackImplBase {
+class CallbackImpl<R,T1,T2,T3,T4,T5,empty> : public CallbackImplBase {
public:
virtual ~CallbackImpl () {}
virtual R operator() (T1, T2, T3, T4, T5) = 0;
};
+// define CallbackImpl for 6 params
+ template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
+class CallbackImpl : public CallbackImplBase {
+public:
+ virtual ~CallbackImpl () {}
+ virtual R operator() (T1, T2, T3, T4, T5, T6) = 0;
+};
// an impl for Functors:
-template <typename T, typename R, typename T1, typename T2, typename T3, typename T4,typename T5>
-class FunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> {
+template <typename T, typename R, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6>
+class FunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,T6> {
public:
FunctorCallbackImpl (T const &functor)
: m_functor (functor) {}
@@ -160,9 +168,12 @@
R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
return m_functor (a1,a2,a3,a4,a5);
}
+ R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) {
+ return m_functor (a1,a2,a3,a4,a5,a6);
+ }
virtual bool IsEqual (CallbackImplBase const *other) const {
- FunctorCallbackImpl<T,R,T1,T2,T3,T4,T5> const *otherDerived =
- dynamic_cast<FunctorCallbackImpl<T,R,T1,T2,T3,T4,T5> const *> (other);
+ FunctorCallbackImpl<T,R,T1,T2,T3,T4,T5,T6> const *otherDerived =
+ dynamic_cast<FunctorCallbackImpl<T,R,T1,T2,T3,T4,T5,T6> const *> (other);
if (otherDerived == 0)
{
return false;
@@ -178,8 +189,8 @@
};
// an impl for pointer to member functions
-template <typename OBJ_PTR, typename MEM_PTR, typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
-class MemPtrCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> {
+template <typename OBJ_PTR, typename MEM_PTR, typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
+class MemPtrCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,T6> {
public:
MemPtrCallbackImpl (OBJ_PTR const&objPtr, MEM_PTR mem_ptr)
: m_objPtr (objPtr), m_memPtr (mem_ptr) {}
@@ -202,9 +213,12 @@
R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3, a4, a5);
}
+ R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) {
+ return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3, a4, a5, a6);
+ }
virtual bool IsEqual (CallbackImplBase const *other) const {
- MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5> const *otherDerived =
- dynamic_cast<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5> const *> (other);
+ MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5,T6> const *otherDerived =
+ dynamic_cast<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5,T6> const *> (other);
if (otherDerived == 0)
{
return false;
@@ -260,22 +274,22 @@
template<typename R,
typename T1 = empty, typename T2 = empty,
typename T3 = empty, typename T4 = empty,
- typename T5 = empty>
+ typename T5 = empty, typename T6 = empty>
class Callback : public CallbackBase {
public:
// There are two dummy args below to ensure that this constructor is
// always properly disambiguited by the c++ compiler
template <typename FUNCTOR>
Callback (FUNCTOR const &functor, bool, bool)
- : m_impl (Create<FunctorCallbackImpl<FUNCTOR,R,T1,T2,T3,T4,T5> > (functor))
+ : m_impl (Create<FunctorCallbackImpl<FUNCTOR,R,T1,T2,T3,T4,T5,T6> > (functor))
{}
template <typename OBJ_PTR, typename MEM_PTR>
Callback (OBJ_PTR const &objPtr, MEM_PTR mem_ptr)
- : m_impl (Create<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5> > (objPtr, mem_ptr))
+ : m_impl (Create<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5,T6> > (objPtr, mem_ptr))
{}
- Callback (Ptr<CallbackImpl<R,T1,T2,T3,T4,T5> > const &impl)
+ Callback (Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,T6> > const &impl)
: m_impl (impl)
{}
@@ -305,14 +319,17 @@
R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5) const {
return (*(PeekImpl ())) (a1,a2,a3,a4,a5);
}
+ R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5,T6 a6) const {
+ return (*(PeekImpl ())) (a1,a2,a3,a4,a5,a6);
+ }
- bool IsEqual (CallbackBase const &other) {
+ bool IsEqual (CallbackBase const &other) const {
return PeekImpl ()->IsEqual (other.PeekImpl ());
}
- bool CheckType (CallbackBase const& other) {
+ bool CheckType (CallbackBase const& other) const {
CallbackImplBase *otherBase = other.PeekImpl ();
- if (dynamic_cast<CallbackImpl<R,T1,T2,T3,T4,T5> *> (otherBase) != 0)
+ if (dynamic_cast<CallbackImpl<R,T1,T2,T3,T4,T5,T6> *> (otherBase) != 0)
{
return true;
}
@@ -328,27 +345,27 @@
" got=" << typeid (other).name () <<
", expected=" << typeid (*this).name ());
}
- const Callback<R, T1,T2,T3,T4,T5> *goodType = static_cast<const Callback<R,T1,T2,T3,T4,T5> *> (&other);
+ const Callback<R, T1,T2,T3,T4,T5,T6> *goodType = static_cast<const Callback<R,T1,T2,T3,T4,T5,T6> *> (&other);
*this = *goodType;
}
void Assign (Ptr<CallbackImplBase> other) {
- CallbackImpl<R,T1,T2,T3,T4,T5> *impl = dynamic_cast<CallbackImpl<R,T1,T2,T3,T4,T5> *> (PeekPointer (other));
+ CallbackImpl<R,T1,T2,T3,T4,T5,T6> *impl = dynamic_cast<CallbackImpl<R,T1,T2,T3,T4,T5,T6> *> (PeekPointer (other));
if (other == 0)
{
NS_FATAL_ERROR ("Incompatible types. (feed to \"c++filt -t\")"
" got=" << typeid (other).name () <<
", expected=" << typeid (*impl).name ());
}
- *this = Callback<R,T1,T2,T3,T4,T5> (impl);
+ *this = Callback<R,T1,T2,T3,T4,T5,T6> (impl);
}
virtual Ptr<CallbackImplBase>GetImpl (void) const {
return m_impl;
}
private:
- virtual CallbackImpl<R,T1,T2,T3,T4,T5> *PeekImpl (void) const {
+ virtual CallbackImpl<R,T1,T2,T3,T4,T5,T6> *PeekImpl (void) const {
return PeekPointer (m_impl);
}
- Ptr<CallbackImpl<R,T1,T2,T3,T4,T5> > m_impl;
+ Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,T6> > m_impl;
};
/**
@@ -369,7 +386,7 @@
return Callback<R> (objPtr, memPtr);
}
template <typename T, typename OBJ, typename R>
-Callback<R> MakeCallback (R (T::*mem_ptr) () const, OBJ const objPtr) {
+Callback<R> MakeCallback (R (T::*mem_ptr) () const, OBJ objPtr) {
return Callback<R> (objPtr, mem_ptr);
}
/**
@@ -381,11 +398,11 @@
* and potentially return a value.
*/
template <typename T, typename OBJ, typename R, typename T1>
-Callback<R,T1> MakeCallback (R (T::*mem_ptr) (T1), OBJ *const objPtr) {
+Callback<R,T1> MakeCallback (R (T::*mem_ptr) (T1), OBJ objPtr) {
return Callback<R,T1> (objPtr, mem_ptr);
}
template <typename T, typename OBJ, typename R, typename T1>
-Callback<R,T1> MakeCallback (R (T::*mem_ptr) (T1) const, OBJ const *const objPtr) {
+Callback<R,T1> MakeCallback (R (T::*mem_ptr) (T1) const, OBJ objPtr) {
return Callback<R,T1> (objPtr, mem_ptr);
}
/**
@@ -397,11 +414,11 @@
* and potentially return a value.
*/
template <typename T, typename OBJ, typename R, typename T1, typename T2>
-Callback<R,T1,T2> MakeCallback (R (T::*mem_ptr) (T1,T2), OBJ *const objPtr) {
+Callback<R,T1,T2> MakeCallback (R (T::*mem_ptr) (T1,T2), OBJ objPtr) {
return Callback<R,T1,T2> (objPtr, mem_ptr);
}
template <typename T, typename OBJ, typename R, typename T1, typename T2>
-Callback<R,T1,T2> MakeCallback (R (T::*mem_ptr) (T1,T2) const, OBJ const*const objPtr) {
+Callback<R,T1,T2> MakeCallback (R (T::*mem_ptr) (T1,T2) const, OBJ objPtr) {
return Callback<R,T1,T2> (objPtr, mem_ptr);
}
/**
@@ -413,11 +430,11 @@
* and potentially return a value.
*/
template <typename T, typename OBJ, typename R, typename T1,typename T2, typename T3>
-Callback<R,T1,T2,T3> MakeCallback (R (T::*mem_ptr) (T1,T2,T3), OBJ *const objPtr) {
+Callback<R,T1,T2,T3> MakeCallback (R (T::*mem_ptr) (T1,T2,T3), OBJ objPtr) {
return Callback<R,T1,T2,T3> (objPtr, mem_ptr);
}
template <typename T, typename OBJ, typename R, typename T1,typename T2, typename T3>
-Callback<R,T1,T2,T3> MakeCallback (R (T::*mem_ptr) (T1,T2,T3) const, OBJ const*const objPtr) {
+Callback<R,T1,T2,T3> MakeCallback (R (T::*mem_ptr) (T1,T2,T3) const, OBJ objPtr) {
return Callback<R,T1,T2,T3> (objPtr, mem_ptr);
}
/**
@@ -429,11 +446,11 @@
* and potentially return a value.
*/
template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4>
-Callback<R,T1,T2,T3,T4> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4), OBJ *const objPtr) {
+Callback<R,T1,T2,T3,T4> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4), OBJ objPtr) {
return Callback<R,T1,T2,T3,T4> (objPtr, mem_ptr);
}
template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4>
-Callback<R,T1,T2,T3,T4> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4) const, OBJ const*const objPtr) {
+Callback<R,T1,T2,T3,T4> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4) const, OBJ objPtr) {
return Callback<R,T1,T2,T3,T4> (objPtr, mem_ptr);
}
/**
@@ -445,13 +462,29 @@
* and potentially return a value.
*/
template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5>
-Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5), OBJ *const objPtr) {
+Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5), OBJ objPtr) {
return Callback<R,T1,T2,T3,T4,T5> (objPtr, mem_ptr);
}
template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5>
-Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5) const, OBJ const*const objPtr) {
+Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5) const, OBJ objPtr) {
return Callback<R,T1,T2,T3,T4,T5> (objPtr, mem_ptr);
}
+/**
+ * \ingroup MakeCallback
+ * \param mem_ptr class method member pointer
+ * \param objPtr class instance
+ * \return a wrapper Callback
+ * Build Callbacks for class method members which takes five arguments
+ * and potentially return a value.
+ */
+template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5,typename T6>
+Callback<R,T1,T2,T3,T4,T5,T6> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5,T6), OBJ objPtr) {
+ return Callback<R,T1,T2,T3,T4,T5,T6> (objPtr, mem_ptr);
+}
+template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6>
+Callback<R,T1,T2,T3,T4,T5,T6> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5,T6) const, OBJ objPtr) {
+ return Callback<R,T1,T2,T3,T4,T5,T6> (objPtr, mem_ptr);
+}
/**
* \ingroup MakeCallback
@@ -519,6 +552,17 @@
Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (*fnPtr) (T1,T2,T3,T4,T5)) {
return Callback<R,T1,T2,T3,T4,T5> (fnPtr, true, true);
}
+/**
+ * \ingroup MakeCallback
+ * \param fnPtr function pointer
+ * \return a wrapper Callback
+ * Build Callbacks for functions which takes five arguments
+ * and potentially return a value.
+ */
+template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5,typename T6>
+Callback<R,T1,T2,T3,T4,T5,T6> MakeCallback (R (*fnPtr) (T1,T2,T3,T4,T5,T6)) {
+ return Callback<R,T1,T2,T3,T4,T5,T6> (fnPtr, true, true);
+}
@@ -587,6 +631,17 @@
Callback<R,T1,T2,T3,T4,T5> MakeNullCallback (void) {
return Callback<R,T1,T2,T3,T4,T5> ();
}
+/**
+ * \ingroup MakeCallback
+ * \overload Callback<R> MakeNullCallback (void)
+ * \return a wrapper Callback
+ * Build a null callback which takes five arguments
+ * and potentially return a value.
+ */
+template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5,typename T6>
+Callback<R,T1,T2,T3,T4,T5,T6> MakeNullCallback (void) {
+ return Callback<R,T1,T2,T3,T4,T5,T6> ();
+}
/*
@@ -596,9 +651,10 @@
*/
// an impl for Bound Functors:
template <typename T, typename R, typename TX, typename T1, typename T2, typename T3, typename T4,typename T5>
-class BoundFunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> {
+class BoundFunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,empty> {
public:
- BoundFunctorCallbackImpl (T const &functor, TX a)
+ template <typename FUNCTOR, typename ARG>
+ BoundFunctorCallbackImpl (FUNCTOR functor, ARG a)
: m_functor (functor), m_a (a) {}
virtual ~BoundFunctorCallbackImpl () {}
R operator() (void) {
@@ -635,38 +691,48 @@
}
private:
T m_functor;
- TX m_a;
+ typename TypeTraits<TX>::ReferencedType m_a;
};
-template <typename R, typename TX>
-Callback<R> MakeBoundCallback (R (*fnPtr) (TX), TX a) {
- Ptr<CallbackImpl<R,empty,empty,empty,empty,empty> > impl =
+template <typename R, typename TX, typename ARG>
+Callback<R> MakeBoundCallback (R (*fnPtr) (TX), ARG a) {
+ Ptr<CallbackImpl<R,empty,empty,empty,empty,empty,empty> > impl =
Create<BoundFunctorCallbackImpl<R (*) (TX),R,TX,empty,empty,empty,empty,empty> >(fnPtr, a);
return Callback<R> (impl);
}
-template <typename R, typename TX, typename T1>
-Callback<R,T1> MakeBoundCallback (R (*fnPtr) (TX,T1), TX a) {
- Ptr<CallbackImpl<R,T1,empty,empty,empty,empty> > impl =
+template <typename R, typename TX, typename ARG,
+ typename T1>
+Callback<R,T1> MakeBoundCallback (R (*fnPtr) (TX,T1), ARG a) {
+ Ptr<CallbackImpl<R,T1,empty,empty,empty,empty,empty> > impl =
Create<BoundFunctorCallbackImpl<R (*) (TX,T1),R,TX,T1,empty,empty,empty,empty> > (fnPtr, a);
return Callback<R,T1> (impl);
}
-template <typename R, typename TX, typename T1, typename T2>
-Callback<R,T1,T2> MakeBoundCallback (R (*fnPtr) (TX,T1,T2), TX a) {
- Ptr<CallbackImpl<R,T1,T2,empty,empty,empty> > impl =
+template <typename R, typename TX, typename ARG,
+ typename T1, typename T2>
+Callback<R,T1,T2> MakeBoundCallback (R (*fnPtr) (TX,T1,T2), ARG a) {
+ Ptr<CallbackImpl<R,T1,T2,empty,empty,empty,empty> > impl =
Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2),R,TX,T1,T2,empty,empty,empty> > (fnPtr, a);
return Callback<R,T1,T2> (impl);
}
-template <typename R, typename TX, typename T1, typename T2,typename T3,typename T4>
-Callback<R,T1,T2,T3,T4> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4), TX a) {
- Ptr<CallbackImpl<R,T1,T2,T3,T4,empty> > impl =
+template <typename R, typename TX, typename ARG,
+ typename T1, typename T2,typename T3>
+Callback<R,T1,T2,T3> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3), ARG a) {
+ Ptr<CallbackImpl<R,T1,T2,T3,empty,empty,empty> > impl =
+ Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3),R,TX,T1,T2,T3,empty,empty> > (fnPtr, a);
+ return Callback<R,T1,T2,T3> (impl);
+}
+template <typename R, typename TX, typename ARG,
+ typename T1, typename T2,typename T3,typename T4>
+Callback<R,T1,T2,T3,T4> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4), ARG a) {
+ Ptr<CallbackImpl<R,T1,T2,T3,T4,empty,empty> > impl =
Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4),R,TX,T1,T2,T3,T4,empty> > (fnPtr, a);
return Callback<R,T1,T2,T3,T4> (impl);
}
-
-template <typename R, typename TX, typename T1, typename T2,typename T3,typename T4,typename T5>
-Callback<R,T1,T2,T3,T4,T5> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5), TX a) {
- Ptr<CallbackImpl<R,T1,T2,T3,T4,T5> > impl =
+template <typename R, typename TX, typename ARG,
+ typename T1, typename T2,typename T3,typename T4,typename T5>
+Callback<R,T1,T2,T3,T4,T5> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5), ARG a) {
+ Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,empty> > impl =
Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5),R,TX,T1,T2,T3,T4,T5> > (fnPtr, a);
return Callback<R,T1,T2,T3,T4,T5> (impl);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/composite-trace-resolver.cc Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,595 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "composite-trace-resolver.h"
+#include "debug.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("CompositeTraceResolver");
+
+namespace ns3 {
+
+CompositeTraceResolver::CompositeTraceResolver ()
+{}
+
+CompositeTraceResolver::~CompositeTraceResolver ()
+{
+ for (TraceItems::iterator i = m_items.begin (); i != m_items.end (); i++)
+ {
+ delete *i;
+ }
+ m_items.clear ();
+}
+
+void
+CompositeTraceResolver::AddItem (ResolveItem *item)
+{
+ m_items.push_back (item);
+}
+
+void
+CompositeTraceResolver::Add (std::string name,
+ Callback<Ptr<TraceResolver> > createResolver)
+{
+ class MakerResolveItem : public ResolveItem
+ {
+ public:
+ virtual void Connect (std::string subpath, const CallbackBase &cb, const TraceContext &context)
+ {maker ()->Connect (subpath, cb, context);}
+ virtual void Disconnect (std::string subpath, const CallbackBase &cb)
+ {maker ()->Disconnect (subpath, cb);}
+ virtual void CollectSources (std::string path, const TraceContext &context,
+ SourceCollection *collection)
+ {
+ path.append ("/");
+ path.append (this->name);
+ TraceContext ctx = context;
+ ctx.Union (this->context);
+ this->maker ()->CollectSources (path, ctx, collection);
+ }
+ virtual void TraceAll (std::ostream &os, const TraceContext &context)
+ {
+ TraceContext ctx = context;
+ ctx.Union (this->context);
+ this->maker ()->TraceAll (os, ctx);
+ }
+ Callback<Ptr<TraceResolver> > maker;
+ } *item = new MakerResolveItem ();
+ item->name = name;
+ item->context = TraceContext ();
+ item->maker = createResolver;
+ AddItem (item);
+}
+
+void
+CompositeTraceResolver::AddSource (std::string name,
+ const TraceDoc &doc,
+ const TraceSource &trace)
+{
+ DoAddSource (name, doc, trace, TraceContext ());
+}
+
+void
+CompositeTraceResolver::DoAddSource (std::string name,
+ const TraceDoc &doc,
+ const TraceSource &trace,
+ const TraceContext &context)
+{
+ class SourceResolveItem : public ResolveItem
+ {
+ public:
+ virtual void Connect (std::string subpath, const CallbackBase &cb, const TraceContext &context)
+ {if (subpath == "") {trace->AddCallback (cb, context);}}
+ virtual void Disconnect (std::string subpath, const CallbackBase &cb)
+ {if (subpath == "") {trace->RemoveCallback (cb);}}
+ virtual void CollectSources (std::string path, const TraceContext &context,
+ SourceCollection *collection)
+ {
+ path.append ("/");
+ path.append (this->name);
+ TraceContext ctx = context;
+ ctx.Union (this->context);
+ collection->AddUnique (path, ctx, this->doc);
+ }
+ virtual void TraceAll (std::ostream &os, const TraceContext &context)
+ {
+ TraceContext ctx = context;
+ ctx.Union (this->context);
+ this->trace->ConnectPrinter (os, ctx);
+ }
+ TraceSource *trace;
+ TraceDoc doc;
+ } *item = new SourceResolveItem ();
+ item->name = name;
+ item->context = context;
+ item->trace = const_cast<TraceSource *> (&trace);
+ item->doc = doc;
+ AddItem (item);
+}
+
+
+
+
+void
+CompositeTraceResolver::AddComposite (std::string name, Ptr<Object> composite)
+{
+ DoAddComposite (name, composite, TraceContext ());
+}
+void
+CompositeTraceResolver::DoAddComposite (std::string name, Ptr<Object> composite, const TraceContext &context)
+{
+ class CompositeResolveItem : public ResolveItem
+ {
+ public:
+ virtual void Connect (std::string subpath, const CallbackBase &cb, const TraceContext &context)
+ {composite->GetTraceResolver ()->Connect (subpath, cb, context);}
+ virtual void Disconnect (std::string subpath, const CallbackBase &cb)
+ {composite->TraceDisconnect (subpath, cb);}
+ virtual void CollectSources (std::string path, const TraceContext &context,
+ SourceCollection *collection)
+ {
+ path.append ("/");
+ path.append (this->name);
+ TraceContext ctx = context;
+ ctx.Union (this->context);
+ this->composite->GetTraceResolver ()->CollectSources (path, ctx, collection);
+ }
+ virtual void TraceAll (std::ostream &os, const TraceContext &context)
+ {
+ TraceContext ctx = context;
+ ctx.Union (this->context);
+ this->composite->GetTraceResolver ()->TraceAll (os, ctx);
+ }
+
+ Ptr<Object> composite;
+ } *item = new CompositeResolveItem ();
+ item->name = name;
+ item->context = context;
+ item->composite = composite;
+ AddItem (item);
+}
+
+void
+CompositeTraceResolver::SetParentResolver (Ptr<TraceResolver> resolver)
+{
+ m_parent = resolver;
+}
+
+void
+CompositeTraceResolver::Connect (std::string path, CallbackBase const &cb, const TraceContext &context)
+{
+ NS_DEBUG ("connect path="<<path);
+ class ConnectOperation : public Operation
+ {
+ public:
+ ConnectOperation (const CallbackBase &cb, const TraceContext &context)
+ : m_cb (cb), m_context (context)
+ {}
+ virtual void Do (std::string subpath, ResolveItem *item) const
+ {
+ NS_DEBUG ("connect to path="<<subpath<<" name="<<item->name);
+ TraceContext context = m_context;
+ context.Union (item->context);
+ item->Connect (subpath, m_cb, context);
+ }
+ virtual void DoParent (std::string path, Ptr<TraceResolver> parent) const
+ {
+ if (parent != 0)
+ {
+ parent->Connect (path, m_cb, m_context);
+ }
+ }
+ private:
+ const CallbackBase &m_cb;
+ const TraceContext &m_context;
+ } operation = ConnectOperation (cb, context);
+ DoRecursiveOperation (path, operation);
+}
+void
+CompositeTraceResolver::DoRecursiveOperation (std::string path,
+ const Operation &operation)
+{
+ if (path == "")
+ {
+ return;
+ }
+ std::string id = GetElement (path);
+ std::string subpath = GetSubpath (path);
+
+ if (id == "*")
+ {
+ for (TraceItems::const_iterator i = m_items.begin (); i != m_items.end (); i++)
+ {
+ operation.Do (subpath, *i);
+ }
+ operation.DoParent (path, m_parent);
+ return;
+ }
+ std::string::size_type start, end;
+ start = id.find_first_of ("(", 0);
+ end = id.find_first_of (")", 0);
+ if (start != 0 || end != (id.size ()-1))
+ {
+ for (TraceItems::const_iterator i = m_items.begin (); i != m_items.end (); i++)
+ {
+ if ((*i)->name == id)
+ {
+ operation.Do (subpath, *i);
+ operation.DoParent (path, m_parent);
+ return;
+ }
+ }
+ }
+ std::list<std::string> names;
+ std::string alternatives = std::string (id, start+1, end-1);
+ std::string::size_type next_pos, cur_pos;
+ next_pos = 0;
+ cur_pos = 0;
+ while (true)
+ {
+ std::string element;
+ next_pos = alternatives.find ("|", cur_pos);
+ if (next_pos == std::string::npos)
+ {
+ element = std::string (alternatives, cur_pos, alternatives.size ());
+ names.push_back (element);
+ break;
+ }
+ element = std::string (alternatives, cur_pos, next_pos);
+ names.push_back (element);
+ cur_pos = next_pos + 1;
+ }
+ for (std::list<std::string>::const_iterator i = names.begin (); i != names.end (); i++)
+ {
+ for (TraceItems::const_iterator j = m_items.begin (); j != m_items.end (); j++)
+ {
+ if ((*j)->name == *i)
+ {
+ operation.Do (subpath, *j);
+ break;
+ }
+ }
+ }
+ operation.DoParent (path, m_parent);
+}
+
+void
+CompositeTraceResolver::Disconnect (std::string path, CallbackBase const &cb)
+{
+ NS_DEBUG ("disconnect path="<<path);
+ class DisconnectOperation : public Operation
+ {
+ public:
+ DisconnectOperation (const CallbackBase &cb)
+ : m_cb (cb)
+ {}
+ virtual void Do (std::string subpath, ResolveItem *item) const
+ {
+ NS_DEBUG ("disconnect from path="<<subpath<<" name="<<item->name);
+ item->Disconnect (subpath, m_cb);
+ }
+ virtual void DoParent (std::string path, Ptr<TraceResolver> parent) const
+ {
+ if (parent != 0)
+ {
+ parent->Disconnect (path, m_cb);
+ }
+ }
+ private:
+ const CallbackBase &m_cb;
+ } operation = DisconnectOperation (cb);
+ DoRecursiveOperation (path, operation);
+}
+
+void
+CompositeTraceResolver::CollectSources (std::string path, const TraceContext &context,
+ SourceCollection *collection)
+{
+ for (TraceItems::const_iterator i = m_items.begin (); i != m_items.end (); i++)
+ {
+ NS_DEBUG ("print " << (*i)->name);
+ (*i)->CollectSources (path, context, collection);
+ }
+ if (m_parent != 0)
+ {
+ m_parent->CollectSources (path, context, collection);
+ }
+}
+void
+CompositeTraceResolver::TraceAll (std::ostream &os, const TraceContext &context)
+{
+ for (TraceItems::const_iterator i = m_items.begin (); i != m_items.end (); i++)
+ {
+ NS_DEBUG ("print " << (*i)->name);
+ (*i)->TraceAll (os, context);
+ }
+ if (m_parent != 0)
+ {
+ m_parent->TraceAll (os, context);
+ }
+}
+
+
+}//namespace ns3
+
+#ifdef RUN_SELF_TESTS
+
+#include "test.h"
+#include "trace-context-element.h"
+
+namespace ns3 {
+
+class TraceSourceTest : public TraceContextElement
+{
+public:
+ enum Sources {
+ DOUBLEA,
+ DOUBLEB,
+ UINT16_T
+ };
+ static uint16_t GetUid (void)
+ {static uint16_t uid = AllocateUid<TraceSourceTest> ("TraceSourceTest"); return uid;}
+ void Print (std::ostream &os)
+ {os << "tracesource=";
+ if (m_sources == DOUBLEA) {os << "doubleA";}
+ else if (m_sources == DOUBLEB) {os << "doubleB";}
+ else if (m_sources == UINT16_T) {os << "uint16_t";}
+ }
+ std::string GetTypeName (void) {return "ns3::TraceSourceTest";}
+ TraceSourceTest () : m_sources (TraceSourceTest::DOUBLEA) {}
+ TraceSourceTest (enum Sources sources) :m_sources (sources) {}
+ bool IsDoubleA (void) const {return m_sources == TraceSourceTest::DOUBLEA;}
+ bool IsDoubleB (void) const {return m_sources == TraceSourceTest::DOUBLEB;}
+ bool IsUint16 (void) const {return m_sources == TraceSourceTest::UINT16_T;}
+private:
+ enum TraceSourceTest::Sources m_sources;
+};
+
+class SubTraceSourceTest : public TraceContextElement
+{
+public:
+ enum Sources {
+ INT,
+ };
+ static uint16_t GetUid (void)
+ {static uint16_t uid = AllocateUid<SubTraceSourceTest> ("SubTraceSourceTest"); return uid;}
+ void Print (std::ostream &os)
+ {os << "subtracesource=int";}
+ std::string GetTypeName (void) const {return "ns3::SubTraceSourceTest";}
+ SubTraceSourceTest () : m_sources (SubTraceSourceTest::INT) {}
+ SubTraceSourceTest (enum Sources sources) : m_sources (sources) {}
+private:
+ enum Sources m_sources;
+};
+
+class CompositeTraceResolverTest : public Test
+{
+public:
+ CompositeTraceResolverTest ();
+ virtual ~CompositeTraceResolverTest ();
+ virtual bool RunTests (void);
+private:
+ void TraceDouble (TraceContext const &context, double v);
+ void TraceInt (TraceContext const &context, int v);
+ Ptr<TraceResolver> CreateSubResolver ();
+
+
+ bool m_gotDoubleA;
+ bool m_gotDoubleB;
+ CallbackTraceSource<int> m_traceInt;
+ bool m_gotInt;
+};
+
+CompositeTraceResolverTest::CompositeTraceResolverTest ()
+ : Test ("CompositeTraceResolver")
+{}
+CompositeTraceResolverTest::~CompositeTraceResolverTest ()
+{}
+void
+CompositeTraceResolverTest::TraceDouble (TraceContext const &context, double v)
+{
+ TraceSourceTest source;
+ context.GetElement (source);
+ if (source.IsDoubleA ())
+ {
+ m_gotDoubleA = true;
+ }
+ else if (source.IsDoubleB ())
+ {
+ m_gotDoubleB = true;
+ }
+ else
+ {
+ NS_FATAL_ERROR ("should not get any other trace source in this sink");
+ }
+
+}
+
+void
+CompositeTraceResolverTest::TraceInt (TraceContext const &context, int v)
+{
+ m_gotInt = true;
+}
+
+Ptr<TraceResolver>
+CompositeTraceResolverTest::CreateSubResolver (void)
+{
+ Ptr<CompositeTraceResolver> subresolver = Create<CompositeTraceResolver> ();
+ subresolver->AddSource ("trace-int", TraceDoc ("test source"), m_traceInt,
+ SubTraceSourceTest (SubTraceSourceTest::INT));
+ return subresolver;
+}
+bool
+CompositeTraceResolverTest::RunTests (void)
+{
+ bool ok = true;
+
+ CallbackTraceSource<double> traceDoubleA;
+ CallbackTraceSource<double> traceDoubleB;
+ TraceContext context;
+
+ CompositeTraceResolver resolver;
+
+ resolver.AddSource ("trace-double-a", TraceDoc ("test source"), traceDoubleA,
+ TraceSourceTest (TraceSourceTest::DOUBLEA));
+ resolver.AddSource ("trace-double-b", TraceDoc ("test source"), traceDoubleB,
+ TraceSourceTest (TraceSourceTest::DOUBLEB));
+
+ resolver.Connect ("/*", MakeCallback (&CompositeTraceResolverTest::TraceDouble, this), TraceContext ());
+
+ m_gotDoubleA = false;
+ m_gotDoubleB = false;
+ traceDoubleA (0);
+ if (!m_gotDoubleA || m_gotDoubleB)
+ {
+ ok = false;
+ }
+ m_gotDoubleA = false;
+ traceDoubleA (0);
+ traceDoubleB (0);
+ if (!m_gotDoubleA || !m_gotDoubleB)
+ {
+ ok = false;
+ }
+ m_gotDoubleA = false;
+ m_gotDoubleB = false;
+
+ resolver.Disconnect ("/*", MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+
+ m_gotDoubleA = false;
+ m_gotDoubleB = false;
+ traceDoubleA (0);
+ traceDoubleB (0);
+ if (m_gotDoubleA || m_gotDoubleB)
+ {
+ ok = false;
+ }
+
+ resolver.Connect ("/trace-double-a",
+ MakeCallback (&CompositeTraceResolverTest::TraceDouble, this), TraceContext ());
+ m_gotDoubleA = false;
+ m_gotDoubleB = false;
+ traceDoubleA (0);
+ traceDoubleB (0);
+ if (!m_gotDoubleA || m_gotDoubleB)
+ {
+ ok = false;
+ }
+ resolver.Disconnect ("/trace-double-a",
+ MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+
+ resolver.Connect ("/(trace-double-a)",
+ MakeCallback (&CompositeTraceResolverTest::TraceDouble, this), TraceContext ());
+ m_gotDoubleA = false;
+ m_gotDoubleB = false;
+ traceDoubleA (0);
+ traceDoubleB (0);
+ if (!m_gotDoubleA || m_gotDoubleB)
+ {
+ ok = false;
+ }
+ resolver.Disconnect ("/trace-double-a",
+ MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+
+ resolver.Connect ("/(trace-double-a|trace-double-b)",
+ MakeCallback (&CompositeTraceResolverTest::TraceDouble, this), TraceContext ());
+ m_gotDoubleA = false;
+ m_gotDoubleB = false;
+ traceDoubleA (0);
+ traceDoubleB (0);
+ if (!m_gotDoubleA || !m_gotDoubleB)
+ {
+ ok = false;
+ }
+ resolver.Disconnect ("/trace-double-a",
+ MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+ m_gotDoubleA = false;
+ m_gotDoubleB = false;
+ traceDoubleA (0);
+ traceDoubleB (0);
+ if (m_gotDoubleA || !m_gotDoubleB)
+ {
+ ok = false;
+ }
+
+
+ resolver.Disconnect ("/(trace-double-a|trace-double-b)",
+ MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+ m_gotDoubleA = false;
+ m_gotDoubleB = false;
+ traceDoubleA (0);
+ traceDoubleB (0);
+ if (m_gotDoubleA || m_gotDoubleB)
+ {
+ ok = false;
+ }
+
+ resolver.Add ("subresolver",
+ MakeCallback (&CompositeTraceResolverTest::CreateSubResolver, this));
+
+ resolver.Connect ("/subresolver/trace-int",
+ MakeCallback (&CompositeTraceResolverTest::TraceInt, this), TraceContext ());
+ m_gotInt = false;
+ m_traceInt (1);
+ if (!m_gotInt)
+ {
+ ok = false;
+ }
+
+ resolver.Disconnect ("/subresolver/trace-int",
+ MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
+ m_gotInt = false;
+ m_traceInt (1);
+ if (m_gotInt)
+ {
+ ok = false;
+ }
+
+ resolver.Connect ("/*/trace-int",
+ MakeCallback (&CompositeTraceResolverTest::TraceInt, this), TraceContext ());
+ m_gotInt = false;
+ m_traceInt (1);
+ if (!m_gotInt)
+ {
+ ok = false;
+ }
+
+ resolver.Disconnect ("/subresolver/trace-int",
+ MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
+ m_gotInt = false;
+ m_traceInt (1);
+ if (m_gotInt)
+ {
+ ok = false;
+ }
+
+ SVTraceSource<uint16_t> source;
+
+ resolver.AddSource ("uint16_t", TraceDoc ("test source"), source, TraceSourceTest (TraceSourceTest::UINT16_T));
+
+
+ return ok;
+}
+
+static CompositeTraceResolverTest g_compositeTraceResolverTest;
+
+}//namespace ns3
+
+
+#endif /* RUN_SELF_TESTS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/composite-trace-resolver.h Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,233 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef COMPOSITE_TRACE_RESOLVER_H
+#define COMPOSITE_TRACE_RESOLVER_H
+
+#include <vector>
+#include "callback.h"
+#include "ptr.h"
+#include "trace-resolver.h"
+#include "callback-trace-source.h"
+#include "uv-trace-source.h"
+#include "sv-trace-source.h"
+#include "fv-trace-source.h"
+#include "array-trace-resolver.h"
+#include "trace-doc.h"
+
+namespace ns3 {
+
+/**
+ * \brief a helper class to aggregate contained TraceResolver and other trace sources.
+ * \ingroup tracing
+ */
+class CompositeTraceResolver : public TraceResolver
+{
+public:
+ CompositeTraceResolver ();
+ virtual ~CompositeTraceResolver ();
+ /**
+ * \param name name of trace source
+ * \param doc the documentation associated to this trace source
+ * \param trace a callback trace source
+ * \param context the context associated to this trace source
+ *
+ * Add a callback trace source in this resolver. This trace
+ * source will match the name specified during namespace
+ * resolution. The TraceContext of this trace source will also
+ * be automatically extended to contain the input context.
+ */
+ template <typename T>
+ void AddSource (std::string name, const TraceDoc &doc,
+ const TraceSource &trace, T const &context);
+ /**
+ * \param name name of trace source
+ * \param doc the documentation associated to this trace source
+ * \param trace a callback trace source
+ *
+ * Add a callback trace source in this resolver. This trace
+ * source will match the name specified during namespace
+ * resolution.
+ */
+ void AddSource (std::string name,
+ const TraceDoc &doc,
+ const TraceSource &trace);
+
+ /**
+ * \param name the name of the composite element
+ * \param composite the composite object
+ *
+ * The input composite object will be used to resolve a connection
+ * of a disconnection attempt if its name matches the trace path.
+ *
+ */
+ void AddComposite (std::string name, Ptr<Object> composite);
+
+ /**
+ * \param name the name of the composite element
+ * \param composite the composite object
+ * \param contextElement the context element associated to the composite
+ *
+ * The input composite object will be used to resolve a connection
+ * of a disconnection attempt if its name matches the trace path.
+ * The contextElement will be appended to the TraceContext during connection.
+ */
+ template <typename T>
+ void AddComposite (std::string name, Ptr<Object> composite, const T &contextElement);
+
+ /**
+ * \param name the name of the array
+ * \param begin an iterator which points to the first element of the array
+ * \param end an iterator which points to the last element of the array
+ * \param index an object which can store the index of an element in the
+ * array. In practice, this object should support a constructor
+ * whose single argument is an array index.
+ */
+ template <typename ITERATOR, typename INDEX>
+ void AddArray (std::string name,
+ ITERATOR begin, ITERATOR end, INDEX index);
+
+ /**
+ * \param parent the parent trace resolver
+ *
+ * The parent trace resolver is the trace resolver returned by the
+ * GetTraceResolver method of the base class of the caller. It is
+ * used during connection and disconnection to chain up the connect
+ * and disconnect calls to the parent.
+ */
+ void SetParentResolver (Ptr<TraceResolver> parent);
+
+
+private:
+ virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context);
+ virtual void Disconnect (std::string path, CallbackBase const &cb);
+ virtual void CollectSources (std::string path, const TraceContext &context,
+ SourceCollection *collection);
+ virtual void TraceAll (std::ostream &os, const TraceContext &context);
+ friend class CompositeTraceResolverTest;
+ class ResolveItem
+ {
+ public:
+ virtual ~ResolveItem () {}
+ virtual void Connect (std::string subpath, const CallbackBase &cb, const TraceContext &context) = 0;
+ virtual void Disconnect (std::string subpath, const CallbackBase &cb) = 0;
+ virtual void CollectSources (std::string path, const TraceContext &context,
+ SourceCollection *collection) = 0;
+ virtual void TraceAll (std::ostream &os, const TraceContext &context) = 0;
+
+ std::string name;
+ TraceContext context;
+ };
+ typedef std::vector<ResolveItem *> TraceItems;
+ class Operation
+ {
+ public:
+ virtual ~Operation () {}
+ virtual void Do (std::string subpath, ResolveItem *item) const = 0;
+ virtual void DoParent (std::string path, Ptr<TraceResolver> parent) const = 0;
+ };
+
+ void AddItem (ResolveItem *item);
+ void DoRecursiveOperation (std::string path,
+ const Operation &operation);
+ void DoRecursiveOperationForParent (std::string path,
+ const Operation &operation);
+ void DoAddComposite (std::string name, Ptr<Object> composite, const TraceContext &context);
+ void DoAddSource (std::string name,
+ const TraceDoc &doc,
+ const TraceSource &trace,
+ const TraceContext &context);
+ void Add (std::string name,
+ Callback<Ptr<TraceResolver> > createResolver);
+
+
+ CompositeTraceResolver::TraceItems m_items;
+ Ptr<TraceResolver> m_parent;
+};
+
+}//namespace ns3
+
+namespace ns3 {
+
+
+
+template <typename T>
+void
+CompositeTraceResolver::AddSource (std::string name,
+ const TraceDoc &doc,
+ const TraceSource &trace,
+ T const &context)
+{
+ TraceContext ctx;
+ ctx.AddElement (context);
+ DoAddSource (name, doc, trace, ctx);
+}
+
+template <typename ITERATOR, typename INDEX>
+void
+CompositeTraceResolver::AddArray (std::string name,
+ ITERATOR begin, ITERATOR end, INDEX index)
+{
+ class ArrayResolveItem : public ResolveItem
+ {
+ public:
+ virtual void Connect (std::string subpath, const CallbackBase &cb, const TraceContext &context)
+ {array->Connect (subpath, cb, context);}
+ virtual void Disconnect (std::string subpath, const CallbackBase &cb)
+ {array->Disconnect (subpath, cb);}
+ virtual void CollectSources (std::string path, const TraceContext &context,
+ SourceCollection *collection)
+ {
+ path.append ("/");
+ path.append (this->name);
+ TraceContext ctx = context;
+ ctx.Union (this->context);
+ array->CollectSources (path, ctx, collection);
+ }
+ virtual void TraceAll (std::ostream &os, const TraceContext &context)
+ {
+ TraceContext ctx = context;
+ ctx.Union (this->context);
+ array->TraceAll (os, ctx);
+ }
+
+ Ptr<ArrayTraceResolver<INDEX> > array;
+ } *item = new ArrayResolveItem ();
+ item->name = name;
+ item->context = TraceContext ();
+ item->array = Create<ArrayTraceResolver<INDEX> > ();
+ item->array->SetIterators (begin, end);
+ AddItem (item);
+}
+
+template <typename T>
+void
+CompositeTraceResolver::AddComposite (std::string name, Ptr<Object> composite, const T &contextElement)
+{
+ TraceContext context;
+ context.AddElement (contextElement);
+ DoAddComposite (name, composite, context);
+}
+
+
+
+}//namespace ns3
+
+#endif /* COMPOSITE_TRACE_RESOLVER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/fv-trace-source.h Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,71 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef F_VARIABLE_TRACER_H
+#define F_VARIABLE_TRACER_H
+
+#include "callback-trace-source.h"
+#include "trace-source.h"
+#include <stdint.h>
+
+namespace ns3 {
+
+class FVTraceSourceBase : public TraceSource {
+public:
+ typedef CallbackTraceSource<double, double> ChangeNotifyCallback;
+
+ FVTraceSourceBase () {}
+ FVTraceSourceBase (FVTraceSourceBase const &o) {}
+ FVTraceSourceBase &operator = (FVTraceSourceBase const &o) {
+ return *this;
+ }
+
+ ~FVTraceSourceBase () {}
+
+ virtual void AddCallback (CallbackBase const & callback, TraceContext const & context) {
+ m_callback.AddCallback (callback, context);
+ }
+ virtual void RemoveCallback (CallbackBase const & callback) {
+ m_callback.RemoveCallback (callback);
+ }
+ virtual void ConnectPrinter (std::ostream &os, const TraceContext &context) {
+ m_callback.ConnectPrinter (os, context);
+ }
+protected:
+ void notify (double oldVal, double newVal) {
+ if (oldVal != newVal)
+ {
+ m_callback (oldVal, newVal);
+ }
+ }
+private:
+ ChangeNotifyCallback m_callback;
+};
+
+template <typename T>
+class FVTraceSource : public FVTraceSourceBase
+{
+public:
+};
+
+}; // namespace ns3
+
+#endif /* F_VARIABLE_TRACER_H */
--- a/src/core/object.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/core/object.cc Tue Sep 11 14:52:15 2007 +0100
@@ -22,8 +22,12 @@
#include "assert.h"
#include "singleton.h"
#include "uid-manager.h"
+#include "trace-resolver.h"
+#include "debug.h"
#include <vector>
+NS_DEBUG_COMPONENT_DEFINE ("Object");
+
namespace {
class IidManager : public ns3::UidManager
@@ -34,6 +38,7 @@
public:
void SetParent (uint16_t child, const uint16_t *parent);
uint16_t LookupParent (uint16_t child);
+
private:
std::vector<const uint16_t *> m_parents;
};
@@ -55,6 +60,68 @@
namespace ns3 {
+class InterfaceIdTraceResolver : public TraceResolver
+{
+public:
+ InterfaceIdTraceResolver (Ptr<const Object> aggregate);
+ virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context);
+ virtual void Disconnect (std::string path, CallbackBase const &cb);
+ virtual void CollectSources (std::string path, const TraceContext &context,
+ SourceCollection *collection);
+ virtual void TraceAll (std::ostream &os, const TraceContext &context);
+private:
+ Ptr<const Object> ParseForInterface (std::string path);
+ Ptr<const Object> m_aggregate;
+};
+
+InterfaceIdTraceResolver::InterfaceIdTraceResolver (Ptr<const Object> aggregate)
+ : m_aggregate (aggregate)
+{}
+Ptr<const Object>
+InterfaceIdTraceResolver::ParseForInterface (std::string path)
+{
+ std::string element = GetElement (path);
+ std::string::size_type dollar_pos = element.find ("$");
+ if (dollar_pos != 0)
+ {
+ return 0;
+ }
+ std::string interfaceName = element.substr (1, std::string::npos);
+ InterfaceId interfaceId = InterfaceId::LookupByName (interfaceName);
+ Ptr<Object> interface = m_aggregate->QueryInterface<Object> (interfaceId);
+ return interface;
+}
+void
+InterfaceIdTraceResolver::Connect (std::string path, CallbackBase const &cb, const TraceContext &context)
+{
+ Ptr<const Object> interface = ParseForInterface (path);
+ if (interface != 0)
+ {
+ interface->GetTraceResolver ()->Connect (GetSubpath (path), cb, context);
+ }
+}
+void
+InterfaceIdTraceResolver::Disconnect (std::string path, CallbackBase const &cb)
+{
+ Ptr<const Object> interface = ParseForInterface (path);
+ if (interface != 0)
+ {
+ interface->TraceDisconnect (GetSubpath (path), cb);
+ }
+}
+void
+InterfaceIdTraceResolver::CollectSources (std::string path, const TraceContext &context,
+ SourceCollection *collection)
+{
+ m_aggregate->DoCollectSources (path, context, collection);
+}
+void
+InterfaceIdTraceResolver::TraceAll (std::ostream &os, const TraceContext &context)
+{
+ m_aggregate->DoTraceAll (os, context);
+}
+
+
InterfaceId::InterfaceId (uint16_t iid)
: m_iid (iid)
{}
@@ -72,6 +139,12 @@
{
return Singleton<IidTree>::Get ()->LookupParent (iid.m_iid);
}
+std::string
+InterfaceId::GetName (void) const
+{
+ std::string name = Singleton<IidManager>::Get ()->LookupByUid (m_iid);
+ return name;
+}
bool operator == (const InterfaceId &a, const InterfaceId &b)
{
@@ -109,6 +182,7 @@
: m_count (1),
m_iid (Object::iid),
m_disposed (false),
+ m_collecting (false),
m_next (this)
{}
Object::~Object ()
@@ -164,6 +238,17 @@
}
void
+Object::TraceConnect (std::string path, const CallbackBase &cb) const
+{
+ GetTraceResolver ()->Connect (path, cb, TraceContext ());
+}
+void
+Object::TraceDisconnect (std::string path, const CallbackBase &cb) const
+{
+ GetTraceResolver ()->Disconnect (path, cb);
+}
+
+void
Object::SetInterfaceId (InterfaceId iid)
{
NS_ASSERT (Check ());
@@ -176,6 +261,14 @@
NS_ASSERT (!m_disposed);
}
+Ptr<TraceResolver>
+Object::GetTraceResolver (void) const
+{
+ Ptr<InterfaceIdTraceResolver> resolver =
+ Create<InterfaceIdTraceResolver> (this);
+ return resolver;
+}
+
bool
Object::Check (void) const
{
@@ -209,12 +302,77 @@
} while (current != end);
}
+void
+Object::DoCollectSources (std::string path, const TraceContext &context,
+ TraceResolver::SourceCollection *collection) const
+{
+ const Object *current;
+ current = this;
+ do {
+ if (current->m_collecting)
+ {
+ return;
+ }
+ current = current->m_next;
+ } while (current != this);
+
+ m_collecting = true;
+
+ current = this->m_next;
+ while (current != this)
+ {
+ NS_ASSERT (current != 0);
+ NS_DEBUG ("collect current=" << current);
+ InterfaceId cur = current->m_iid;
+ while (cur != Object::iid)
+ {
+ std::string name = cur.GetName ();
+ std::string fullpath = path;
+ fullpath.append ("/$");
+ fullpath.append (name);
+ NS_DEBUG ("collect: " << fullpath);
+ current->GetTraceResolver ()->CollectSources (fullpath, context, collection);
+ cur = InterfaceId::LookupParent (cur);
+ }
+ current = current->m_next;
+ }
+
+ m_collecting = false;
+}
+void
+Object::DoTraceAll (std::ostream &os, const TraceContext &context) const
+{
+ const Object *current;
+ current = this;
+ do {
+ if (current->m_collecting)
+ {
+ return;
+ }
+ current = current->m_next;
+ } while (current != this);
+
+ m_collecting = true;
+
+ current = this->m_next;
+ while (current != this)
+ {
+ NS_ASSERT (current != 0);
+ current->GetTraceResolver ()->TraceAll (os, context);
+ current = current->m_next;
+ }
+
+ m_collecting = false;
+}
+
} // namespace ns3
#ifdef RUN_SELF_TESTS
#include "test.h"
+#include "sv-trace-source.h"
+#include "composite-trace-resolver.h"
namespace {
@@ -226,7 +384,18 @@
{
SetInterfaceId (BaseA::iid);
}
+ void BaseGenerateTrace (int16_t v)
+ { m_source = v; }
virtual void Dispose (void) {}
+ virtual ns3::Ptr<ns3::TraceResolver> GetTraceResolver (void) const
+ {
+ ns3::Ptr<ns3::CompositeTraceResolver> resolver =
+ ns3::Create<ns3::CompositeTraceResolver> ();
+ resolver->AddSource ("basea-x", ns3::TraceDoc ("test source"), m_source);
+ resolver->SetParentResolver (Object::GetTraceResolver ());
+ return resolver;
+ }
+ ns3::SVTraceSource<int16_t> m_source;
};
class DerivedA : public BaseA
@@ -237,9 +406,20 @@
{
SetInterfaceId (DerivedA::iid);
}
+ void DerivedGenerateTrace (int16_t v)
+ { m_sourceDerived = v; }
virtual void Dispose (void) {
BaseA::Dispose ();
}
+ virtual ns3::Ptr<ns3::TraceResolver> GetTraceResolver (void) const
+ {
+ ns3::Ptr<ns3::CompositeTraceResolver> resolver =
+ ns3::Create<ns3::CompositeTraceResolver> ();
+ resolver->AddSource ("deriveda-x", ns3::TraceDoc ("test source"), m_sourceDerived);
+ resolver->SetParentResolver (BaseA::GetTraceResolver ());
+ return resolver;
+ }
+ ns3::SVTraceSource<int16_t> m_sourceDerived;
};
const ns3::InterfaceId BaseA::iid =
@@ -255,7 +435,18 @@
{
SetInterfaceId (BaseB::iid);
}
+ void BaseGenerateTrace (int16_t v)
+ { m_source = v; }
virtual void Dispose (void) {}
+ virtual ns3::Ptr<ns3::TraceResolver> GetTraceResolver (void) const
+ {
+ ns3::Ptr<ns3::CompositeTraceResolver> resolver =
+ ns3::Create<ns3::CompositeTraceResolver> ();
+ resolver->AddSource ("baseb-x", ns3::TraceDoc ("test source"), m_source);
+ resolver->SetParentResolver (Object::GetTraceResolver ());
+ return resolver;
+ }
+ ns3::SVTraceSource<int16_t> m_source;
};
class DerivedB : public BaseB
@@ -266,9 +457,20 @@
{
SetInterfaceId (DerivedB::iid);
}
+ void DerivedGenerateTrace (int16_t v)
+ { m_sourceDerived = v; }
virtual void Dispose (void) {
BaseB::Dispose ();
}
+ virtual ns3::Ptr<ns3::TraceResolver> GetTraceResolver (void) const
+ {
+ ns3::Ptr<ns3::CompositeTraceResolver> resolver =
+ ns3::Create<ns3::CompositeTraceResolver> ();
+ resolver->AddSource ("derivedb-x", ns3::TraceDoc ("test source"), m_sourceDerived);
+ resolver->SetParentResolver (BaseB::GetTraceResolver ());
+ return resolver;
+ }
+ ns3::SVTraceSource<int16_t> m_sourceDerived;
};
const ns3::InterfaceId BaseB::iid =
@@ -285,120 +487,82 @@
public:
ObjectTest ();
virtual bool RunTests (void);
+private:
+ void BaseATrace (const TraceContext &context, int64_t oldValue, int64_t newValue);
+ void DerivedATrace (const TraceContext &context, int64_t oldValue, int64_t newValue);
+ void BaseBTrace (const TraceContext &context, int64_t oldValue, int64_t newValue);
+ void DerivedBTrace (const TraceContext &context, int64_t oldValue, int64_t newValue);
+
+ bool m_baseATrace;
+ bool m_derivedATrace;
+ bool m_baseBTrace;
+ bool m_derivedBTrace;
};
ObjectTest::ObjectTest ()
: Test ("Object")
{}
+void
+ObjectTest::BaseATrace (const TraceContext &context, int64_t oldValue, int64_t newValue)
+{
+ m_baseATrace = true;
+}
+void
+ObjectTest::DerivedATrace (const TraceContext &context, int64_t oldValue, int64_t newValue)
+{
+ m_derivedATrace = true;
+}
+void
+ObjectTest::BaseBTrace (const TraceContext &context, int64_t oldValue, int64_t newValue)
+{
+ m_baseBTrace = true;
+}
+void
+ObjectTest::DerivedBTrace (const TraceContext &context, int64_t oldValue, int64_t newValue)
+{
+ m_derivedBTrace = true;
+}
+
bool
ObjectTest::RunTests (void)
{
- bool ok = true;
+ bool result = true;
Ptr<BaseA> baseA = Create<BaseA> ();
- if (baseA->QueryInterface<BaseA> (BaseA::iid) != baseA)
- {
- ok = false;
- }
- if (baseA->QueryInterface<BaseA> (DerivedA::iid) != 0)
- {
- ok = false;
- }
- if (baseA->QueryInterface<DerivedA> (DerivedA::iid) != 0)
- {
- ok = false;
- }
+ NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<BaseA> (BaseA::iid), baseA);
+ NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<BaseA> (DerivedA::iid), 0);
+ NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<DerivedA> (DerivedA::iid), 0);
baseA = Create<DerivedA> (10);
- if (baseA->QueryInterface<BaseA> (BaseA::iid) != baseA)
- {
- ok = false;
- }
- if (baseA->QueryInterface<BaseA> (DerivedA::iid) != baseA)
- {
- ok = false;
- }
- if (baseA->QueryInterface<DerivedA> (DerivedA::iid) == 0)
- {
- ok = false;
- }
+ NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<BaseA> (BaseA::iid), baseA);
+ NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<BaseA> (DerivedA::iid), baseA);
+ NS_TEST_ASSERT_UNEQUAL (baseA->QueryInterface<DerivedA> (DerivedA::iid), 0);
baseA = Create<BaseA> ();
Ptr<BaseB> baseB = Create<BaseB> ();
Ptr<BaseB> baseBCopy = baseB;
baseA->AddInterface (baseB);
- if (baseA->QueryInterface<BaseA> (BaseA::iid) == 0)
- {
- ok = false;
- }
- if (baseA->QueryInterface<DerivedA> (DerivedA::iid) != 0)
- {
- ok = false;
- }
- if (baseA->QueryInterface<BaseB> (BaseB::iid) == 0)
- {
- ok = false;
- }
- if (baseA->QueryInterface<DerivedB> (DerivedB::iid) != 0)
- {
- ok = false;
- }
- if (baseB->QueryInterface<BaseB> (BaseB::iid) == 0)
- {
- ok = false;
- }
- if (baseB->QueryInterface<DerivedB> (DerivedB::iid) != 0)
- {
- ok = false;
- }
- if (baseB->QueryInterface<BaseA> (BaseA::iid) == 0)
- {
- ok = false;
- }
- if (baseB->QueryInterface<DerivedA> (DerivedA::iid) != 0)
- {
- ok = false;
- }
- if (baseBCopy->QueryInterface<BaseA> (BaseA::iid) == 0)
- {
- ok = false;
- }
+ NS_TEST_ASSERT_UNEQUAL (baseA->QueryInterface<BaseA> (BaseA::iid), 0);
+ NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<DerivedA> (DerivedA::iid), 0);
+ NS_TEST_ASSERT_UNEQUAL (baseA->QueryInterface<BaseB> (BaseB::iid), 0);
+ NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<DerivedB> (DerivedB::iid), 0);
+ NS_TEST_ASSERT_UNEQUAL (baseB->QueryInterface<BaseB> (BaseB::iid), 0);
+ NS_TEST_ASSERT_EQUAL (baseB->QueryInterface<DerivedB> (DerivedB::iid), 0);
+ NS_TEST_ASSERT_UNEQUAL (baseB->QueryInterface<BaseA> (BaseA::iid), 0);
+ NS_TEST_ASSERT_EQUAL (baseB->QueryInterface<DerivedA> (DerivedA::iid), 0);
+ NS_TEST_ASSERT_UNEQUAL (baseBCopy->QueryInterface<BaseA> (BaseA::iid), 0);
baseA = Create<DerivedA> (1);
baseB = Create<DerivedB> (1);
baseBCopy = baseB;
baseA->AddInterface (baseB);
- if (baseA->QueryInterface<DerivedB> (DerivedB::iid) == 0)
- {
- ok = false;
- }
- if (baseA->QueryInterface<BaseB> (BaseB::iid) == 0)
- {
- ok = false;
- }
- if (baseB->QueryInterface<DerivedA> (DerivedA::iid) == 0)
- {
- ok = false;
- }
- if (baseB->QueryInterface<BaseA> (BaseA::iid) == 0)
- {
- ok = false;
- }
- if (baseBCopy->QueryInterface<DerivedA> (DerivedA::iid) == 0)
- {
- ok = false;
- }
- if (baseBCopy->QueryInterface<BaseA> (BaseA::iid) == 0)
- {
- ok = false;
- }
- if (baseB->QueryInterface<DerivedB> (DerivedB::iid) == 0)
- {
- ok = false;
- }
- if (baseB->QueryInterface<BaseB> (BaseB::iid) == 0)
- {
- ok = false;
- }
+ NS_TEST_ASSERT_UNEQUAL (baseA->QueryInterface<DerivedB> (DerivedB::iid), 0);
+ NS_TEST_ASSERT_UNEQUAL (baseA->QueryInterface<BaseB> (BaseB::iid), 0);
+ NS_TEST_ASSERT_UNEQUAL (baseB->QueryInterface<DerivedA> (DerivedA::iid), 0);
+ NS_TEST_ASSERT_UNEQUAL (baseB->QueryInterface<BaseA> (BaseA::iid), 0);
+ NS_TEST_ASSERT_UNEQUAL (baseBCopy->QueryInterface<DerivedA> (DerivedA::iid), 0);
+ NS_TEST_ASSERT_UNEQUAL (baseBCopy->QueryInterface<BaseA> (BaseA::iid), 0);
+ NS_TEST_ASSERT_UNEQUAL (baseB->QueryInterface<DerivedB> (DerivedB::iid), 0);
+ NS_TEST_ASSERT_UNEQUAL (baseB->QueryInterface<BaseB> (BaseB::iid), 0)
baseA = Create<BaseA> ();
baseB = Create<BaseB> ();
@@ -406,7 +570,76 @@
baseA = 0;
baseA = baseB->QueryInterface<BaseA> (BaseA::iid);
- return ok;
+ baseA = Create<BaseA> ();
+ baseA->TraceConnect ("/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+ m_baseATrace = false;
+ baseA->BaseGenerateTrace (1);
+ NS_TEST_ASSERT (m_baseATrace);
+ baseA->TraceDisconnect ("/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+
+ baseB = Create<BaseB> ();
+ baseB->TraceConnect ("/baseb-x", MakeCallback (&ObjectTest::BaseBTrace, this));
+ m_baseBTrace = false;
+ baseB->BaseGenerateTrace (2);
+ NS_TEST_ASSERT (m_baseBTrace);
+ baseB->TraceDisconnect ("/baseb-x", MakeCallback (&ObjectTest::BaseBTrace, this));
+
+ baseA->AddInterface (baseB);
+
+ baseA->TraceConnect ("/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+ m_baseATrace = false;
+ baseA->BaseGenerateTrace (3);
+ NS_TEST_ASSERT (m_baseATrace);
+ baseA->TraceDisconnect ("/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+
+ baseA->TraceConnect ("/$BaseB/baseb-x", MakeCallback (&ObjectTest::BaseBTrace, this));
+ m_baseBTrace = false;
+ baseB->BaseGenerateTrace (4);
+ NS_TEST_ASSERT (m_baseBTrace);
+ baseA->TraceDisconnect ("/$BaseB/baseb-x", MakeCallback (&ObjectTest::BaseBTrace, this));
+ m_baseBTrace = false;
+ baseB->BaseGenerateTrace (5);
+ NS_TEST_ASSERT (!m_baseBTrace);
+
+ baseB->TraceConnect ("/$BaseA/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+ m_baseATrace = false;
+ baseA->BaseGenerateTrace (6);
+ NS_TEST_ASSERT (m_baseATrace);
+ baseB->TraceDisconnect ("/$BaseA/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+
+ baseA->TraceConnect ("/$BaseA/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+ m_baseATrace = false;
+ baseA->BaseGenerateTrace (7);
+ NS_TEST_ASSERT (m_baseATrace);
+ baseA->TraceDisconnect ("/$BaseA/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+
+ Ptr<DerivedA> derivedA;
+ derivedA = Create<DerivedA> (1);
+ baseB = Create<BaseB> ();
+ derivedA->AddInterface (baseB);
+ baseB->TraceConnect ("/$DerivedA/deriveda-x", MakeCallback (&ObjectTest::DerivedATrace, this));
+ baseB->TraceConnect ("/$DerivedA/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+ m_derivedATrace = false;
+ m_baseATrace = false;
+ derivedA->DerivedGenerateTrace (8);
+ derivedA->BaseGenerateTrace (9);
+ NS_TEST_ASSERT (m_derivedATrace);
+ NS_TEST_ASSERT (m_baseATrace);
+ baseB->TraceDisconnect ("/$DerivedA/deriveda-x", MakeCallback (&ObjectTest::BaseATrace, this));
+ baseB->TraceDisconnect ("/$DerivedA/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+
+ baseB->TraceConnect ("/$DerivedA/*", MakeCallback (&ObjectTest::DerivedATrace, this));
+ m_derivedATrace = false;
+ derivedA->DerivedGenerateTrace (10);
+ NS_TEST_ASSERT (m_derivedATrace);
+ // here, we have connected the derived trace sink to all
+ // trace sources, including the base trace source.
+ m_derivedATrace = false;
+ derivedA->BaseGenerateTrace (11);
+ NS_TEST_ASSERT (m_derivedATrace);
+ baseB->TraceDisconnect ("/$DerivedA/*", MakeCallback (&ObjectTest::BaseATrace, this));
+
+ return result;
}
static ObjectTest g_interfaceObjectTests;
--- a/src/core/object.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/core/object.h Tue Sep 11 14:52:15 2007 +0100
@@ -24,9 +24,13 @@
#include <stdint.h>
#include <string>
#include "ptr.h"
+#include "trace-resolver.h"
namespace ns3 {
+class TraceContext;
+class CallbackBase;
+
/**
* \brief a unique identifier for an interface.
*
@@ -56,6 +60,11 @@
* id is not a valid interface id.
*/
static InterfaceId LookupParent (InterfaceId iid);
+
+ /**
+ * \returns the name of this interface.
+ */
+ std::string GetName (void) const;
~InterfaceId ();
private:
InterfaceId (uint16_t iid);
@@ -131,6 +140,30 @@
* on one to get the other, and vice-versa.
*/
void AddInterface (Ptr<Object> other);
+
+ /**
+ * \param path the path to match for the callback
+ * \param cb callback to connect
+ *
+ * Connect the input callback to all trace sources which
+ * match the input path.
+ *
+ */
+ void TraceConnect (std::string path, const CallbackBase &cb) const;
+ /**
+ * \param path the path to match for the callback
+ * \param cb callback to disconnect
+ *
+ * Disconnect the input callback from all trace sources which
+ * match the input path.
+ */
+ void TraceDisconnect (std::string path, const CallbackBase &cb) const;
+ /**
+ * \returns the trace resolver associated to this object.
+ *
+ * This method should be rarely called by users.
+ */
+ virtual Ptr<TraceResolver> GetTraceResolver (void) const;
protected:
/**
* \param iid an InterfaceId
@@ -147,12 +180,17 @@
*/
virtual void DoDispose (void);
private:
+ friend class InterfaceIdTraceResolver;
Ptr<Object> DoQueryInterface (InterfaceId iid) const;
+ void DoCollectSources (std::string path, const TraceContext &context,
+ TraceResolver::SourceCollection *collection) const;
+ void DoTraceAll (std::ostream &os, const TraceContext &context) const;
bool Check (void) const;
void MaybeDelete (void) const;
mutable uint32_t m_count;
InterfaceId m_iid;
bool m_disposed;
+ mutable bool m_collecting;
Object *m_next;
};
--- a/src/core/random-variable-default-value.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/core/random-variable-default-value.cc Tue Sep 11 14:52:15 2007 +0100
@@ -19,7 +19,7 @@
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "random-variable-default-value.h"
-#include "ns3/debug.h"
+#include "debug.h"
NS_DEBUG_COMPONENT_DEFINE ("RandomVariableDefaultValue");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/stream-tracer-test.cc Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,68 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "stream-tracer.h"
+#include "test.h"
+#include <iostream>
+
+#ifdef RUN_SELF_TESTS
+
+namespace {
+
+class TestStreamTracer : public ns3::Test {
+public:
+ TestStreamTracer ();
+ virtual bool RunTests (void);
+};
+
+static TestStreamTracer gTestStream;
+
+TestStreamTracer::TestStreamTracer ()
+ : Test ("StreamTracer")
+{}
+
+bool
+TestStreamTracer::RunTests (void)
+{
+ bool ok = true;
+ ns3::StreamTracer trace;
+ //trace.setStream (&std::cout);
+ trace << 1;
+ trace << " X ";
+ trace << 1.0;
+ trace << std::endl;
+ trace << "test ";
+ trace << 1 << " test";
+ trace << "test "
+ << 1.0 << " "
+ << 0xdeadbead
+ << std::endl;
+ trace << "0x" << std::hex
+ << 0xdeadbeaf
+ << std::dec << " "
+ << 0xdeadbeaf
+ << std::endl;
+ return ok;
+}
+
+
+}; // namespace ns3
+
+#endif /* RUN_SELF_TESTS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/stream-tracer.h Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,76 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef STREAM_TRACER_H
+#define STREAM_TRACER_H
+
+#include <ostream>
+
+namespace ns3 {
+
+/**
+ * \brief log arbitrary data to std::ostreams
+ *
+ * Whenever operator << is invoked on this class,
+ * it is forwarded to the stored std::ostream output
+ * stream (if there is one).
+ */
+class StreamTracer {
+public:
+ StreamTracer ()
+ : m_os (0) {}
+ template <typename T>
+ StreamTracer &operator << (T const&v) {
+ if (m_os != 0)
+ {
+ (*m_os) << v;
+ }
+ return *this;
+ }
+ template <typename T>
+ StreamTracer &operator << (T &v) {
+ if (m_os != 0)
+ {
+ (*m_os) << v;
+ }
+ return *this;
+ }
+ StreamTracer &operator << (std::ostream &(*v) (std::ostream &)) {
+ if (m_os != 0)
+ {
+ (*m_os) << v;
+ }
+ return *this;
+ }
+
+ /**
+ * \param os the output stream to store
+ */
+ void SetStream (std::ostream * os) {
+ m_os = os;
+ }
+private:
+ std::ostream *m_os;
+};
+
+}; // namespace ns3
+
+
+#endif /* TRACER_STREAM_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/sv-trace-source.h Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,246 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef SV_TRACE_SOURCE_H
+#define SV_TRACE_SOURCE_H
+
+#include "callback-trace-source.h"
+#include "trace-source.h"
+#include <stdint.h>
+
+namespace ns3 {
+
+class SVTraceSourceBase : public TraceSource {
+public:
+ typedef CallbackTraceSource<int64_t, int64_t> ChangeNotifyCallback;
+
+ SVTraceSourceBase () {}
+ SVTraceSourceBase (SVTraceSourceBase const &o) {}
+ SVTraceSourceBase &operator = (SVTraceSourceBase const &o) {
+ return *this;
+ }
+
+ virtual ~SVTraceSourceBase () {}
+
+ virtual void AddCallback (CallbackBase const & callback, TraceContext const & context) {
+ m_callback.AddCallback (callback, context);
+ }
+ virtual void RemoveCallback (CallbackBase const & callback) {
+ m_callback.RemoveCallback (callback);
+ }
+ virtual void ConnectPrinter (std::ostream &os, const TraceContext &context) {
+ m_callback.ConnectPrinter (os, context);
+ }
+protected:
+ void Notify (int64_t oldVal, int64_t newVal) {
+ if (oldVal != newVal)
+ {
+ m_callback (oldVal, newVal);
+ }
+ }
+private:
+ ChangeNotifyCallback m_callback;
+};
+
+template <typename T>
+class UVTraceSource;
+
+
+/**
+ * \brief trace variables of type "signed integer"
+ * \ingroup tracing
+ *
+ * This template class implements a POD type: it
+ * behaves like any other variable of type "signed integer"
+ * except that it also reports any changes to its
+ * value with its internal callback.
+ *
+ * To instantiate a 32-bit signed variable (to store
+ * a TCP counter for example), you would create a variable of type
+ * ns3::UVTraceSource<int32_t> :
+ \code
+ #include <stdint.h>
+ #include "sv-trace-source.h"
+
+ ns3::SVTraceSource<uint16_t> var;
+ \endcode
+ * and you would use it like any other variable of type int32_t:
+ \code
+ var += 12;
+ var = 10;
+ var = -10;
+ \endcode
+ */
+template <typename T>
+class SVTraceSource : public SVTraceSourceBase {
+public:
+ SVTraceSource ()
+ : m_var (0)
+ {}
+ SVTraceSource (T const &var)
+ : m_var (var)
+ {}
+
+ SVTraceSource &operator = (SVTraceSource const &o) {
+ Assign (o.Get ());
+ return *this;
+ }
+ template <typename TT>
+ SVTraceSource &operator = (SVTraceSource<TT> const &o) {
+ Assign (o.Get ());
+ return *this;
+ }
+ template <typename TT>
+ SVTraceSource &operator = (UVTraceSource<TT> const &o) {
+ Assign (o.Get ());
+ return *this;
+ }
+ SVTraceSource &operator++ () {
+ Assign (Get () + 1);
+ return *this;
+ }
+ SVTraceSource &operator-- () {
+ Assign (Get () - 1);
+ return *this;
+ }
+ SVTraceSource operator++ (int) {
+ SVTraceSource old (*this);
+ ++*this;
+ return old;
+ }
+ SVTraceSource operator-- (int) {
+ SVTraceSource old (*this);
+ --*this;
+ return old;
+ }
+ operator T () const {
+ return Get ();
+ }
+
+
+ void Assign (T var) {
+ Notify (m_var, var);
+ m_var = var;
+ }
+ T Get (void) const {
+ return m_var;
+ }
+
+private:
+ T m_var;
+};
+
+template <typename T>
+SVTraceSource<T> &operator += (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () + rhs.Get ());
+ return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator -= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () - rhs.Get ());
+ return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator *= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () * rhs.Get ());
+ return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator /= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () / rhs.Get ());
+ return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator <<= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () << rhs.Get ());
+ return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator >>= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () >> rhs.Get ());
+ return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator &= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () & rhs.Get ());
+ return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator |= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () | rhs.Get ());
+ return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator ^= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () ^ rhs.Get ());
+ return lhs;
+}
+
+
+template <typename T, typename U>
+SVTraceSource<T> &operator += (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () + rhs);
+ return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator -= (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () - rhs);
+ return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator *= (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () * rhs);
+ return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator /= (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () / rhs);
+ return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator <<= (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () << rhs);
+ return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator >>= (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () >> rhs);
+ return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator &= (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () & rhs);
+ return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator |= (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () | rhs);
+ return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator ^= (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () ^ rhs);
+ return lhs;
+}
+
+}; // namespace ns3
+
+#endif /* SV_TRACE_SOURCE_H */
--- a/src/core/test.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/core/test.h Tue Sep 11 14:52:15 2007 +0100
@@ -119,6 +119,23 @@
result = false; \
}
/**
+ * Convenience macro to check that a value returned by a test is what
+ * is expected. Note: this macro assumes a 'bool result = true'
+ * declaration exists in the test function body, and that the function
+ * returns that value.
+ *
+ * \param got value obtained from the test
+ * \param expected value that the test is expected to return
+ */
+#define NS_TEST_ASSERT_UNEQUAL(got, expected) \
+ if ((got) == (expected)) \
+ { \
+ Failure () << __FILE__ << ":" <<__LINE__ \
+ << ": did not want " << (expected) \
+ << ", got " << (got) << std::endl; \
+ result = false; \
+ }
+/**
* Convenience macro to check an assertion is held during an unit
* test. Note: this macro assumes a 'bool result = true' declaration
* exists in the test function body, and that the function returns
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-context-element.cc Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,41 @@
+#include "trace-context-element.h"
+
+namespace ns3 {
+
+std::string
+ElementRegistry::GetTypeName (uint16_t uid)
+{
+ InfoVector *vec = GetInfoVector ();
+ struct Info info = (*vec)[uid - 1];
+ return info.getTypeName ();
+}
+uint32_t
+ElementRegistry::GetSize (uint16_t uid)
+{
+ InfoVector *vec = GetInfoVector ();
+ struct Info info = (*vec)[uid - 1];
+ return info.size;
+}
+void
+ElementRegistry::Print (uint16_t uid, uint8_t *instance, std::ostream &os)
+{
+ InfoVector *vec = GetInfoVector ();
+ struct Info info = (*vec)[uid - 1];
+ info.print (instance, os);
+}
+void
+ElementRegistry::Destroy (uint16_t uid, uint8_t *instance)
+{
+ InfoVector *vec = GetInfoVector ();
+ struct Info info = (*vec)[uid - 1];
+ info.destroy (instance);
+}
+ElementRegistry::InfoVector *
+ElementRegistry::GetInfoVector (void)
+{
+ static InfoVector vector;
+ return &vector;
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-context-element.h Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,211 @@
+#ifndef TRACE_CONTEXT_ELEMENT_H
+#define TRACE_CONTEXT_ELEMENT_H
+
+#include <string>
+#include <vector>
+
+#define NS_TRACE_CONTEXT_ELEMENT_ENSURE_REGISTERED(x) \
+namespace { \
+static class thisisaveryverylongclassname ##x \
+ { \
+ public: \
+ thisisaveryverylongclassname ##x () \
+ { uint32_t uid; uid = x::GetUid ();} \
+ } g_thisisanotherveryveryverylongname ##x ; \
+}
+
+namespace ns3 {
+
+/**
+ * \brief an item stored in a TraceContext
+ *
+ * To store trace context information in a TraceContext instance,
+ * users must subclass this base class and store subclass instances
+ * in a TraceContext with TraceContext::Add.
+ *
+ * Each subclass should define and implement:
+ * - a public default constructor: it is used by the internals
+ * of the implementation of TraceContext.
+ * - a public destructor: it is also used by the internals of
+ * the implementation of TraceContext.
+ * - a public static method named GetUid which returns a 16 bit
+ * integer. The integer returned from this method should be
+ * allocated with the protected AllocatedUid method.
+ * - a public Print method: this method is used by the
+ * TraceContext::Print method to print the content of each
+ * of the trace context element stored in the trace context.
+ * This method takes a c++ output stream and argument and is
+ * expected to write an ascii string describing its content
+ * in this output stream.
+ * - a public GetTypeName method which returns the fully-qualified
+ * c++ type name of this subclass as a string.
+ *
+ * A typical subclass should look like this:
+ * \code
+ * class MyContext : public TraceContextElement
+ * {
+ * public:
+ * // the _required_ public API
+ * static uint16_t GetUid (void);
+ * MyContext ();
+ * ~MyContext ();
+ * void Print (std::ostream &os) const;
+ * std::string GetTypeName (void) const;
+ *
+ * // the user-specific API to manipulate the context.
+ * void SetData (uint8_t data);
+ * uint8_t GetData (void) const;
+ * private:
+ * uint8_t m_myContextData;
+ * };
+ *
+ * uint16_t
+ * MyContext::GetUid (void)
+ * {
+ * static uint16_t uid = AllocateUid<MyContext> ("MyContext");
+ * return uid;
+ * }
+ * MyContext::MyContext ()
+ * {}
+ * MyContext::~MyContext ()
+ * {}
+ * void
+ * MyContext::Print (std::ostream &os) const
+ * {
+ * os << "mycontext=" << (uint32_t) m_myContextData;
+ * }
+ * std::string
+ * MyContext::GetTypeName (void) const
+ * {
+ * // return a fully-qualified c++ type name
+ * return "MyContext";
+ * }
+ * void
+ * MyContext::SetData (uint8_t data)
+ * {
+ * m_myContextData = data;
+ * }
+ * uint8_t
+ * MyContext::GetData (void) const
+ * {
+ * return m_myContextData;
+ * }
+ * \endcode
+ */
+class TraceContextElement
+{
+protected:
+ /**
+ * \param name a string which uniquely identifies the type
+ * of the subclass which is calling this method.
+ * \returns a unique 32 bit integer associated to the
+ * input string.
+ *
+ * Subclasses are expected to call this method from their
+ * public static GetUid method.
+ */
+ template <typename T>
+ static uint16_t AllocateUid (std::string name);
+};
+
+} // namespace ns3
+
+namespace ns3 {
+
+/**
+ * \brief a registry of TraceContextElement subclasses
+ * \internal
+ */
+class ElementRegistry
+{
+public:
+ template <typename T>
+ static uint16_t AllocateUid (std::string name);
+
+ static uint32_t GetSize (uint16_t uid);
+ static void Print (uint16_t uid, uint8_t *instance, std::ostream &os);
+ static std::string GetTypeName (uint16_t uid);
+ static void Destroy (uint16_t uid, uint8_t *instance);
+private:
+ typedef std::string (*GetTypeNameCb) (void);
+ typedef void (*PrintCb) (uint8_t *instance, std::ostream &os);
+ typedef void (*DestroyCb) (uint8_t *instance);
+ struct Info {
+ uint32_t size;
+ std::string uidString;
+ GetTypeNameCb getTypeName;
+ PrintCb print;
+ DestroyCb destroy;
+ };
+ typedef std::vector<struct Info> InfoVector;
+ static InfoVector *GetInfoVector (void);
+ template <typename T>
+ static std::string DoGetTypeName (void);
+ template <typename T>
+ static void DoPrint (uint8_t *instance, std::ostream &os);
+ template <typename T>
+ static void DoDestroy (uint8_t *instance);
+};
+
+template <typename T>
+void
+ElementRegistry::DoPrint (uint8_t *instance, std::ostream &os)
+{
+ static T obj;
+ // make sure we are aligned.
+ memcpy ((void*)&obj, instance, sizeof (T));
+ obj.Print (os);
+}
+template <typename T>
+std::string
+ElementRegistry::DoGetTypeName (void)
+{
+ static T obj;
+ return obj.GetTypeName ();
+}
+template <typename T>
+void
+ElementRegistry::DoDestroy (uint8_t *instance)
+{
+ static T obj;
+ // make sure we are aligned.
+ memcpy ((void*)&obj, instance, sizeof (T));
+ obj.~T ();
+}
+
+template <typename T>
+uint16_t
+ElementRegistry::AllocateUid (std::string name)
+{
+ InfoVector *vec = GetInfoVector ();
+ uint16_t uid = 1;
+ for (InfoVector::iterator i = vec->begin (); i != vec->end (); i++)
+ {
+ if (i->uidString == name)
+ {
+ return uid;
+ }
+ uid++;
+ }
+ struct Info info;
+ info.size = sizeof (T);
+ info.uidString = name;
+ info.getTypeName = &ElementRegistry::DoGetTypeName<T>;
+ info.print = &ElementRegistry::DoPrint<T>;
+ info.destroy = &ElementRegistry::DoDestroy<T>;
+ vec->push_back (info);
+ return vec->size ();
+}
+
+
+
+template <typename T>
+uint16_t
+TraceContextElement::AllocateUid (std::string name)
+{
+ return ElementRegistry::AllocateUid<T> (name);
+}
+
+} // namespace ns3
+
+#endif /* TRACE_CONTEXT_ELEMENT_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-context.cc Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,459 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "trace-context.h"
+#include "trace-context-element.h"
+#include "assert.h"
+
+namespace ns3 {
+
+TraceContext::Iterator::Iterator ()
+ : m_buffer (0),
+ m_size (0),
+ m_current (0)
+{}
+TraceContext::Iterator::Iterator (uint8_t *buffer, uint16_t size)
+ : m_buffer (buffer),
+ m_size (size),
+ m_current (0)
+{
+ m_uid = m_buffer[m_current];
+}
+bool
+TraceContext::Iterator::IsLast (void) const
+{
+ if (m_buffer == 0 || m_uid == 0 || m_current >= m_size)
+ {
+ return true;
+ }
+ return false;
+}
+void
+TraceContext::Iterator::Next (void)
+{
+ if (m_buffer == 0)
+ {
+ return;
+ }
+ if (m_uid == 0)
+ {
+ return;
+ }
+ else
+ {
+ uint8_t size = ElementRegistry::GetSize (m_uid);
+ m_current += 1 + size;
+ }
+ m_uid = m_buffer[m_current];
+}
+std::string
+TraceContext::Iterator::Get (void) const
+{
+ std::string name = ElementRegistry::GetTypeName (m_uid);
+ return name;
+}
+
+TraceContext::TraceContext ()
+ : m_data (0)
+{}
+TraceContext::TraceContext (TraceContext const &o)
+ : m_data (o.m_data)
+{
+ if (m_data != 0)
+ {
+ m_data->count++;
+ }
+}
+TraceContext const &
+TraceContext::operator = (TraceContext const &o)
+{
+ if (m_data != 0)
+ {
+ m_data->count--;
+ if (m_data->count == 0)
+ {
+ uint8_t *buffer = (uint8_t *)m_data;
+ delete [] buffer;
+ }
+ }
+ m_data = o.m_data;
+ if (m_data != 0)
+ {
+ m_data->count++;
+ }
+ return *this;
+}
+TraceContext::~TraceContext ()
+{
+ if (m_data != 0)
+ {
+ m_data->count--;
+ if (m_data->count == 0)
+ {
+ uint8_t *buffer = (uint8_t *)m_data;
+ delete [] buffer;
+ }
+ }
+}
+
+void
+TraceContext::Union (TraceContext const &o)
+{
+ if (o.m_data == 0)
+ {
+ return;
+ }
+ uint16_t currentUid;
+ uint16_t i = 0;
+ while (i < o.m_data->size)
+ {
+ currentUid = o.m_data->data[i];
+ uint8_t size = ElementRegistry::GetSize (currentUid);
+ uint8_t *selfBuffer = CheckPresent (currentUid);
+ uint8_t *otherBuffer = &(o.m_data->data[i+1]);
+ if (selfBuffer != 0)
+ {
+ if (memcmp (selfBuffer, otherBuffer, size) != 0)
+ {
+ NS_FATAL_ERROR ("You cannot add TraceContexts which "<<
+ "have different values stored in them.");
+ }
+ }
+ else
+ {
+ DoAdd (currentUid, otherBuffer);
+ }
+ i += 1 + size;
+ }
+}
+
+uint8_t *
+TraceContext::CheckPresent (uint8_t uid) const
+{
+ if (m_data == 0)
+ {
+ return false;
+ }
+ uint8_t currentUid;
+ uint16_t i = 0;
+ do {
+ currentUid = m_data->data[i];
+ uint8_t size = ElementRegistry::GetSize (currentUid);
+ if (currentUid == uid)
+ {
+ return &m_data->data[i+1];
+ }
+ i += 1 + size;
+ } while (i < m_data->size && currentUid != 0);
+ return 0;
+}
+
+
+bool
+TraceContext::DoAdd (uint8_t uid, uint8_t const *buffer)
+{
+ NS_ASSERT (uid != 0);
+ uint8_t size = ElementRegistry::GetSize (uid);
+ uint8_t *present = CheckPresent (uid);
+ if (present != 0) {
+ if (memcmp (present, buffer, size) == 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ if (m_data == 0)
+ {
+ uint16_t newSize = 1 + size;
+ uint16_t allocatedSize;
+ if (newSize > 4)
+ {
+ allocatedSize = sizeof (struct Data) + newSize - 4;
+ }
+ else
+ {
+ allocatedSize = sizeof (struct Data);
+ }
+ struct Data *data = (struct Data *) (new uint8_t [allocatedSize] ());
+ data->size = newSize;
+ data->count = 1;
+ data->data[0] = uid;
+ memcpy (data->data + 1, buffer, size);
+ m_data = data;
+ }
+ else
+ {
+ uint16_t newSize = m_data->size + 1 + size;
+ uint16_t allocatedSize;
+ if (newSize > 4)
+ {
+ allocatedSize = sizeof (struct Data) + newSize - 4;
+ }
+ else
+ {
+ allocatedSize = sizeof (struct Data);
+ }
+ struct Data *data = (struct Data *) (new uint8_t [allocatedSize] ());
+ data->size = newSize;
+ data->count = 1;
+ memcpy (data->data, m_data->data, m_data->size);
+ data->data[m_data->size] = uid;
+ memcpy (data->data + m_data->size + 1, buffer, size);
+ m_data->count--;
+ if (m_data->count == 0)
+ {
+ uint8_t *buffer = (uint8_t *)m_data;
+ delete [] buffer;
+ }
+ m_data = data;
+ }
+ return true;
+}
+bool
+TraceContext::DoGet (uint8_t uid, uint8_t *buffer) const
+{
+ if (m_data == 0)
+ {
+ return false;
+ }
+ uint8_t currentUid;
+ uint16_t i = 0;
+ do {
+ currentUid = m_data->data[i];
+ uint8_t size = ElementRegistry::GetSize (currentUid);
+ if (currentUid == uid)
+ {
+ memcpy (buffer, &m_data->data[i+1], size);
+ return true;
+ }
+ i += 1 + size;
+ } while (i < m_data->size && currentUid != 0);
+ return false;
+}
+
+void
+TraceContext::Print (std::ostream &os) const
+{
+ if (m_data == 0)
+ {
+ return;
+ }
+ uint8_t currentUid;
+ uint16_t i = 0;
+ do {
+ currentUid = m_data->data[i];
+ uint8_t size = ElementRegistry::GetSize (currentUid);
+ uint8_t *instance = &m_data->data[i+1];
+ ElementRegistry::Print (currentUid, instance, os);
+ i += 1 + size;
+ if (i < m_data->size && currentUid != 0)
+ {
+ os << " ";
+ }
+ else
+ {
+ break;
+ }
+ } while (true);
+}
+TraceContext::Iterator
+TraceContext::Begin (void) const
+{
+ if (m_data == 0)
+ {
+ return Iterator ();
+ }
+ return Iterator (m_data->data, m_data->size);
+}
+
+void
+TraceContext::PrintAvailable (std::ostream &os, std::string separator) const
+{
+ if (m_data == 0)
+ {
+ return;
+ }
+ uint8_t currentUid;
+ uint16_t i = 0;
+ do {
+ currentUid = m_data->data[i];
+ uint8_t size = ElementRegistry::GetSize (currentUid);
+ os << ElementRegistry::GetTypeName (currentUid);
+ i += 1 + size;
+ if (i < m_data->size && currentUid != 0)
+ {
+ os << separator;
+ }
+ else
+ {
+ break;
+ }
+ } while (true);
+}
+
+bool
+TraceContext::IsSimilar (const TraceContext &o) const
+{
+ if (m_data == 0 && o.m_data == 0)
+ {
+ return true;
+ }
+ if ((m_data != 0 && o.m_data == 0) ||
+ (m_data == 0 && o.m_data != 0))
+ {
+ return false;
+ }
+ uint8_t myCurrentUid;
+ uint16_t myI = 0;
+ uint8_t otherCurrentUid;
+ uint16_t otherI = 0;
+
+ myCurrentUid = m_data->data[myI];
+ otherCurrentUid = o.m_data->data[otherI];
+
+ while (myCurrentUid == otherCurrentUid &&
+ myCurrentUid != 0 &&
+ otherCurrentUid != 0 &&
+ myI < m_data->size &&
+ otherI < o.m_data->size)
+ {
+ uint8_t mySize = ElementRegistry::GetSize (myCurrentUid);
+ uint8_t otherSize = ElementRegistry::GetSize (otherCurrentUid);
+ myI += 1 + mySize;
+ otherI += 1 + otherSize;
+ myCurrentUid = m_data->data[myI];
+ otherCurrentUid = o.m_data->data[otherI];
+ }
+ if (myCurrentUid == 0 && otherCurrentUid == 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+std::ostream& operator<< (std::ostream& os, const TraceContext &context)
+{
+ context.Print (os);
+ return os;
+}
+
+}//namespace ns3
+
+#include "test.h"
+#include <sstream>
+
+namespace ns3 {
+
+template <int N>
+class Ctx : public TraceContextElement
+{
+public:
+ static uint16_t GetUid (void) {static uint16_t uid = AllocateUid<Ctx<N> > (GetTypeName ()); return uid;}
+ static std::string GetTypeName (void) {std::ostringstream oss; oss << "Ctx" << N; return oss.str ();}
+ Ctx () : m_v (0) {}
+ Ctx (int v) : m_v (v) {}
+ void Print (std::ostream &os) {os << N;}
+ int Get (void) const { return N;}
+private:
+ int m_v;
+};
+
+class TraceContextTest : public Test
+{
+public:
+ TraceContextTest ();
+ virtual bool RunTests (void);
+};
+
+TraceContextTest::TraceContextTest ()
+ : Test ("TraceContext")
+{}
+bool
+TraceContextTest::RunTests (void)
+{
+ bool ok = true;
+
+ TraceContext ctx;
+ Ctx<0> v0;
+ Ctx<0> v01 = Ctx<0> (1);
+ Ctx<1> v1;
+ Ctx<2> v2;
+ Ctx<3> v3;
+
+ if (ctx.SafeGet (v0))
+ {
+ ok = false;
+ }
+ ctx.AddElement (v0);
+ ctx.AddElement (v0);
+ if (ctx.SafeAdd (v01))
+ {
+ ok = false;
+ }
+ ctx.GetElement (v0);
+ ctx.AddElement (v1);
+ ctx.GetElement (v1);
+ ctx.GetElement (v0);
+ ctx.GetElement (v1);
+
+ TraceContext copy = ctx;
+ ctx.GetElement (v0);
+ ctx.GetElement (v1);
+ copy.GetElement (v0);
+ copy.GetElement (v1);
+ copy.AddElement (v2);
+ copy.GetElement (v0);
+ copy.GetElement (v1);
+ copy.GetElement (v2);
+ ctx.AddElement (v3);
+ ctx.GetElement (v0);
+ ctx.GetElement (v1);
+ ctx.GetElement (v3);
+
+ if (ctx.SafeGet (v2))
+ {
+ ok = false;
+ }
+ if (copy.SafeGet (v3))
+ {
+ ok = false;
+ }
+ ctx.Union (copy);
+ ctx.GetElement (v2);
+ if (copy.SafeGet (v3))
+ {
+ ok = false;
+ }
+ copy.Union (ctx);
+ copy.GetElement (v3);
+
+ return ok;
+}
+
+static TraceContextTest g_traceContextTest;
+
+
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-context.h Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,204 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef TRACE_CONTEXT_H
+#define TRACE_CONTEXT_H
+
+#include <stdint.h>
+#include <vector>
+#include "fatal-error.h"
+#include "trace-context-element.h"
+
+namespace ns3 {
+
+/**
+ * \brief Provide context to trace sources
+ * \ingroup tracing
+ *
+ * Instances of this class are used to hold context
+ * for each trace source. Each instance holds a list of
+ * TraceContextElement. Trace sinks can lookup these contexts
+ * from this list with the ns3::TraceContext::Get method.
+ * They can also ask the TraceContext for the list of
+ * TraceContextElements it contains with the PrintAvailable method.
+ *
+ * This class is implemented
+ * using Copy On Write which means that copying unmodified
+ * versions of this class is very cheap. However, modifying
+ * the content of this class through a call
+ * to ns3::TraceContext::AddElement or ns3::TraceContext::Union
+ * will trigger a costly memory reallocation if needed.
+ */
+class TraceContext
+{
+public:
+ TraceContext ();
+ TraceContext (TraceContext const &o);
+ TraceContext const & operator = (TraceContext const &o);
+ ~TraceContext ();
+
+ /**
+ * \param context add context to list of trace contexts.
+ *
+ * A copy of the input context is appended at the end of the list
+ * stored in this TraceContext.
+ */
+ template <typename T>
+ void AddElement (T const &context);
+
+ /**
+ * \param o the other context
+ *
+ * Perform the Union operation (in the sense of set theory) on the
+ * two input lists of elements. This method is used in the
+ * ns3::CallbackTraceSource class when multiple sinks are connected
+ * to a single source to ensure that the source does not need
+ * to store a single TraceContext instance per connected sink.
+ * Instead, all sinks share the same TraceContext.
+ */
+ void Union (TraceContext const &o);
+
+ /**
+ * \param context context to get from this list of trace contexts.
+ * \returns true if the requested trace context element was found
+ * in this TraceContext, false otherwise.
+ */
+ template <typename T>
+ bool GetElement (T &context) const;
+
+ /**
+ * \param os a c++ STL output stream
+ *
+ * Iterate over the list of TraceContextElement stored in this
+ * TraceContext and invoke each of their Print method.
+ */
+ void Print (std::ostream &os) const;
+ /**
+ * \param os a c++ STL output stream
+ * \param separator the separator inserted between each TraceContextElement typename.
+ *
+ * Print the typename of each TraceContextElement stored in this TraceContext.
+ */
+ void PrintAvailable (std::ostream &os, std::string separator) const;
+ class Iterator
+ {
+ public:
+ void Next (void);
+ bool IsLast (void) const;
+ std::string Get (void) const;
+ private:
+ friend class TraceContext;
+ Iterator ();
+ Iterator (uint8_t *buffer, uint16_t index);
+ uint8_t *m_buffer;
+ uint16_t m_size;
+ uint16_t m_current;
+ uint8_t m_uid;
+ };
+ Iterator Begin (void) const;
+ /**
+ * \param o another trace context
+ * \returns true if the input trace context contains exactly the same set of
+ * TraceContextElement instances, false otherwise.
+ *
+ * This method does not test for equality: the content of each matching
+ * TraceContextElement could be different. It merely checks that both
+ * trace contexts contain the same types of TraceContextElements.
+ */
+ bool IsSimilar (const TraceContext &o) const;
+private:
+ friend class TraceContextTest;
+ // used exclusively for testing code.
+ template <typename T>
+ bool SafeGet (T &context) const;
+ template <typename T>
+ bool SafeAdd (const T &context);
+
+ uint8_t *CheckPresent (uint8_t uid) const;
+ bool DoAdd (uint8_t uid, uint8_t const *buffer);
+ bool DoGet (uint8_t uid, uint8_t *buffer) const;
+
+ struct Data {
+ uint16_t count;
+ uint16_t size;
+ uint8_t data[4];
+ } * m_data;
+};
+
+std::ostream& operator<< (std::ostream& os, const TraceContext &context);
+
+}//namespace ns3
+
+namespace ns3 {
+
+template <typename T>
+void
+TraceContext::AddElement (T const &context)
+{
+ const TraceContextElement *parent;
+ // if the following assignment fails, it is because the input
+ // to this function is not a subclass of the TraceContextElement class.
+ parent = &context;
+ uint8_t *data = (uint8_t *) &context;
+ bool ok = DoAdd (T::GetUid (), data);
+ if (!ok)
+ {
+ NS_FATAL_ERROR ("Trying to add twice the same type with different values is invalid.");
+ }
+}
+template <typename T>
+bool
+TraceContext::GetElement (T &context) const
+{
+ TraceContextElement *parent;
+ // if the following assignment fails, it is because the input
+ // to this function is not a subclass of the TraceContextElement class.
+ parent = &context;
+ uint8_t *data = (uint8_t *) &context;
+ bool found = DoGet (T::GetUid (), data);
+ return found;
+}
+template <typename T>
+bool
+TraceContext::SafeGet (T &context) const
+{
+ TraceContextElement *parent;
+ // if the following assignment fails, it is because the input
+ // to this function is not a subclass of the TraceContextElement class.
+ parent = &context;
+ uint8_t *data = (uint8_t *) &context;
+ bool found = DoGet (T::GetUid (), data);
+ return found;
+}
+template <typename T>
+bool
+TraceContext::SafeAdd (const T &context)
+{
+ const TraceContextElement *parent;
+ // if the following assignment fails, it is because the input
+ // to this function is not a subclass of the TraceContextElement class.
+ parent = &context;
+ uint8_t *data = (uint8_t *) &context;
+ bool ok = DoAdd (T::GetUid (), data);
+ return ok;
+}
+}//namespace ns3
+
+#endif /* TRACE_CONTEXT_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-doc.cc Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,74 @@
+#include "trace-doc.h"
+
+namespace ns3 {
+
+TraceDoc::TraceDoc ()
+ : m_help ("empty help")
+{}
+
+TraceDoc::TraceDoc (std::string help)
+ : m_help (help)
+{}
+TraceDoc::TraceDoc (std::string help,
+ std::string arg0Type,
+ std::string arg0Help)
+ : m_help (help)
+{
+ m_argVector.push_back (std::make_pair (arg0Type, arg0Help));
+}
+TraceDoc::TraceDoc (std::string help,
+ std::string arg0Type,
+ std::string arg0Help,
+ std::string arg1Type,
+ std::string arg1Help)
+ : m_help (help)
+{
+ m_argVector.push_back (std::make_pair (arg0Type, arg0Help));
+ m_argVector.push_back (std::make_pair (arg1Type, arg1Help));
+}
+TraceDoc::TraceDoc (std::string help,
+ std::string arg0Type,
+ std::string arg0Help,
+ std::string arg1Type,
+ std::string arg1Help,
+ std::string arg2Type,
+ std::string arg2Help)
+ : m_help (help)
+{
+ m_argVector.push_back (std::make_pair (arg0Type, arg0Help));
+ m_argVector.push_back (std::make_pair (arg1Type, arg1Help));
+ m_argVector.push_back (std::make_pair (arg2Type, arg2Help));
+}
+TraceDoc::TraceDoc (std::string help,
+ std::string arg0Type,
+ std::string arg0Help,
+ std::string arg1Type,
+ std::string arg1Help,
+ std::string arg2Type,
+ std::string arg2Help,
+ std::string arg3Type,
+ std::string arg3Help)
+ : m_help (help)
+{
+ m_argVector.push_back (std::make_pair (arg0Type, arg0Help));
+ m_argVector.push_back (std::make_pair (arg1Type, arg1Help));
+ m_argVector.push_back (std::make_pair (arg2Type, arg2Help));
+ m_argVector.push_back (std::make_pair (arg3Type, arg3Help));
+}
+std::string
+TraceDoc::GetHelp (void) const
+{
+ return m_help;
+}
+TraceDoc::Iterator
+TraceDoc::ArgsBegin (void) const
+{
+ return m_argVector.begin ();
+}
+TraceDoc::Iterator
+TraceDoc::ArgsEnd (void) const
+{
+ return m_argVector.end ();
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-doc.h Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,103 @@
+#ifndef TRACE_DOC_H
+#define TRACE_DOC_H
+
+#include <vector>
+#include <string>
+
+namespace ns3 {
+
+/**
+ * \brief describe the signature of a trace source
+ */
+class TraceDoc
+{
+ typedef std::vector<std::pair<std::string,std::string> > ArgVector;
+public:
+ typedef ArgVector::const_iterator Iterator;
+ TraceDoc ();
+ /**
+ * \param help a description of the purpose of the trace source
+ */
+ TraceDoc (std::string help);
+ /**
+ * \param help a description of the purpose of the trace source
+ * \param arg1Type the fully-qualified typename of the first argument of the trace source
+ * \param arg1Help the purpose of the first argument of the trace source
+ */
+ TraceDoc (std::string help,
+ std::string arg1Type,
+ std::string arg1Help);
+ /**
+ * \param help a description of the purpose of the trace source
+ * \param arg1Type the fully-qualified typename of the first argument of the trace source
+ * \param arg1Help the purpose of the first argument of the trace source
+ * \param arg2Type the fully-qualified typename of the second argument of the trace source
+ * \param arg2Help the purpose of the second argument of the trace source
+ */
+ TraceDoc (std::string help,
+ std::string arg1Type,
+ std::string arg1Help,
+ std::string arg2Type,
+ std::string arg2Help);
+ /**
+ * \param help a description of the purpose of the trace source
+ * \param arg1Type the fully-qualified typename of the first argument of the trace source
+ * \param arg1Help the purpose of the first argument of the trace source
+ * \param arg2Type the fully-qualified typename of the second argument of the trace source
+ * \param arg2Help the purpose of the second argument of the trace source
+ * \param arg3Type the fully-qualified typename of the third argument of the trace source
+ * \param arg3Help the purpose of the third argument of the trace source
+ */
+ TraceDoc (std::string help,
+ std::string arg1Type,
+ std::string arg1Help,
+ std::string arg2Type,
+ std::string arg2Help,
+ std::string arg3Type,
+ std::string arg3Help);
+ /**
+ * \param help a description of the purpose of the trace source
+ * \param arg1Type the fully-qualified typename of the first argument of the trace source
+ * \param arg1Help the purpose of the first argument of the trace source
+ * \param arg2Type the fully-qualified typename of the second argument of the trace source
+ * \param arg2Help the purpose of the second argument of the trace source
+ * \param arg3Type the fully-qualified typename of the third argument of the trace source
+ * \param arg3Help the purpose of the third argument of the trace source
+ * \param arg4Type the fully-qualified typename of the fourth argument of the trace source
+ * \param arg4Help the purpose of the fourth argument of the trace source
+ */
+ TraceDoc (std::string help,
+ std::string arg1Type,
+ std::string arg1Help,
+ std::string arg2Type,
+ std::string arg2Help,
+ std::string arg3Type,
+ std::string arg3Help,
+ std::string arg4Type,
+ std::string arg4Help);
+ /**
+ * \returns the help string associated to this trace source
+ */
+ std::string GetHelp (void) const;
+ /**
+ * \returns an iterator which points to the first descriptor of the trace source.
+ *
+ * Each descriptor is a pair of strings. The first one describes the type of the argument
+ * while the second one describeds the purpose of the argument.
+ */
+ Iterator ArgsBegin (void) const;
+ /**
+ * \returns an iterator which points to the last descriptor of the trace source.
+ *
+ * Each descriptor is a pair of strings. The first one describes the type of the argument
+ * while the second one describeds the purpose of the argument.
+ */
+ Iterator ArgsEnd (void) const;
+private:
+ ArgVector m_argVector;
+ std::string m_help;
+};
+
+} // namespace ns3
+
+#endif /* TRACE_DOC_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-resolver.cc Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,107 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "trace-resolver.h"
+#include "debug.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("TraceResolver");
+
+namespace ns3 {
+
+TraceResolver::TraceResolver ()
+ : m_count (1)
+{}
+
+TraceResolver::~TraceResolver ()
+{}
+
+void
+TraceResolver::Ref (void)
+{
+ m_count++;
+}
+void
+TraceResolver::Unref (void)
+{
+ m_count--;
+ if (m_count == 0)
+ {
+ NS_DEBUG ("delete "<<this);
+ delete this;
+ }
+}
+
+std::string
+TraceResolver::GetElement (std::string path)
+{
+ std::string::size_type cur = 1;
+ // check that first char is "/"
+ std::string::size_type next = path.find ("/", cur);
+ std::string id = std::string (path, cur, next-1);
+ return id;
+}
+std::string
+TraceResolver::GetSubpath (std::string path)
+{
+ std::string::size_type cur = 1;
+ // check that first char is "/"
+ std::string::size_type next = path.find ("/", cur);
+ std::string subpath;
+ if (next != std::string::npos)
+ {
+ subpath = std::string (path, next, std::string::npos);
+ }
+ else
+ {
+ subpath = "";
+ }
+ return subpath;
+}
+
+void
+TraceResolver::SourceCollection::AddUnique (std::string path,
+ const TraceContext &context,
+ const TraceDoc &doc)
+{
+ for (SourceVector::const_iterator i = m_sources.begin (); i != m_sources.end (); i++)
+ {
+ if (i->path == path &&
+ context.IsSimilar (i->context))
+ {
+ return;
+ }
+ }
+ struct Source source;
+ source.path = path;
+ source.context = context;
+ source.doc = doc;
+ m_sources.push_back (source);
+}
+TraceResolver::SourceCollection::Iterator
+TraceResolver::SourceCollection::Begin (void) const
+{
+ return m_sources.begin ();
+}
+TraceResolver::SourceCollection::Iterator
+TraceResolver::SourceCollection::End (void) const
+{
+ return m_sources.end ();
+}
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-resolver.h Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,159 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef TRACE_RESOLVER_H
+#define TRACE_RESOLVER_H
+
+#include <string>
+#include <list>
+#include "trace-context.h"
+#include "trace-doc.h"
+
+namespace ns3 {
+
+class CallbackBase;
+
+/**
+ * \brief the base class which is used to recursively perform trace
+ * namespace resolution.
+ * \ingroup tracing
+ *
+ * Although users could conceivably implement their own trace resolver
+ * subclasses, doing so is complicated so, it is recommended to use
+ * the default implementation ns3::CompositeTraceResolver instead.
+ */
+class TraceResolver
+{
+public:
+
+ TraceResolver ();
+ virtual ~TraceResolver ();
+ void Ref (void);
+ void Unref (void);
+
+ /**
+ * \param path the namespace path to resolver
+ * \param cb the callback to connect to the matching namespace
+ * \param context the context in which to store the trace context
+ *
+ * First, extract the leading path element from the input path, and
+ * match this leading patch element against any terminal trace source
+ * contained in this trace resolver.
+ * Second, recursively resolve the rest of the path using other
+ * objects if there are any.
+ * If there is any TraceContextElement associated to one of the matching
+ * elements, it should be added to the input TraceContext.
+ */
+ virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context) = 0;
+ /**
+ * \param path the namespace path to resolver
+ * \param cb the callback to disconnect in the matching namespace
+ *
+ * This method should behave as Connect.
+ */
+ virtual void Disconnect (std::string path, CallbackBase const &cb) = 0;
+
+ /**
+ * \brief hold a list of trace sources
+ */
+ class SourceCollection
+ {
+ public:
+ /**
+ * \brief describe a single trace source
+ */
+ struct Source
+ {
+ /**
+ * The trace path associated to this trace source
+ */
+ std::string path;
+ /**
+ * The trace context associated to this trace source
+ */
+ TraceContext context;
+ /**
+ * Document the signature of this trace source
+ */
+ TraceDoc doc;
+ };
+ typedef std::vector<struct Source>::const_iterator Iterator;
+ void AddUnique (std::string path,
+ const TraceContext &context,
+ const TraceDoc &doc);
+
+ /**
+ * \returns an iterator which points to the first element of the set of
+ * trace sources collected in this SourceCollection object.
+ */
+ Iterator Begin (void) const;
+ /**
+ * \returns an iterator which points to the last element of the set of
+ * trace sources collected in this SourceCollection object.
+ */
+ Iterator End (void) const;
+ private:
+ typedef std::vector<struct Source> SourceVector;
+ SourceVector m_sources;
+ };
+ /**
+ * \param path the path to the current recursive level.
+ * \param context the trace context associated to the current recursive level
+ * \param collection the collection in which to gather every trace source found.
+ *
+ * This method is invoked recursively until all trace sources have been
+ * stored in the output SourceCollection argument.
+ */
+ virtual void CollectSources (std::string path, const TraceContext &context,
+ SourceCollection *collection) = 0;
+
+ /**
+ * \param os the output stream to which ascii output should be written.
+ * \param context the context associated to the current recursive level.
+ *
+ * This method is invoked recursively until each trace source has been
+ * connected to a trace sink which can output an ascii representation
+ * of each trace event on the output stream specified.
+ */
+ virtual void TraceAll (std::ostream &os, const TraceContext &context) = 0;
+protected:
+ /**
+ * \param path a namespace path
+ * \returns the initial element of the path.
+ *
+ * If the input path is "/foo/...", the return
+ * value is "foo".
+ */
+ std::string GetElement (std::string path);
+ /**
+ * \param path a namespace path
+ * \returns the subpath.
+ *
+ * If the input path is "/foo/bar/...", the return
+ * value is "/bar/...".
+ */
+ std::string GetSubpath (std::string path);
+private:
+ uint32_t m_count;
+};
+
+}//namespace ns3
+
+#endif /* TRACE_RESOLVER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-source.cc Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,31 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "trace-source.h"
+#include "trace-context.h"
+
+namespace ns3 {
+
+void
+TraceSource::AddCallback (CallbackBase const & callback)
+{
+ AddCallback (callback, TraceContext ());
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-source.h Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,61 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef TRACE_SOURCE_H
+#define TRACE_SOURCE_H
+
+#include <ostream>
+
+namespace ns3 {
+
+class CallbackBase;
+class TraceContext;
+
+/**
+ * \brief the base class for all trace sources
+ *
+ * Every trace source which wishes to be connectable and disconnectable with
+ * the TraceResolver system should derive from this base class and implement
+ * all three methods below.
+ */
+class TraceSource
+{
+public:
+ virtual ~TraceSource () {}
+ /**
+ * \param callback the callback to connect to this trace source
+ * \param context the context associated to the input callback which should be passed
+ * back to the user.
+ */
+ virtual void AddCallback (CallbackBase const & callback, TraceContext const & context) = 0;
+ /**
+ * \param callback the callback to connect to this trace source
+ */
+ void AddCallback (CallbackBase const & callback);
+ /**
+ * \param callback the callback to disconnect from this trace source
+ */
+ virtual void RemoveCallback (CallbackBase const & callback) = 0;
+ virtual void ConnectPrinter (std::ostream &os, TraceContext const &context) = 0;
+};
+
+} // namespace ns3
+
+#endif /* TRACE_SOURCE_H */
--- a/src/core/uid-manager.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/core/uid-manager.cc Tue Sep 11 14:52:15 2007 +0100
@@ -19,8 +19,8 @@
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "uid-manager.h"
-#include "ns3/fatal-error.h"
-#include "ns3/assert.h"
+#include "fatal-error.h"
+#include "assert.h"
namespace ns3 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/uv-trace-source.h Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,249 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef UV_TRACE_SOURCE_H
+#define UV_TRACE_SOURCE_H
+
+#include "callback-trace-source.h"
+#include "trace-source.h"
+#include <stdint.h>
+
+namespace ns3 {
+
+class UVTraceSourceBase : public TraceSource {
+public:
+ typedef CallbackTraceSource<uint64_t, uint64_t> ChangeNotifyCallback;
+
+ UVTraceSourceBase ()
+ : m_callback () {}
+ /* We don't want to copy the base callback. Only setCallback on
+ * a specific instance will do something to it. */
+ UVTraceSourceBase (UVTraceSourceBase const &o)
+ : m_callback () {}
+ UVTraceSourceBase &operator = (UVTraceSourceBase const &o) {
+ return *this;
+ }
+ ~UVTraceSourceBase () {}
+
+ virtual void AddCallback (CallbackBase const & callback, TraceContext const & context) {
+ m_callback.AddCallback (callback, context);
+ }
+ virtual void RemoveCallback (CallbackBase const & callback) {
+ m_callback.RemoveCallback (callback);
+ }
+ virtual void ConnectPrinter (std::ostream &os, const TraceContext &context) {
+ m_callback.ConnectPrinter (os, context);
+ }
+
+protected:
+ void Notify (uint64_t oldVal, uint64_t newVal) {
+ if (oldVal != newVal)
+ {
+ m_callback (oldVal, newVal);
+ }
+ }
+private:
+ ChangeNotifyCallback m_callback;
+};
+
+template <typename T>
+class SVTraceSource;
+
+
+/**
+ * \brief trace variables of type "unsigned integer"
+ * \ingroup tracing
+ *
+ * This template class implements a POD type: it
+ * behaves like any other variable of type "unsigned integer"
+ * except that it also reports any changes to its
+ * value with its internal callback.
+ *
+ * To instantiate a 32-bit unsigned variable (to store
+ * a TCP counter for example), you would create a variable of type
+ * ns3::UVTraceSource<uint32_t> :
+ \code
+ #include <stdint.h>
+ #include "uv-trace-source.h"
+
+ ns3::UVTraceSource<uint32_t> var;
+ \endcode
+ * and you would use it like any other variable of type uint32_t:
+ \code
+ var += 12;
+ var = 10;
+ \endcode
+ */
+template <typename T>
+class UVTraceSource : public UVTraceSourceBase {
+public:
+ UVTraceSource ()
+ : m_var ()
+ {}
+ UVTraceSource (T const &var)
+ : m_var (var)
+ {}
+
+ UVTraceSource &operator = (UVTraceSource const &o) {
+ Assign (o.Get ());
+ return *this;
+ }
+ template <typename TT>
+ UVTraceSource &operator = (UVTraceSource<TT> const &o) {
+ Assign (o.Get ());
+ return *this;
+ }
+ template <typename TT>
+ UVTraceSource &operator = (SVTraceSource<TT> const &o) {
+ Assign (o.Get ());
+ return *this;
+ }
+ UVTraceSource &operator++ () {
+ Assign (Get () + 1);
+ return *this;
+ }
+ UVTraceSource &operator-- () {
+ Assign (Get () - 1);
+ return *this;
+ }
+ UVTraceSource operator++ (int) {
+ UVTraceSource old (*this);
+ ++*this;
+ return old;
+ }
+ UVTraceSource operator-- (int) {
+ UVTraceSource old (*this);
+ --*this;
+ return old;
+ }
+ operator T () const {
+ return Get ();
+ }
+
+
+ void Assign (T var) {
+ Notify (m_var, var);
+ m_var = var;
+ }
+ T Get (void) const {
+ return m_var;
+ }
+
+private:
+ T m_var;
+};
+
+template <typename T>
+UVTraceSource<T> &operator += (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () + rhs.Get ());
+ return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator -= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () - rhs.Get ());
+ return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator *= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () * rhs.Get ());
+ return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator /= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () / rhs.Get ());
+ return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator <<= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () << rhs.Get ());
+ return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator >>= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () >> rhs.Get ());
+ return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator &= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () & rhs.Get ());
+ return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator |= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () | rhs.Get ());
+ return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator ^= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () ^ rhs.Get ());
+ return lhs;
+}
+
+
+template <typename T, typename U>
+UVTraceSource<T> &operator += (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () + rhs);
+ return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator -= (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () - rhs);
+ return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator *= (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () * rhs);
+ return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator /= (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () / rhs);
+ return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator <<= (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () << rhs);
+ return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator >>= (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () >> rhs);
+ return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator &= (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () & rhs);
+ return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator |= (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () | rhs);
+ return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator ^= (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () ^ rhs);
+ return lhs;
+}
+
+}; // namespace ns3
+
+#endif /* UV_TRACE_SOURCE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/variable-tracer-test.cc Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,272 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "uv-trace-source.h"
+#include "sv-trace-source.h"
+#include "trace-context.h"
+#include "test.h"
+#include "callback.h"
+
+
+namespace ns3 {
+
+class Foo {
+public:
+ void Notify (TraceContext const &contex, uint64_t oldVal, uint64_t newVal) {}
+};
+
+class VariableTracerTest: public Test {
+public:
+ VariableTracerTest ();
+ void RunUnsignedTests (void);
+ void RunSignedUnsignedTests (void);
+ virtual bool RunTests (void);
+};
+void
+VariableTracerTest::RunUnsignedTests (void)
+{
+ UVTraceSource<uint32_t> var, ovar, tmp;
+ uint32_t utmp;
+ Foo *foo = new Foo ();
+
+ var.AddCallback (MakeCallback (&Foo::Notify, foo), TraceContext ());
+
+ var = 10;
+ ovar = var;
+
+ if (var == ovar)
+ {
+ }
+ if (var != ovar)
+ {
+ }
+ if (var > ovar)
+ {
+ }
+ if (var >= ovar)
+ {
+ }
+ if (var < ovar)
+ {
+ }
+
+ if (var <= ovar)
+
+ if (var == 1)
+ {
+ }
+ if (var != 1)
+ {
+ }
+ if (var > 1)
+ {
+ }
+ if (var >= 1)
+ {
+ }
+ if (var < 1)
+ {
+ }
+ if (var <= 1)
+ {
+ }
+
+ if (1 == ovar)
+ {
+ }
+ if (1 != ovar)
+ {
+ }
+ if (1 > ovar)
+ {
+ }
+ if (1 >= ovar)
+ {
+ }
+ if (1 < ovar)
+ {
+ }
+ if (1 <= ovar)
+ {
+ }
+
+ var++;
+ ++var;
+ var--;
+ --var;
+
+ tmp = var + ovar;
+ tmp = var - ovar;
+ tmp = var / ovar;
+ tmp = var * ovar;
+ tmp = var << ovar;
+ tmp = var >> ovar;
+ tmp = var & ovar;
+ tmp = var | ovar;
+ tmp = var ^ ovar;
+
+ tmp = var + 1;
+ tmp = var - 1;
+ tmp = var / 1;
+ tmp = var * 1;
+ tmp = var << 1;
+ tmp = var >> 1;
+ tmp = var & 1;
+ tmp = var | 1;
+ tmp = var ^ 1;
+
+ tmp = 1 + ovar;
+ tmp = 1 - ovar;
+ tmp = 1 / ovar;
+ tmp = 1 * ovar;
+ tmp = 1 << ovar;
+ tmp = 1 >> ovar;
+ tmp = 1 & ovar;
+ tmp = 1 | ovar;
+ tmp = 1 ^ ovar;
+
+ tmp += var;
+ tmp -= var;
+ tmp /= var;
+ tmp *= var;
+ tmp <<= var;
+ tmp >>= var;
+ tmp &= var;
+ tmp |= var;
+ tmp ^= var;
+
+ tmp += 1;
+ tmp -= 1;
+ tmp /= 1;
+ tmp *= 1;
+ tmp <<= 1;
+ tmp >>= 1;
+ tmp &= 1;
+ tmp |= 1;
+ tmp ^= 1;
+
+
+ utmp = var + ovar;
+ utmp = var - ovar;
+ utmp = var / ovar;
+ utmp = var * ovar;
+ utmp = var << ovar;
+ utmp = var >> ovar;
+ utmp = var & ovar;
+ utmp = var | ovar;
+ utmp = var ^ ovar;
+
+ utmp = var + 1;
+ utmp = var - 1;
+ utmp = var / 1;
+ utmp = var * 1;
+ utmp = var << 1;
+ utmp = var >> 1;
+ utmp = var & 1;
+ utmp = var | 1;
+ utmp = var ^ 1;
+
+ utmp = 1 + ovar;
+ utmp = 1 - ovar;
+ utmp = 1 / ovar;
+ utmp = 1 * ovar;
+ utmp = 1 << ovar;
+ utmp = 1 >> ovar;
+ utmp = 1 & ovar;
+ utmp = 1 | ovar;
+ utmp = 1 ^ ovar;
+
+ utmp += var;
+ utmp -= var;
+ utmp /= var;
+ utmp *= var;
+ utmp <<= var;
+ utmp >>= var;
+ utmp &= var;
+ utmp |= var;
+ utmp ^= var;
+
+ utmp += 1;
+ utmp -= 1;
+ utmp /= 1;
+ utmp *= 1;
+ utmp <<= 1;
+ utmp >>= 1;
+ utmp &= 1;
+ utmp |= 1;
+ utmp ^= 1;
+
+ delete foo;
+}
+
+void
+VariableTracerTest::RunSignedUnsignedTests (void)
+{
+ unsigned short utmp = 10;
+ unsigned int uitmp = 7;
+ short stmp = 5;
+ utmp = stmp;
+ utmp += stmp;
+ uitmp = utmp;
+ utmp = uitmp;
+
+ UVTraceSource<unsigned short> uvar = 10;
+ UVTraceSource<unsigned int> uivar = 5;
+ SVTraceSource<short> svar = 5;
+ SVTraceSource<int> sivar = 5;
+ uvar = svar;
+ svar = uvar;
+ uvar += svar;
+ svar += uvar;
+
+ uvar = sivar;
+ sivar = uvar;
+ uvar += sivar;
+ sivar += uvar;
+
+ uivar = uvar;
+ uvar = uivar;
+ uivar += uvar;
+ uvar += uivar;
+
+ sivar = svar;
+ svar = sivar;
+ sivar += svar;
+ svar += sivar;
+}
+
+bool
+VariableTracerTest::RunTests (void)
+{
+ RunUnsignedTests ();
+ RunSignedUnsignedTests ();
+
+ return true;
+}
+
+VariableTracerTest::VariableTracerTest ()
+ : Test ("VariableTracer") {}
+
+static VariableTracerTest gVariableTracerTest;
+
+}; // namespace ns3
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/waf Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../waf "$@"
\ No newline at end of file
--- a/src/core/wscript Thu Sep 06 15:18:14 2007 +0100
+++ b/src/core/wscript Tue Sep 11 14:52:15 2007 +0100
@@ -42,6 +42,14 @@
'type-name.cc',
'component-manager.cc',
'random-variable-default-value.cc',
+ 'variable-tracer-test.cc',
+ 'trace-context.cc',
+ 'trace-context-element.cc',
+ 'trace-resolver.cc',
+ 'callback-trace-source.cc',
+ 'composite-trace-resolver.cc',
+ 'trace-doc.cc',
+ 'trace-source.cc',
]
if sys.platform == 'win32':
@@ -73,5 +81,16 @@
'component-manager.h',
'type-traits.h',
'random-variable-default-value.h',
+ 'trace-source.h',
+ 'uv-trace-source.h',
+ 'sv-trace-source.h',
+ 'fv-trace-source.h',
+ 'callback-trace-source.h',
+ 'trace-context.h',
+ 'trace-context-element.h',
+ 'trace-resolver.h',
+ 'composite-trace-resolver.h',
+ 'array-trace-resolver.h',
+ 'trace-doc.h',
]
--- a/src/devices/csma/csma-net-device.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/devices/csma/csma-net-device.cc Tue Sep 11 14:52:15 2007 +0100
@@ -59,6 +59,16 @@
static uint16_t uid = AllocateUid<CsmaTraceType> ("CsmaTraceType");
return uid;
}
+std::string
+CsmaTraceType::GetTypeName (void) const
+{
+ return "ns3::CsmaTraceType";
+}
+enum CsmaTraceType::Type
+CsmaTraceType::Get (void) const
+{
+ return m_type;
+}
CsmaNetDevice::CsmaNetDevice (Ptr<Node> node)
@@ -452,20 +462,23 @@
}
}
-TraceResolver *
-CsmaNetDevice::DoCreateTraceResolver (TraceContext const &context)
+Ptr<TraceResolver>
+CsmaNetDevice::GetTraceResolver (void) const
{
- CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
- resolver->Add ("queue",
- MakeCallback (&Queue::CreateTraceResolver,
- PeekPointer (m_queue)));
- resolver->Add ("rx",
- m_rxTrace,
- CsmaTraceType (CsmaTraceType::RX));
- resolver->Add ("drop",
- m_dropTrace,
- CsmaTraceType (CsmaTraceType::DROP));
- return resolver;
+ Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+ resolver->AddComposite ("queue", m_queue);
+ resolver->AddSource ("rx",
+ TraceDoc ("receive MAC packet",
+ "const Packet &", "packet received"),
+ m_rxTrace,
+ CsmaTraceType (CsmaTraceType::RX));
+ resolver->AddSource ("drop",
+ TraceDoc ("drop MAC packet",
+ "const Packet &", "packet dropped"),
+ m_dropTrace,
+ CsmaTraceType (CsmaTraceType::DROP));
+ resolver->SetParentResolver (NetDevice::GetTraceResolver ());
+ return resolver;
}
bool
--- a/src/devices/csma/csma-net-device.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/devices/csma/csma-net-device.h Tue Sep 11 14:52:15 2007 +0100
@@ -41,6 +41,9 @@
class Queue;
class CsmaChannel;
+/**
+ * \brief hold in a TraceContext the type of trace source from a CsmaNetDevice
+ */
class CsmaTraceType : public TraceContextElement
{
public:
@@ -52,6 +55,11 @@
CsmaTraceType ();
void Print (std::ostream &os) const;
static uint16_t GetUid (void);
+ std::string GetTypeName (void) const;
+ /**
+ * \returns the type of the trace source which generated an event.
+ */
+ enum Type Get (void) const;
private:
enum Type m_type;
};
@@ -207,6 +215,13 @@
virtual bool DoNeedsArp (void) const;
virtual void DoDispose (void);
/**
+ * Create a Trace Resolver for events in the net device.
+ * (NOT TESTED)
+ * @see class TraceResolver
+ */
+ virtual Ptr<TraceResolver> GetTraceResolver (void) const;
+
+ /**
* Get a copy of the attached Queue.
*
* This method is provided for any derived class that may need to get
@@ -321,12 +336,6 @@
* @see TransmitStart ()
*/
void TransmitReadyEvent (void);
- /**
- * Create a Trace Resolver for events in the net device.
- * (NOT TESTED)
- * @see class TraceResolver
- */
- virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
/**
* Aborts the transmission of the current packet
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/waf Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../../waf "$@"
--- a/src/devices/point-to-point/point-to-point-net-device.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/devices/point-to-point/point-to-point-net-device.cc Tue Sep 11 14:52:15 2007 +0100
@@ -53,6 +53,11 @@
static uint16_t uid = AllocateUid<PointToPointTraceType> ("PointToPointTraceType");
return uid;
}
+std::string
+PointToPointTraceType::GetTypeName (void) const
+{
+ return "ns3::PointToPointTraceType";
+}
PointToPointNetDevice::PointToPointNetDevice (Ptr<Node> node,
@@ -189,15 +194,17 @@
TransmitStart(p);
}
-TraceResolver* PointToPointNetDevice::DoCreateTraceResolver (
- TraceContext const &context)
+Ptr<TraceResolver>
+PointToPointNetDevice::GetTraceResolver (void) const
{
- CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
- resolver->Add ("queue",
- MakeCallback (&Queue::CreateTraceResolver, PeekPointer (m_queue)));
- resolver->Add ("rx",
- m_rxTrace,
- PointToPointTraceType ());
+ Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+ resolver->AddComposite ("queue", m_queue);
+ resolver->AddSource ("rx",
+ TraceDoc ("receive MAC packet",
+ "const Packet &", "packet received"),
+ m_rxTrace,
+ PointToPointTraceType ());
+ resolver->SetParentResolver (NetDevice::GetTraceResolver ());
return resolver;
}
--- a/src/devices/point-to-point/point-to-point-net-device.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/devices/point-to-point/point-to-point-net-device.h Tue Sep 11 14:52:15 2007 +0100
@@ -38,12 +38,16 @@
class Queue;
class PointToPointChannel;
+/**
+ * \brief hold in a TraceContext the type of trace source from a PointToPointNetDevice
+ */
class PointToPointTraceType : public TraceContextElement
{
public:
PointToPointTraceType ();
void Print (std::ostream &os) const;
static uint16_t GetUid (void);
+ std::string GetTypeName (void) const;
};
/**
@@ -152,6 +156,12 @@
*/
void Receive (Packet& p);
protected:
+ /**
+ * Create a Trace Resolver for events in the net device.
+ *
+ * @see class TraceResolver
+ */
+ virtual Ptr<TraceResolver> GetTraceResolver (void) const;
virtual void DoDispose (void);
/**
* Get a copy of the attached Queue.
@@ -237,12 +247,6 @@
*
*/
void TransmitComplete(void);
- /**
- * Create a Trace Resolver for events in the net device.
- *
- * @see class TraceResolver
- */
- virtual TraceResolver* DoCreateTraceResolver (TraceContext const &context);
virtual bool DoNeedsArp (void) const;
/**
* Enumeration of the states of the transmit machine of the net device.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/point-to-point/waf Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../../waf "$@"
--- a/src/internet-node/arp-cache.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/arp-cache.cc Tue Sep 11 14:52:15 2007 +0100
@@ -19,16 +19,16 @@
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "ns3/assert.h"
-
#include "ns3/packet.h"
#include "ns3/simulator.h"
#include "arp-cache.h"
#include "arp-header.h"
+#include "ipv4-interface.h"
namespace ns3 {
-ArpCache::ArpCache (Ptr<NetDevice> device, Ipv4Interface *interface)
+ArpCache::ArpCache (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface)
: m_device (device),
m_interface (interface),
m_aliveTimeout (Seconds (120)),
@@ -47,7 +47,7 @@
return m_device;
}
-Ipv4Interface *
+Ptr<Ipv4Interface>
ArpCache::GetInterface (void) const
{
return m_interface;
--- a/src/internet-node/arp-cache.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/arp-cache.h Tue Sep 11 14:52:15 2007 +0100
@@ -48,7 +48,7 @@
* \param device The hardware NetDevice associated with this ARP chache
* \param interface the Ipv4Interface associated with this ARP chache
*/
- ArpCache (Ptr<NetDevice> device, Ipv4Interface *interface);
+ ArpCache (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface);
~ArpCache ();
/**
* \return The NetDevice that this ARP cache is associated with
@@ -57,7 +57,7 @@
/**
* \return the Ipv4Interface that this ARP cache is associated with
*/
- Ipv4Interface *GetInterface (void) const;
+ Ptr<Ipv4Interface> GetInterface (void) const;
void SetAliveTimeout (Time aliveTimeout);
void SetDeadTimeout (Time deadTimeout);
@@ -152,7 +152,7 @@
typedef sgi::hash_map<Ipv4Address, ArpCache::Entry *, Ipv4AddressHash>::iterator CacheI;
Ptr<NetDevice> m_device;
- Ipv4Interface *m_interface;
+ Ptr<Ipv4Interface> m_interface;
Time m_aliveTimeout;
Time m_deadTimeout;
Time m_waitReplyTimeout;
--- a/src/internet-node/arp-ipv4-interface.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/arp-ipv4-interface.cc Tue Sep 11 14:52:15 2007 +0100
@@ -40,16 +40,15 @@
ArpIpv4Interface::~ArpIpv4Interface ()
{}
-TraceResolver *
-ArpIpv4Interface::DoCreateTraceResolver (TraceContext const &context)
+Ptr<TraceResolver>
+ArpIpv4Interface::GetTraceResolver (void) const
{
- CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
+ Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
if (GetDevice () != 0)
{
- resolver->Add ("netdevice",
- MakeCallback (&NetDevice::CreateTraceResolver, PeekPointer (GetDevice ())));
+ resolver->AddComposite ("netdevice", GetDevice ());
}
-
+ resolver->SetParentResolver (Ipv4Interface::GetTraceResolver ());
return resolver;
}
@@ -62,8 +61,9 @@
Ptr<ArpL3Protocol> arp = m_node->QueryInterface<ArpL3Protocol> (ArpL3Protocol::iid);
Address hardwareDestination;
bool found;
-
- if (dest.IsBroadcast ())
+
+ if (dest.IsBroadcast () ||
+ dest.IsSubnetDirectedBroadcast (GetNetworkMask ()) )
{
hardwareDestination = GetDevice ()->GetBroadcast ();
found = true;
--- a/src/internet-node/arp-ipv4-interface.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/arp-ipv4-interface.h Tue Sep 11 14:52:15 2007 +0100
@@ -42,9 +42,10 @@
ArpIpv4Interface (Ptr<Node> node, Ptr<NetDevice> device);
virtual ~ArpIpv4Interface ();
- private:
+protected:
+ virtual Ptr<TraceResolver> GetTraceResolver (void) const;
+private:
virtual void SendTo (Packet p, Ipv4Address dest);
- virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
Ptr<Node> m_node;
};
--- a/src/internet-node/arp-l3-protocol.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/arp-l3-protocol.cc Tue Sep 11 14:52:15 2007 +0100
@@ -20,7 +20,6 @@
*/
#include "ns3/packet.h"
#include "ns3/debug.h"
-#include "ns3/empty-trace-resolver.h"
#include "ns3/node.h"
#include "ns3/net-device.h"
@@ -58,12 +57,6 @@
Object::DoDispose ();
}
-TraceResolver *
-ArpL3Protocol::CreateTraceResolver (TraceContext const &context)
-{
- return new EmptyTraceResolver (context);
-}
-
ArpCache *
ArpL3Protocol::FindCache (Ptr<NetDevice> device)
{
@@ -75,7 +68,7 @@
}
}
Ptr<Ipv4L3Protocol> ipv4 = m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
- Ipv4Interface *interface = ipv4->FindInterfaceForDevice (device);
+ Ptr<Ipv4Interface> interface = ipv4->FindInterfaceForDevice (device);
ArpCache * cache = new ArpCache (device, interface);
NS_ASSERT (device->IsBroadcast ());
device->SetLinkChangeCallback (MakeCallback (&ArpCache::Flush, cache));
--- a/src/internet-node/arp-l3-protocol.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/arp-l3-protocol.h Tue Sep 11 14:52:15 2007 +0100
@@ -48,8 +48,6 @@
*/
ArpL3Protocol (Ptr<Node> node);
virtual ~ArpL3Protocol ();
-
- virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
/**
* \brief Recieve a packet
*/
--- a/src/internet-node/ascii-trace.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/ascii-trace.cc Tue Sep 11 14:52:15 2007 +0100
@@ -21,9 +21,9 @@
#include "ascii-trace.h"
#include "ns3/trace-context.h"
-#include "ns3/trace-root.h"
#include "ns3/simulator.h"
#include "ns3/node.h"
+#include "ns3/node-list.h"
#include "ns3/packet.h"
#include "ns3/queue.h"
@@ -41,19 +41,19 @@
AsciiTrace::TraceAllQueues (void)
{
Packet::EnableMetadata ();
- TraceRoot::Connect ("/nodes/*/devices/*/queue/enqueue",
+ NodeList::Connect ("/nodes/*/devices/*/queue/enqueue",
MakeCallback (&AsciiTrace::LogDevQueueEnqueue, this));
- TraceRoot::Connect ("/nodes/*/devices/*/queue/dequeue",
+ NodeList::Connect ("/nodes/*/devices/*/queue/dequeue",
MakeCallback (&AsciiTrace::LogDevQueueDequeue, this));
- TraceRoot::Connect ("/nodes/*/devices/*/queue/drop",
+ NodeList::Connect ("/nodes/*/devices/*/queue/drop",
MakeCallback (&AsciiTrace::LogDevQueueDrop, this));
}
void
AsciiTrace::TraceAllNetDeviceRx (void)
{
Packet::EnableMetadata ();
- TraceRoot::Connect ("/nodes/*/devices/*/rx",
- MakeCallback (&AsciiTrace::LogDevRx, this));
+ NodeList::Connect ("/nodes/*/devices/*/rx",
+ MakeCallback (&AsciiTrace::LogDevRx, this));
}
void
--- a/src/internet-node/internet-node.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/internet-node.cc Tue Sep 11 14:52:15 2007 +0100
@@ -74,13 +74,14 @@
Object::AddInterface (ipv4L4Demux);
}
-void
-InternetNode::DoFillTraceResolver (CompositeTraceResolver &resolver)
+Ptr<TraceResolver>
+InternetNode::GetTraceResolver () const
{
- Node::DoFillTraceResolver (resolver);
+ Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
Ptr<Ipv4L3Protocol> ipv4 = QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
- resolver.Add ("ipv4",
- MakeCallback (&Ipv4L3Protocol::CreateTraceResolver, PeekPointer (ipv4)));
+ resolver->AddComposite ("ipv4", ipv4);
+ resolver->SetParentResolver (Node::GetTraceResolver ());
+ return resolver;
}
void
--- a/src/internet-node/internet-node.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/internet-node.h Tue Sep 11 14:52:15 2007 +0100
@@ -42,8 +42,8 @@
protected:
virtual void DoDispose(void);
+ virtual Ptr<TraceResolver> GetTraceResolver (void) const;
private:
- virtual void DoFillTraceResolver (CompositeTraceResolver &resolver);
bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &p, uint16_t protocolNumber) const;
void Construct (void);
};
--- a/src/internet-node/ipv4-end-point.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/ipv4-end-point.cc Tue Sep 11 14:52:15 2007 +0100
@@ -42,6 +42,13 @@
{
return m_localAddr;
}
+
+void
+Ipv4EndPoint::SetLocalAddress (Ipv4Address address)
+{
+ m_localAddr = address;
+}
+
uint16_t
Ipv4EndPoint::GetLocalPort (void)
{
--- a/src/internet-node/ipv4-end-point.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/ipv4-end-point.h Tue Sep 11 14:52:15 2007 +0100
@@ -37,6 +37,7 @@
~Ipv4EndPoint ();
Ipv4Address GetLocalAddress (void);
+ void SetLocalAddress (Ipv4Address address);
uint16_t GetLocalPort (void);
Ipv4Address GetPeerAddress (void);
uint16_t GetPeerPort (void);
--- a/src/internet-node/ipv4-interface.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/ipv4-interface.cc Tue Sep 11 14:52:15 2007 +0100
@@ -22,6 +22,7 @@
#include "ipv4-interface.h"
#include "ns3/ipv4-address.h"
#include "ns3/net-device.h"
+#include "ns3/trace-resolver.h"
namespace ns3 {
@@ -39,18 +40,19 @@
Ipv4Interface::~Ipv4Interface ()
{}
+void
+Ipv4Interface::DoDispose (void)
+{
+ m_netdevice = 0;
+ Object::DoDispose ();
+}
+
Ptr<NetDevice>
Ipv4Interface::GetDevice (void) const
{
return m_netdevice;
}
-TraceResolver *
-Ipv4Interface::CreateTraceResolver (TraceContext const &context)
-{
- return DoCreateTraceResolver (context);
-}
-
void
Ipv4Interface::SetAddress (Ipv4Address a)
{
--- a/src/internet-node/ipv4-interface.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/ipv4-interface.h Tue Sep 11 14:52:15 2007 +0100
@@ -26,6 +26,7 @@
#include <list>
#include "ns3/ipv4-address.h"
#include "ns3/ptr.h"
+#include "ns3/object.h"
namespace ns3 {
@@ -60,9 +61,8 @@
*
* Subclasses must implement the two methods:
* - Ipv4Interface::SendTo
- * - Ipv4Interface::DoCreateTraceResolver
*/
-class Ipv4Interface
+class Ipv4Interface : public Object
{
public:
/**
@@ -74,17 +74,6 @@
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.
*/
@@ -150,10 +139,10 @@
*/
void Send(Packet p, Ipv4Address dest);
-
- private:
+protected:
+ virtual void DoDispose (void);
+private:
virtual void SendTo (Packet p, Ipv4Address dest) = 0;
- virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
Ptr<NetDevice> m_netdevice;
bool m_ifup;
Ipv4Address m_address;
--- a/src/internet-node/ipv4-l3-protocol.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/ipv4-l3-protocol.cc Tue Sep 11 14:52:15 2007 +0100
@@ -22,7 +22,6 @@
#include "ns3/packet.h"
#include "ns3/debug.h"
#include "ns3/composite-trace-resolver.h"
-#include "ns3/array-trace-resolver.h"
#include "ns3/callback.h"
#include "ns3/ipv4-address.h"
#include "ns3/ipv4-route.h"
@@ -88,30 +87,40 @@
static uint16_t uid = AllocateUid<Ipv4L3ProtocolTraceContextElement> ("Ipv4L3ProtocolTraceContextElement");
return uid;
}
+std::string
+Ipv4L3ProtocolTraceContextElement::GetTypeName (void) const
+{
+ return "ns3::Ipv4L3ProtocolTraceContextElement";
+}
-Ipv4l3ProtocolInterfaceIndex::Ipv4l3ProtocolInterfaceIndex ()
+Ipv4L3ProtocolInterfaceIndex::Ipv4L3ProtocolInterfaceIndex ()
: m_index (0)
{}
-Ipv4l3ProtocolInterfaceIndex::Ipv4l3ProtocolInterfaceIndex (uint32_t index)
+Ipv4L3ProtocolInterfaceIndex::Ipv4L3ProtocolInterfaceIndex (uint32_t index)
: m_index (index)
{}
uint32_t
-Ipv4l3ProtocolInterfaceIndex::Get (void) const
+Ipv4L3ProtocolInterfaceIndex::Get (void) const
{
return m_index;
}
void
-Ipv4l3ProtocolInterfaceIndex::Print (std::ostream &os) const
+Ipv4L3ProtocolInterfaceIndex::Print (std::ostream &os) const
{
os << "ipv4-interface=" << m_index;
}
uint16_t
-Ipv4l3ProtocolInterfaceIndex::GetUid (void)
+Ipv4L3ProtocolInterfaceIndex::GetUid (void)
{
- static uint16_t uid = AllocateUid<Ipv4l3ProtocolInterfaceIndex> ("Ipv4l3ProtocolInterfaceIndex");
+ static uint16_t uid = AllocateUid<Ipv4L3ProtocolInterfaceIndex> ("Ipv4L3ProtocolInterfaceIndex");
return uid;
}
+std::string
+Ipv4L3ProtocolInterfaceIndex::GetTypeName (void) const
+{
+ return "ns3::Ipv4L3ProtocolInterfaceIndex";
+}
Ipv4L3Protocol::Ipv4L3Protocol(Ptr<Node> node)
@@ -131,10 +140,6 @@
void
Ipv4L3Protocol::DoDispose (void)
{
- for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
- {
- delete (*i);
- }
m_interfaces.clear ();
m_node = 0;
m_staticRouting->Dispose ();
@@ -145,7 +150,7 @@
void
Ipv4L3Protocol::SetupLoopback (void)
{
- Ipv4LoopbackInterface * interface = new Ipv4LoopbackInterface (m_node);
+ Ptr<Ipv4LoopbackInterface> interface = Create<Ipv4LoopbackInterface> (m_node);
interface->SetAddress (Ipv4Address::GetLoopback ());
interface->SetNetworkMask (Ipv4Mask::GetLoopback ());
uint32_t index = AddIpv4Interface (interface);
@@ -153,26 +158,27 @@
interface->SetUp ();
}
-TraceResolver *
-Ipv4L3Protocol::CreateTraceResolver (TraceContext const &context)
+Ptr<TraceResolver>
+Ipv4L3Protocol::GetTraceResolver (void) const
{
- CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
- resolver->Add ("tx", m_txTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::TX));
- resolver->Add ("rx", m_rxTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::RX));
- resolver->Add ("drop", m_dropTrace, Ipv4L3ProtocolTraceContextElement (Ipv4L3ProtocolTraceContextElement::DROP));
- resolver->Add ("interfaces",
- MakeCallback (&Ipv4L3Protocol::InterfacesCreateTraceResolver, this));
- return resolver;
-}
-
-TraceResolver *
-Ipv4L3Protocol::InterfacesCreateTraceResolver (TraceContext const &context) const
-{
- ArrayTraceResolver<Ipv4Interface *, Ipv4l3ProtocolInterfaceIndex> *resolver =
- new ArrayTraceResolver<Ipv4Interface *,Ipv4l3ProtocolInterfaceIndex>
- (context,
- MakeCallback (&Ipv4L3Protocol::GetNInterfaces, this),
- MakeCallback (&Ipv4L3Protocol::GetInterface, this));
+ Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+ resolver->AddSource ("tx",
+ TraceDoc ("send ipv4 packet to outgoing interface",
+ "const Packet &", "packet sent",
+ "uint32_t", "index of output ipv4 interface"),
+ m_txTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::TX));
+ resolver->AddSource ("rx",
+ TraceDoc ("receive ipv4 packet from incoming interface",
+ "const Packet &", "packet received",
+ "uint32_t", "index of input ipv4 interface"),
+ m_rxTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::RX));
+ resolver->AddSource ("drop",
+ TraceDoc ("drop ipv4 packet",
+ "const Packet &", "packet dropped"),
+ m_dropTrace, Ipv4L3ProtocolTraceContextElement (Ipv4L3ProtocolTraceContextElement::DROP));
+ resolver->AddArray ("interfaces",
+ m_interfaces.begin (), m_interfaces.end (),
+ Ipv4L3ProtocolInterfaceIndex ());
return resolver;
}
@@ -265,18 +271,18 @@
uint32_t
Ipv4L3Protocol::AddInterface (Ptr<NetDevice> device)
{
- Ipv4Interface *interface = new ArpIpv4Interface (m_node, device);
+ Ptr<Ipv4Interface> interface = Create<ArpIpv4Interface> (m_node, device);
return AddIpv4Interface (interface);
}
uint32_t
-Ipv4L3Protocol::AddIpv4Interface (Ipv4Interface *interface)
+Ipv4L3Protocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
{
uint32_t index = m_nInterfaces;
m_interfaces.push_back (interface);
m_nInterfaces++;
return index;
}
-Ipv4Interface *
+Ptr<Ipv4Interface>
Ipv4L3Protocol::GetInterface (uint32_t index) const
{
uint32_t tmp = 0;
@@ -296,7 +302,7 @@
return m_nInterfaces;
}
-Ipv4Interface *
+Ptr<Ipv4Interface>
Ipv4L3Protocol::FindInterfaceForDevice (Ptr<const NetDevice> device)
{
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
@@ -364,7 +370,7 @@
for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
{
- Ipv4Interface *outInterface = *ifaceIter;
+ Ptr<Ipv4Interface> outInterface = *ifaceIter;
Packet packetCopy = packet;
NS_ASSERT (packetCopy.GetSize () <= outInterface->GetMtu ());
@@ -401,7 +407,7 @@
return;
}
packet.AddHeader (ipHeader);
- Ipv4Interface *outInterface = GetInterface (route.GetInterface ());
+ Ptr<Ipv4Interface> outInterface = GetInterface (route.GetInterface ());
NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ());
m_txTrace (packet, route.GetInterface ());
if (route.IsGateway ())
@@ -431,7 +437,7 @@
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
i != m_interfaces.end (); i++)
{
- Ipv4Interface *interface = *i;
+ Ptr<Ipv4Interface> interface = *i;
if (interface->GetDevice () == device)
{
if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ()))
@@ -481,43 +487,43 @@
void
Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address)
{
- Ipv4Interface *interface = GetInterface (i);
+ Ptr<Ipv4Interface> interface = GetInterface (i);
interface->SetAddress (address);
}
void
Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask)
{
- Ipv4Interface *interface = GetInterface (i);
+ Ptr<Ipv4Interface> interface = GetInterface (i);
interface->SetNetworkMask (mask);
}
Ipv4Mask
Ipv4L3Protocol::GetNetworkMask (uint32_t i) const
{
- Ipv4Interface *interface = GetInterface (i);
+ Ptr<Ipv4Interface> interface = GetInterface (i);
return interface->GetNetworkMask ();
}
Ipv4Address
Ipv4L3Protocol::GetAddress (uint32_t i) const
{
- Ipv4Interface *interface = GetInterface (i);
+ Ptr<Ipv4Interface> interface = GetInterface (i);
return interface->GetAddress ();
}
uint16_t
Ipv4L3Protocol::GetMtu (uint32_t i) const
{
- Ipv4Interface *interface = GetInterface (i);
+ Ptr<Ipv4Interface> interface = GetInterface (i);
return interface->GetMtu ();
}
bool
Ipv4L3Protocol::IsUp (uint32_t i) const
{
- Ipv4Interface *interface = GetInterface (i);
+ Ptr<Ipv4Interface> interface = GetInterface (i);
return interface->IsUp ();
}
void
Ipv4L3Protocol::SetUp (uint32_t i)
{
- Ipv4Interface *interface = GetInterface (i);
+ Ptr<Ipv4Interface> interface = GetInterface (i);
interface->SetUp ();
// If interface address and network mask have been set, add a route
@@ -533,7 +539,7 @@
void
Ipv4L3Protocol::SetDown (uint32_t ifaceIndex)
{
- Ipv4Interface *interface = GetInterface (ifaceIndex);
+ Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
interface->SetDown ();
// Remove all routes that are going through this interface
--- a/src/internet-node/ipv4-l3-protocol.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/ipv4-l3-protocol.h Tue Sep 11 14:52:15 2007 +0100
@@ -44,6 +44,9 @@
class TraceResolver;
class TraceContext;
+/**
+ * \brief hold in a TraceContext the type of trace source used by this Ipv4L3Protocol
+ */
class Ipv4L3ProtocolTraceContextElement : public TraceContextElement
{
public:
@@ -54,23 +57,40 @@
};
Ipv4L3ProtocolTraceContextElement ();
Ipv4L3ProtocolTraceContextElement (enum Type type);
+ /**
+ * \returns true if this is a tx event, false otherwise.
+ */
bool IsTx (void) const;
+ /**
+ * \returns true if this is a rx event, false otherwise.
+ */
bool IsRx (void) const;
+ /**
+ * \returns true if this is a drop event, false otherwise.
+ */
bool IsDrop (void) const;
void Print (std::ostream &os) const;
static uint16_t GetUid (void);
+ std::string GetTypeName (void) const;
private:
enum Type m_type;
};
-class Ipv4l3ProtocolInterfaceIndex : public TraceContextElement
+/**
+ * \brief hold in a TraceContext the index of an Ipv4Interface within the ipv4 stack of a Node
+ */
+class Ipv4L3ProtocolInterfaceIndex : public TraceContextElement
{
public:
- Ipv4l3ProtocolInterfaceIndex ();
- Ipv4l3ProtocolInterfaceIndex (uint32_t index);
+ Ipv4L3ProtocolInterfaceIndex ();
+ Ipv4L3ProtocolInterfaceIndex (uint32_t index);
+ /**
+ * \returns the index of the Ipv4Interface within a Node.
+ */
uint32_t Get (void) const;
void Print (std::ostream &os) const;
static uint16_t GetUid (void);
+ std::string GetTypeName (void) const;
private:
uint32_t m_index;
};
@@ -86,15 +106,6 @@
virtual ~Ipv4L3Protocol ();
/**
- * \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
@@ -109,7 +120,7 @@
* Try to find an Ipv4Interface whose NetDevice is equal to
* the input NetDevice.
*/
- Ipv4Interface *FindInterfaceForDevice (Ptr<const NetDevice> device);
+ Ptr<Ipv4Interface> FindInterfaceForDevice (Ptr<const NetDevice> device);
/**
* Lower layer calls this method after calling L3Demux::Lookup
@@ -159,7 +170,7 @@
void RemoveRoute (uint32_t i);
uint32_t AddInterface (Ptr<NetDevice> device);
- Ipv4Interface * GetInterface (uint32_t i) const;
+ Ptr<Ipv4Interface> GetInterface (uint32_t i) const;
uint32_t GetNInterfaces (void) const;
@@ -178,6 +189,7 @@
protected:
virtual void DoDispose (void);
+ virtual Ptr<TraceResolver> GetTraceResolver (void) const;
private:
@@ -187,11 +199,10 @@
Ipv4Header const &ipHeader);
bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device);
void ForwardUp (Packet p, Ipv4Header const&ip);
- uint32_t AddIpv4Interface (Ipv4Interface *interface);
+ uint32_t AddIpv4Interface (Ptr<Ipv4Interface> interface);
void SetupLoopback (void);
- TraceResolver *InterfacesCreateTraceResolver (TraceContext const &context) const;
- typedef std::list<Ipv4Interface*> Ipv4InterfaceList;
+ typedef std::list<Ptr<Ipv4Interface> > Ipv4InterfaceList;
typedef std::list< std::pair< int, Ptr<Ipv4RoutingProtocol> > > Ipv4RoutingProtocolList;
Ipv4InterfaceList m_interfaces;
--- a/src/internet-node/ipv4-l4-demux.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/ipv4-l4-demux.cc Tue Sep 11 14:52:15 2007 +0100
@@ -54,6 +54,11 @@
static uint16_t uid = AllocateUid<Ipv4L4ProtocolTraceContextElement> ("Ipv4L4ProtocolTraceContextElement");
return uid;
}
+std::string
+Ipv4L4ProtocolTraceContextElement::GetTypeName (void) const
+{
+ return "ns3::Ipv4L4ProtocolTraceContextElement";
+}
Ipv4L4Demux::Ipv4L4Demux (Ptr<Node> node)
@@ -78,21 +83,19 @@
Object::DoDispose ();
}
-TraceResolver *
-Ipv4L4Demux::CreateTraceResolver (TraceContext const &context)
+Ptr<TraceResolver>
+Ipv4L4Demux::GetTraceResolver (void) const
{
- CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
+ Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
for (L4List_t::const_iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
{
Ptr<Ipv4L4Protocol> protocol = *i;
- std::string protValue;
- std::ostringstream oss (protValue);
- oss << (*i)->GetProtocolNumber ();
+ std::ostringstream oss;
+ oss << (unsigned int) (*i)->GetProtocolNumber ();
Ipv4L4ProtocolTraceContextElement protocolNumber = (*i)->GetProtocolNumber ();
- resolver->Add (protValue,
- MakeCallback (&Ipv4L4Protocol::CreateTraceResolver, PeekPointer (protocol)),
- protocolNumber);
+ resolver->AddComposite (oss.str (), protocol, protocolNumber);
}
+ resolver->SetParentResolver (Object::GetTraceResolver ());
return resolver;
}
void
--- a/src/internet-node/ipv4-l4-demux.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/ipv4-l4-demux.h Tue Sep 11 14:52:15 2007 +0100
@@ -37,14 +37,21 @@
class TraceResolver;
class TraceContext;
+/**
+ * \brief hold in a TraceContext the protocol number of a L4 Protocol
+ */
class Ipv4L4ProtocolTraceContextElement : public TraceContextElement
{
public:
Ipv4L4ProtocolTraceContextElement ();
Ipv4L4ProtocolTraceContextElement (int protocolNumber);
+ /**
+ * \returns the protocol number as registered in the Ipv4L4Demux.
+ */
int Get (void) const;
void Print (std::ostream &os) const;
static uint16_t GetUid (void);
+ std::string GetTypeName (void) const;
private:
int m_protocolNumber;
};
@@ -60,14 +67,6 @@
virtual ~Ipv4L4Demux();
/**
- * \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);
- /**
* \param protocol a template for the protocol to add to this L4 Demux.
* \returns the L4Protocol effectively added.
*
@@ -95,8 +94,10 @@
* returned from the Ipv4L4Protocol::Insert method.
*/
void Remove (Ptr<Ipv4L4Protocol> protocol);
+protected:
+ Ptr<TraceResolver> GetTraceResolver (void) const;
+ virtual void DoDispose (void);
private:
- virtual void DoDispose (void);
typedef std::list<Ptr<Ipv4L4Protocol> > L4List_t;
L4List_t m_protocols;
Ptr<Node> m_node;
--- a/src/internet-node/ipv4-l4-protocol.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/ipv4-l4-protocol.h Tue Sep 11 14:52:15 2007 +0100
@@ -37,10 +37,6 @@
/**
* \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.
*/
@@ -59,8 +55,6 @@
*/
int GetVersion() const;
- virtual TraceResolver *CreateTraceResolver (TraceContext const &context) = 0;
-
/**
* \param p packet to forward up
* \param source source address of packet received
--- a/src/internet-node/ipv4-loopback-interface.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/ipv4-loopback-interface.cc Tue Sep 11 14:52:15 2007 +0100
@@ -19,7 +19,6 @@
* Authors:
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
*/
-#include "ns3/empty-trace-resolver.h"
#include "ns3/net-device.h"
#include "ns3/node.h"
#include "ns3/eui48-address.h"
@@ -34,13 +33,6 @@
{}
Ipv4LoopbackInterface::~Ipv4LoopbackInterface ()
{}
-
-TraceResolver *
-Ipv4LoopbackInterface::DoCreateTraceResolver (TraceContext const &context)
-{
- return new EmptyTraceResolver (context);
-}
-
void
Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest)
{
--- a/src/internet-node/ipv4-loopback-interface.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/ipv4-loopback-interface.h Tue Sep 11 14:52:15 2007 +0100
@@ -43,7 +43,6 @@
private:
virtual void SendTo (Packet p, Ipv4Address dest);
- virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
Ptr<Node> m_node;
};
--- a/src/internet-node/pcap-trace.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/pcap-trace.cc Tue Sep 11 14:52:15 2007 +0100
@@ -22,7 +22,7 @@
#include <sstream>
-#include "ns3/trace-root.h"
+#include "ns3/node-list.h"
#include "ns3/trace-context.h"
#include "ns3/callback.h"
#include "ns3/pcap-writer.h"
@@ -50,8 +50,8 @@
void
PcapTrace::TraceAllIp (void)
{
- TraceRoot::Connect ("/nodes/*/ipv4/(tx|rx)",
- MakeCallback (&PcapTrace::LogIp, this));
+ NodeList::Connect ("/nodes/*/ipv4/(tx|rx)",
+ MakeCallback (&PcapTrace::LogIp, this));
}
PcapWriter *
@@ -83,7 +83,7 @@
PcapTrace::LogIp (TraceContext const &context, Packet const &p, uint32_t interfaceIndex)
{
NodeListIndex nodeIndex;
- context.Get (nodeIndex);
+ context.GetElement (nodeIndex);
PcapWriter *writer = GetStream (nodeIndex.Get (), interfaceIndex);
writer->WritePacket (p);
}
--- a/src/internet-node/udp-l4-protocol.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/udp-l4-protocol.cc Tue Sep 11 14:52:15 2007 +0100
@@ -21,7 +21,6 @@
#include "ns3/assert.h"
#include "ns3/packet.h"
-#include "ns3/empty-trace-resolver.h"
#include "ns3/node.h"
#include "udp-l4-protocol.h"
@@ -45,12 +44,6 @@
UdpL4Protocol::~UdpL4Protocol ()
{}
-TraceResolver *
-UdpL4Protocol::CreateTraceResolver (TraceContext const &context)
-{
- return new EmptyTraceResolver (context);
-}
-
void
UdpL4Protocol::DoDispose (void)
{
--- a/src/internet-node/udp-l4-protocol.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/udp-l4-protocol.h Tue Sep 11 14:52:15 2007 +0100
@@ -49,7 +49,6 @@
UdpL4Protocol (Ptr<Node> node);
virtual ~UdpL4Protocol ();
- virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
/**
* \return A smart Socket pointer to a UdpSocket, allocated by this instance
* of the UDP protocol
--- a/src/internet-node/udp-socket.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/udp-socket.cc Tue Sep 11 14:52:15 2007 +0100
@@ -20,6 +20,8 @@
*/
#include "ns3/node.h"
#include "ns3/inet-socket-address.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/ipv4.h"
#include "udp-socket.h"
#include "udp-l4-protocol.h"
#include "ipv4-end-point.h"
@@ -147,13 +149,21 @@
int
UdpSocket::Connect(const Address & address)
{
+ Ipv4Route routeToDest;
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
m_defaultAddress = transport.GetIpv4 ();
m_defaultPort = transport.GetPort ();
NotifyConnectionSucceeded ();
m_connected = true;
+ if (GetIpv4RouteToDestination (m_node, routeToDest, m_defaultAddress) )
+ {
+ uint32_t localIfIndex = routeToDest.GetInterface ();
+ Ptr<Ipv4> ipv4 = m_node->QueryInterface<Ipv4> (Ipv4::iid);
+ m_endPoint->SetLocalAddress (ipv4->GetAddress(localIfIndex) );
+ }
return 0;
}
+
int
UdpSocket::Send (const Packet &p)
{
@@ -162,19 +172,51 @@
m_errno = ERROR_NOTCONN;
return -1;
}
+ return DoSend (p);
+}
+
+int
+UdpSocket::DoSend (const Packet &p)
+{
+ if (m_endPoint == 0)
+ {
+ if (Bind () == -1)
+ {
+ NS_ASSERT (m_endPoint == 0);
+ return -1;
+ }
+ NS_ASSERT (m_endPoint != 0);
+ }
+ if (m_shutdownSend)
+ {
+ m_errno = ERROR_SHUTDOWN;
+ return -1;
+ }
+
return DoSendTo (p, m_defaultAddress, m_defaultPort);
}
+
+
int
UdpSocket::DoSendTo (const Packet &p, const Address &address)
{
- InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
- Ipv4Address ipv4 = transport.GetIpv4 ();
- uint16_t port = transport.GetPort ();
- return DoSendTo (p, ipv4, port);
+ if (!m_connected)
+ {
+ InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
+ Ipv4Address ipv4 = transport.GetIpv4 ();
+ uint16_t port = transport.GetPort ();
+ return DoSendTo (p, ipv4, port);
+ }
+ else
+ {
+ // connected UDP socket must use default addresses
+ return DoSendTo (p, m_defaultAddress, m_defaultPort);
+ }
}
int
-UdpSocket::DoSendTo (const Packet &p, Ipv4Address ipv4, uint16_t port)
+UdpSocket::DoSendTo (const Packet &p, Ipv4Address dest, uint16_t port)
{
+ Ipv4Route routeToDest;
if (m_endPoint == 0)
{
if (Bind () == -1)
@@ -189,19 +231,42 @@
m_errno = ERROR_SHUTDOWN;
return -1;
}
- m_udp->Send (p, m_endPoint->GetLocalAddress (), ipv4,
+ //
+ // If dest is sent to the limited broadcast address (all ones),
+ // convert it to send a copy of the packet out of every interface
+ //
+ if (dest.IsBroadcast ())
+ {
+ Ptr<Ipv4> ipv4 = m_node->QueryInterface<Ipv4> (Ipv4::iid);
+ for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++ )
+ {
+ Ipv4Address addri = ipv4->GetAddress (i);
+ Ipv4Mask maski = ipv4->GetNetworkMask (i);
+ m_udp->Send (p, addri, addri.GetSubnetDirectedBroadcast (maski),
+ m_endPoint->GetLocalPort (), port);
+ NotifyDataSent (p.GetSize ());
+ }
+ }
+ else if (GetIpv4RouteToDestination (m_node, routeToDest, dest) )
+ {
+ uint32_t localIfIndex = routeToDest.GetInterface ();
+ Ptr<Ipv4> ipv4 = m_node->QueryInterface<Ipv4> (Ipv4::iid);
+ m_udp->Send (p, ipv4->GetAddress (localIfIndex), dest,
m_endPoint->GetLocalPort (), port);
- NotifyDataSent (p.GetSize ());
+ NotifyDataSent (p.GetSize ());
+ return 0;
+ }
+ else
+ {
+ m_errno = ERROR_NOROUTETOHOST;
+ return -1;
+ }
return 0;
}
+
int
UdpSocket::SendTo(const Address &address, const Packet &p)
{
- if (m_connected)
- {
- m_errno = ERROR_ISCONN;
- return -1;
- }
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
Ipv4Address ipv4 = transport.GetIpv4 ();
uint16_t port = transport.GetPort ();
--- a/src/internet-node/udp-socket.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/internet-node/udp-socket.h Tue Sep 11 14:52:15 2007 +0100
@@ -62,6 +62,7 @@
int FinishBind (void);
void ForwardUp (const Packet &p, Ipv4Address ipv4, uint16_t port);
void Destroy (void);
+ int DoSend (const Packet &p);
int DoSendTo (const Packet &p, const Address &daddr);
int DoSendTo (const Packet &p, Ipv4Address daddr, uint16_t dport);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/waf Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../waf "$@"
\ No newline at end of file
--- a/src/mobility/hierarchical-mobility-model.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/mobility/hierarchical-mobility-model.cc Tue Sep 11 14:52:15 2007 +0100
@@ -41,8 +41,8 @@
parentNotifier = Create<MobilityModelNotifier> ();
parent->AddInterface (parentNotifier);
}
- childNotifier->RegisterListener (MakeCallback (&HierarchicalMobilityModel::ChildChanged, this));
- parentNotifier->RegisterListener (MakeCallback (&HierarchicalMobilityModel::ParentChanged, this));
+ childNotifier->TraceConnect ("/course-changed", MakeCallback (&HierarchicalMobilityModel::ChildChanged, this));
+ parentNotifier->TraceConnect ("/course-changed", MakeCallback (&HierarchicalMobilityModel::ParentChanged, this));
}
Ptr<MobilityModel>
@@ -89,13 +89,13 @@
}
void
-HierarchicalMobilityModel::ParentChanged (Ptr<const MobilityModel> model)
+HierarchicalMobilityModel::ParentChanged (const TraceContext &context, Ptr<const MobilityModel> model)
{
MobilityModel::NotifyCourseChange ();
}
void
-HierarchicalMobilityModel::ChildChanged (Ptr<const MobilityModel> model)
+HierarchicalMobilityModel::ChildChanged (const TraceContext &context, Ptr<const MobilityModel> model)
{
MobilityModel::NotifyCourseChange ();
}
--- a/src/mobility/hierarchical-mobility-model.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/mobility/hierarchical-mobility-model.h Tue Sep 11 14:52:15 2007 +0100
@@ -63,8 +63,8 @@
virtual void DoSet (const Position &position);
virtual Speed DoGetSpeed (void) const;
- void ParentChanged (Ptr<const MobilityModel> model);
- void ChildChanged (Ptr<const MobilityModel> model);
+ void ParentChanged (const TraceContext &context, Ptr<const MobilityModel> model);
+ void ChildChanged (const TraceContext &context, Ptr<const MobilityModel> model);
Ptr<MobilityModel> m_child;
Ptr<MobilityModel> m_parent;
--- a/src/mobility/mobility-model-notifier.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/mobility/mobility-model-notifier.cc Tue Sep 11 14:52:15 2007 +0100
@@ -19,6 +19,8 @@
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "mobility-model-notifier.h"
+#include "ns3/composite-trace-resolver.h"
+#include "ns3/trace-doc.h"
namespace ns3 {
@@ -33,36 +35,23 @@
}
void
-MobilityModelNotifier::RegisterListener (Listener listener)
-{
- m_listeners.push_back (listener);
-}
-void
-MobilityModelNotifier::UnregisterListener (Listener callback)
-{
- for (std::list<Listener>::iterator i = m_listeners.begin ();
- i != m_listeners.end ();)
- {
- Listener listener = *i;
- if (listener.IsEqual (callback))
- {
- i = m_listeners.erase (i);
- }
- else
- {
- i++;
- }
- }
-}
-void
MobilityModelNotifier::Notify (Ptr<const MobilityModel> position) const
{
- for (std::list<Listener>::const_iterator i = m_listeners.begin ();
- i != m_listeners.end (); i++)
- {
- Listener listener = *i;
- listener (position);
- }
+ m_trace (position);
+}
+
+Ptr<TraceResolver>
+MobilityModelNotifier::GetTraceResolver (void) const
+{
+ Ptr<CompositeTraceResolver> resolver =
+ Create<CompositeTraceResolver> ();
+ resolver->AddSource ("course-change",
+ TraceDoc ("The value of the speed vector changed",
+ "Ptr<const MobilityModel>",
+ "the mobility model whose course changed"),
+ m_trace);
+ resolver->SetParentResolver (Object::GetTraceResolver ());
+ return resolver;
}
} // namespace ns3
--- a/src/mobility/mobility-model-notifier.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/mobility/mobility-model-notifier.h Tue Sep 11 14:52:15 2007 +0100
@@ -24,6 +24,7 @@
#include "ns3/object.h"
#include "ns3/component-manager.h"
#include "ns3/callback.h"
+#include "ns3/callback-trace-source.h"
#include "mobility-model.h"
namespace ns3 {
@@ -37,8 +38,6 @@
static const InterfaceId iid;
static const ClassId cid;
- typedef Callback<void,Ptr<const MobilityModel> > Listener;
-
/**
* Create a new position notifier
*/
@@ -48,23 +47,10 @@
* \param position the position which just changed.
*/
void Notify (Ptr<const MobilityModel> position) const;
-
- /**
- * \param listener listener to add
- *
- * The listener will be notified upon every position change.
- */
- void RegisterListener (Listener listener);
- /**
- * \param listener listener to remove
- *
- * The listener will not be notified anymore upon every
- * position change. It is not an error to try to unregister
- * a non-registered liste
- */
- void UnregisterListener (Listener listener);
+protected:
+ virtual Ptr<TraceResolver> GetTraceResolver (void) const;
private:
- std::list<Listener> m_listeners;
+ CallbackTraceSource<Ptr<const MobilityModel> > m_trace;
};
} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mobility/waf Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../waf "$@"
\ No newline at end of file
--- a/src/node/ipv4-address.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/node/ipv4-address.cc Tue Sep 11 14:52:15 2007 +0100
@@ -99,6 +99,11 @@
{
m_mask = value;
}
+uint32_t
+Ipv4Mask::GetInverse (void) const
+{
+ return ~m_mask;
+}
void
Ipv4Mask::Print (std::ostream &os) const
@@ -162,6 +167,18 @@
return Ipv4Address (GetHostOrder () & mask.GetHostOrder ());
}
+Ipv4Address
+Ipv4Address::GetSubnetDirectedBroadcast (Ipv4Mask const &mask) const
+{
+ return Ipv4Address (GetHostOrder () | mask.GetInverse ());
+}
+
+bool
+Ipv4Address::IsSubnetDirectedBroadcast (Ipv4Mask const &mask) const
+{
+ return ( (GetHostOrder () | mask.GetInverse ()) == GetHostOrder () );
+}
+
bool
Ipv4Address::IsBroadcast (void) const
{
--- a/src/node/ipv4-address.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/node/ipv4-address.h Tue Sep 11 14:52:15 2007 +0100
@@ -119,6 +119,16 @@
* \param mask a network mask
*/
Ipv4Address CombineMask (Ipv4Mask const &mask) const;
+ /**
+ * \brief Generate subnet-directed broadcast address corresponding to mask
+ *
+ * The subnet-directed broadcast address has the host bits set to all
+ * ones.
+ *
+ * \param mask a network mask
+ */
+ Ipv4Address GetSubnetDirectedBroadcast (Ipv4Mask const &mask) const;
+ bool IsSubnetDirectedBroadcast (Ipv4Mask const &mask) const;
static bool IsMatchingType (const Address &address);
operator Address ();
@@ -151,6 +161,10 @@
*/
uint32_t GetHostOrder (void) const;
void SetHostOrder (uint32_t value);
+ /**
+ * \brief Return the inverse mask in host order.
+ */
+ uint32_t GetInverse (void) const;
void Print (std::ostream &os) const;
--- a/src/node/ipv4.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/node/ipv4.cc Tue Sep 11 14:52:15 2007 +0100
@@ -18,6 +18,9 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
+
+#include "ns3/assert.h"
+#include "ns3/node.h"
#include "ipv4.h"
namespace ns3 {
@@ -32,4 +35,53 @@
Ipv4::~Ipv4 ()
{}
+uint32_t
+GetIfIndexByIpv4Address (Ptr<Node> node, Ipv4Address a, Ipv4Mask amask)
+{
+ Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
+ NS_ASSERT_MSG (ipv4, "GetIfIndexByIpv4Address: No Ipv4 interface");
+ for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++)
+ {
+ if (ipv4->GetAddress (i).CombineMask(amask) == a.CombineMask(amask) )
+ {
+ return i;
+ }
+ }
+ // Mapping not found
+ NS_ASSERT_MSG (false, "GetIfIndexByIpv4Address failed");
+ return 0;
+}
+
+bool
+GetIpv4RouteToDestination (Ptr<Node> node, Ipv4Route& route,
+ Ipv4Address a, Ipv4Mask amask)
+{
+ Ipv4Route tempRoute;
+ Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
+ NS_ASSERT_MSG (ipv4, "GetIpv4RouteToDestination: No Ipv4 interface");
+ for (uint32_t i = 0; i < ipv4->GetNRoutes (); i++)
+ {
+ tempRoute = ipv4->GetRoute (i);
+ // Host route found
+ if ( tempRoute.IsNetwork () == false && tempRoute.GetDest () == a )
+ {
+ route = tempRoute;
+ return true;
+ }
+ else if ( tempRoute.IsNetwork () &&
+ tempRoute.GetDestNetwork () == a.CombineMask(amask) )
+ {
+ route = tempRoute;
+ return true;
+ }
+ else if ( tempRoute.IsDefault () )
+ {
+ route = tempRoute;
+ return true;
+ }
+ }
+ return false;
+}
+
+
} // namespace ns3
--- a/src/node/ipv4.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/node/ipv4.h Tue Sep 11 14:52:15 2007 +0100
@@ -29,6 +29,7 @@
namespace ns3 {
+class Node;
class NetDevice;
class Packet;
class Ipv4Route;
@@ -273,6 +274,19 @@
};
+/**
+ * Convenience functions (Doxygen still needed)
+ *
+ * Return the ifIndex corresponding to the Ipv4Address provided.
+ */
+uint32_t GetIfIndexByIpv4Address (Ptr<Node> node,
+ Ipv4Address a,
+ Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
+
+bool GetIpv4RouteToDestination (Ptr<Node> node, Ipv4Route& route,
+ Ipv4Address a,
+ Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
+
} // namespace ns3
#endif /* IPV4_H */
--- a/src/node/net-device.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/node/net-device.cc Tue Sep 11 14:52:15 2007 +0100
@@ -23,6 +23,7 @@
#include "ns3/assert.h"
#include "ns3/object.h"
#include "ns3/debug.h"
+#include "ns3/trace-resolver.h"
#include "channel.h"
@@ -183,12 +184,6 @@
}
}
-TraceResolver *
-NetDevice::CreateTraceResolver (TraceContext const &context)
-{
- return DoCreateTraceResolver (context);
-}
-
Ptr<Channel>
NetDevice::GetChannel (void) const
{
--- a/src/node/net-device.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/node/net-device.h Tue Sep 11 14:52:15 2007 +0100
@@ -62,14 +62,6 @@
static const InterfaceId iid;
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
@@ -283,15 +275,6 @@
*/
virtual bool DoNeedsArp (void) const = 0;
/**
- * \param context the trace context to associated to the
- * trace resolver.
- * \returns a trace resolver associated to the input context.
- * the caller takes ownership of the pointer returned.
- *
- * Subclasses must implement this method.
- */
- virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
- /**
* \returns the channel associated to this NetDevice.
*
* Subclasses must implement this method.
--- a/src/node/node-list.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/node/node-list.cc Tue Sep 11 14:52:15 2007 +0100
@@ -20,24 +20,12 @@
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
*/
-#include "ns3/array-trace-resolver.h"
-#include "ns3/trace-root.h"
+#include "ns3/composite-trace-resolver.h"
#include "ns3/simulator.h"
#include "ns3/simulation-singleton.h"
#include "node-list.h"
#include "node.h"
-namespace {
-static class Initialization
-{
-public:
- Initialization ()
- {
- ns3::TraceRoot::Register ("nodes", ns3::MakeCallback (&ns3::NodeList::CreateTraceResolver));
- }
-} g_initialization;
-}
-
namespace ns3 {
NodeListIndex::NodeListIndex ()
@@ -62,6 +50,11 @@
{
return m_index;
}
+std::string
+NodeListIndex::GetTypeName (void) const
+{
+ return "ns3::NodeListIndex";
+}
/**
@@ -74,9 +67,9 @@
~NodeListPriv ();
uint32_t Add (Ptr<Node> node);
- NodeList::Iterator Begin (void);
- NodeList::Iterator End (void);
- TraceResolver *CreateTraceResolver (TraceContext const &context);
+ NodeList::Iterator Begin (void) const;
+ NodeList::Iterator End (void) const;
+ Ptr<TraceResolver> GetTraceResolver (void) const;
Ptr<Node> GetNode (uint32_t n);
uint32_t GetNNodes (void);
@@ -108,12 +101,12 @@
}
NodeList::Iterator
-NodeListPriv::Begin (void)
+NodeListPriv::Begin (void) const
{
return m_nodes.begin ();
}
NodeList::Iterator
-NodeListPriv::End (void)
+NodeListPriv::End (void) const
{
return m_nodes.end ();
}
@@ -130,14 +123,11 @@
}
-TraceResolver *
-NodeListPriv::CreateTraceResolver (TraceContext const &context)
+Ptr<TraceResolver>
+NodeListPriv::GetTraceResolver (void) const
{
- ArrayTraceResolver<Ptr<Node>, NodeListIndex> *resolver =
- new ArrayTraceResolver<Ptr<Node>, NodeListIndex>
- (context,
- MakeCallback (&NodeListPriv::GetNNodes, this),
- MakeCallback (&NodeListPriv::GetNode, this));
+ Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+ resolver->AddArray ("nodes", Begin (), End (), NodeListIndex ());
return resolver;
}
@@ -165,17 +155,30 @@
{
return SimulationSingleton<NodeListPriv>::Get ()->End ();
}
-TraceResolver *
-NodeList::CreateTraceResolver (TraceContext const &context)
-{
- return SimulationSingleton<NodeListPriv>::Get ()->CreateTraceResolver (context);
-}
Ptr<Node>
NodeList::GetNode (uint32_t n)
{
return SimulationSingleton<NodeListPriv>::Get ()->GetNode (n);
}
-
-
+void
+NodeList::Connect (std::string name, const CallbackBase &cb)
+{
+ SimulationSingleton<NodeListPriv>::Get ()->GetTraceResolver ()->Connect (name, cb, TraceContext ());
+}
+void
+NodeList::Disconnect (std::string name, const CallbackBase &cb)
+{
+ SimulationSingleton<NodeListPriv>::Get ()->GetTraceResolver ()->Disconnect (name, cb);
+}
+void
+NodeList::TraceAll (std::ostream &os)
+{
+ SimulationSingleton<NodeListPriv>::Get ()->GetTraceResolver ()->TraceAll (os, TraceContext ());
+}
+Ptr<TraceResolver>
+NodeList::GetTraceResolver (void)
+{
+ return SimulationSingleton<NodeListPriv>::Get ()->GetTraceResolver ();
+}
}//namespace ns3
--- a/src/node/node-list.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/node/node-list.h Tue Sep 11 14:52:15 2007 +0100
@@ -29,9 +29,12 @@
namespace ns3 {
class Node;
+class CallbackBase;
class TraceResolver;
-class TraceContext;
+/**
+ * \brief hold in a TraceContext the index of a node within a NodeList.
+ */
class NodeListIndex : public TraceContextElement
{
public:
@@ -39,7 +42,11 @@
NodeListIndex (uint32_t index);
void Print (std::ostream &os);
static uint16_t GetUid (void);
+ /**
+ * \returns the index of the node within the NodeList
+ */
uint32_t Get (void) const;
+ std::string GetTypeName (void) const;
private:
uint32_t m_index;
};
@@ -53,7 +60,7 @@
class NodeList
{
public:
- typedef std::vector< Ptr<Node> >::iterator Iterator;
+ typedef std::vector< Ptr<Node> >::const_iterator Iterator;
/**
* \param node node to add
@@ -74,18 +81,49 @@
*/
static Iterator End (void);
/**
- * \param context trace context to use for trace resolver
- * to create.
- * \returns the requested trace resolver. The caller
- * takes ownership of the returned pointer.
- */
- static TraceResolver *CreateTraceResolver (TraceContext const &context);
-
- /**
* \param n index of requested node.
* \returns the Node associated to index n.
*/
static Ptr<Node> GetNode (uint32_t n);
+ /**
+ * \param name namespace regexp to match
+ * \param cb callback to connect
+ *
+ * Connect input callback to all trace sources which match
+ * the input namespace regexp.
+ * A tutorial which explains how to use this method can be
+ * found in the \ref tracing section.
+ */
+ static void Connect (std::string name, const CallbackBase &cb);
+ /**
+ * \param name namespace regexp to match
+ * \param cb callback to connect
+ *
+ * Disconnect input callback from all trace sources which match
+ * the input namespace regexp.
+ */
+ static void Disconnect (std::string name, const CallbackBase &cb);
+ /**
+ * \param os the output stream on which the content of each trace event should be
+ * dumped in ascii format.
+ *
+ * Enable _every_ trace source accessible from the NodeList and write to the
+ * output stream an ascii representation of each trace event.
+ * This method is very useful to get quick-and-dirty trace output from a
+ * simulation.
+ * More fancy tracing output could be generated with the ns3::NodeList::Connect
+ * method as explained in the \ref tracing section.
+ */
+ static void TraceAll (std::ostream &os);
+ /**
+ * \returns the trace resolver used by the ns3::NodeList::Connect,
+ * ns3::NodeList::Disconnect, and, ns3::NodeList::TraceAll methods.
+ *
+ * Using this method directly is not really recommended. Instead, users
+ * should use one of the three methods ns3::NodeList::Connect,
+ * ns3::NodeList::Disconnect, or, ns3::NodeList::TraceAll methods.
+ */
+ static Ptr<TraceResolver> GetTraceResolver (void);
};
}//namespace ns3
--- a/src/node/node.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/node/node.cc Tue Sep 11 14:52:15 2007 +0100
@@ -25,7 +25,6 @@
#include "packet-socket-factory.h"
#include "ns3/simulator.h"
#include "ns3/composite-trace-resolver.h"
-#include "ns3/array-trace-resolver.h"
namespace ns3{
@@ -53,6 +52,11 @@
static uint16_t uid = AllocateUid<NodeNetDeviceIndex> ("NodeNetDeviceIndex");
return uid;
}
+std::string
+NodeNetDeviceIndex::GetTypeName (void) const
+{
+ return "ns3::NodeNetDeviceIndex";
+}
@@ -82,11 +86,12 @@
Node::~Node ()
{}
-TraceResolver *
-Node::CreateTraceResolver (TraceContext const &context)
+Ptr<TraceResolver>
+Node::GetTraceResolver (void) const
{
- CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
- DoFillTraceResolver (*resolver);
+ Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+ resolver->AddArray ("devices", m_devices.begin (), m_devices.end (), NodeNetDeviceIndex ());
+ resolver->SetParentResolver (Object::GetTraceResolver ());
return resolver;
}
@@ -141,25 +146,6 @@
return m_applications.size ();
}
-TraceResolver *
-Node::CreateDevicesTraceResolver (const TraceContext &context)
-{
- ArrayTraceResolver<Ptr<NetDevice>,NodeNetDeviceIndex> *resolver =
- new ArrayTraceResolver<Ptr<NetDevice>,NodeNetDeviceIndex>
- (context,
- MakeCallback (&Node::GetNDevices, this),
- MakeCallback (&Node::GetDevice, this));
-
- return resolver;
-}
-
-void
-Node::DoFillTraceResolver (CompositeTraceResolver &resolver)
-{
- resolver.Add ("devices",
- MakeCallback (&Node::CreateDevicesTraceResolver, this));
-}
-
void
Node::DoDispose()
{
--- a/src/node/node.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/node/node.h Tue Sep 11 14:52:15 2007 +0100
@@ -37,13 +37,20 @@
class Address;
class CompositeTraceResolver;
+/**
+ * \brief hold in a TraceContext the index of a NetDevice within a Node
+ */
class NodeNetDeviceIndex : public TraceContextElement
{
public:
NodeNetDeviceIndex ();
NodeNetDeviceIndex (uint32_t index);
+ /**
+ * \returns the index of the NetDevice within its container Node.
+ */
uint32_t Get (void) const;
void Print (std::ostream &os) const;
+ std::string GetTypeName (void) const;
static uint16_t GetUid (void);
private:
uint32_t m_index;
@@ -85,17 +92,6 @@
virtual ~Node();
/**
- * \param context the trace context for the TraceResolver to create
- * \returns a newly-created TraceResolver. The caller takes
- * ownership of the returned pointer.
- *
- * Request the Node to create a trace resolver. This method
- * could be used directly by a user who needs access to very low-level
- * trace configuration.
- */
- TraceResolver *CreateTraceResolver (TraceContext const &context);
-
- /**
* \returns the unique id of this node.
*
* This unique id happens to be also the index of the Node into
@@ -183,23 +179,15 @@
void UnregisterProtocolHandler (ProtocolHandler handler);
protected:
+ virtual Ptr<TraceResolver> GetTraceResolver (void) const;
/**
* The dispose method. Subclasses must override this method
* and must chain up to it by calling Node::DoDispose at the
* end of their own DoDispose method.
*/
virtual void DoDispose (void);
- /**
- * \param resolver the resolver to store trace sources in.
- *
- * If a subclass wants to add new traces to a Node, it needs
- * to override this method and record the new trace sources
- * in the input resolver. Subclasses also _must_ chain up to
- * their parent's DoFillTraceResolver method prior
- * to recording they own trace sources.
- */
- virtual void DoFillTraceResolver (CompositeTraceResolver &resolver);
private:
+
/**
* \param device the device added to this Node.
*
@@ -213,7 +201,6 @@
bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &packet,
uint16_t protocol, const Address &from);
void Construct (void);
- TraceResolver *CreateDevicesTraceResolver (const TraceContext &context);
struct ProtocolHandlerEntry {
ProtocolHandler handler;
--- a/src/node/packet-socket-factory.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/node/packet-socket-factory.cc Tue Sep 11 14:52:15 2007 +0100
@@ -20,6 +20,7 @@
*/
#include "packet-socket-factory.h"
#include "node.h"
+#include "packet-socket.h"
namespace ns3 {
--- a/src/node/packet-socket-factory.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/node/packet-socket-factory.h Tue Sep 11 14:52:15 2007 +0100
@@ -22,7 +22,6 @@
#define PACKET_SOCKET_FACTORY_H
#include "socket-factory.h"
-#include "packet-socket.h"
namespace ns3 {
--- a/src/node/queue.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/node/queue.cc Tue Sep 11 14:52:15 2007 +0100
@@ -32,6 +32,11 @@
Queue::iid, "DropTailQueue");
+std::string
+QueueTraceType::GetTypeName (void) const
+{
+ return "ns3::QueueTraceType";
+}
uint16_t
QueueTraceType::GetUid (void)
{
@@ -94,13 +99,23 @@
NS_DEBUG("Queue::~Queue ()");
}
-TraceResolver *
-Queue::CreateTraceResolver (TraceContext const &context)
+Ptr<TraceResolver>
+Queue::GetTraceResolver (void) const
{
- CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
- resolver->Add ("enqueue", m_traceEnqueue, QueueTraceType (QueueTraceType::ENQUEUE));
- resolver->Add ("dequeue", m_traceDequeue, QueueTraceType (QueueTraceType::DEQUEUE));
- resolver->Add ("drop", m_traceDrop, QueueTraceType (QueueTraceType::DROP));
+ Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+ resolver->AddSource ("enqueue",
+ TraceDoc ("store packet in queue",
+ "const Packet &", "packet queued"),
+ m_traceEnqueue, QueueTraceType (QueueTraceType::ENQUEUE));
+ resolver->AddSource ("dequeue",
+ TraceDoc ("remove packet from queue",
+ "const Packet &", "packet dequeued"),
+ m_traceDequeue, QueueTraceType (QueueTraceType::DEQUEUE));
+ resolver->AddSource ("drop",
+ TraceDoc ("drop packet from queue",
+ "const Packet &", "packet dropped"),
+ m_traceDrop, QueueTraceType (QueueTraceType::DROP));
+ resolver->SetParentResolver (Object::GetTraceResolver ());
return resolver;
}
--- a/src/node/queue.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/node/queue.h Tue Sep 11 14:52:15 2007 +0100
@@ -37,6 +37,9 @@
class StringEnumDefaultValue;
+/**
+ * \brief hold in a TraceContext the type of a trace source
+ */
class QueueTraceType : public TraceContextElement
{
public:
@@ -48,10 +51,20 @@
static uint16_t GetUid (void);
QueueTraceType ();
QueueTraceType (enum Type type);
+ /**
+ * \returns true if this is an enqueue event, false otherwise.
+ */
bool IsEnqueue (void) const;
+ /**
+ * \returns true if this is a dequeue event, false otherwise.
+ */
bool IsDequeue (void) const;
+ /**
+ * \returns true if this is a drop event, false otherwise.
+ */
bool IsDrop (void) const;
void Print (std::ostream &os) const;
+ std::string GetTypeName (void) const;
private:
enum Type m_type;
};
@@ -69,8 +82,6 @@
Queue ();
virtual ~Queue ();
-
- TraceResolver *CreateTraceResolver (TraceContext const &context);
/**
* \return true if the queue is empty; false otherwise
@@ -167,6 +178,7 @@
virtual bool DoPeek (Packet &p) = 0;
protected:
+ Ptr<TraceResolver> GetTraceResolver (void) const;
// called by subclasses to notify parent of packet drops.
void Drop (const Packet& p);
--- a/src/node/socket.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/node/socket.h Tue Sep 11 14:52:15 2007 +0100
@@ -58,6 +58,7 @@
ERROR_AFNOSUPPORT,
ERROR_INVAL,
ERROR_BADF,
+ ERROR_NOROUTETOHOST,
SOCKET_ERRNO_LAST
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/waf Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../waf "$@"
\ No newline at end of file
--- a/src/routing/global-routing/global-route-manager-impl.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/src/routing/global-routing/global-route-manager-impl.cc Tue Sep 11 14:52:15 2007 +0100
@@ -1089,82 +1089,9 @@
}
//
-// XXX This should probably be a method on Ipv4
-//
// Return the interface index corresponding to a given IP address
-//
- uint32_t
-GlobalRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a)
-{
-//
-// We have an IP address <a> and a vertex ID of the root of the SPF tree.
-// The question is what interface index does this address correspond to.
-// The answer is a little complicated since we have to find a pointer to
-// the node corresponding to the vertex ID, find the Ipv4 interface on that
-// node in order to iterate the interfaces and find the one corresponding to
-// the address in question.
-//
- Ipv4Address routerId = m_spfroot->GetVertexId ();
-//
-// Walk the list of nodes in the system looking for the one corresponding to
-// the node at the root of the SPF tree. This is the node for which we are
-// building the routing table.
-//
- NodeList::Iterator i = NodeList::Begin ();
- for (; i != NodeList::End (); i++)
- {
- Ptr<Node> node = *i;
-
- Ptr<GlobalRouter> rtr =
- node->QueryInterface<GlobalRouter> (GlobalRouter::iid);
-//
-// If the node doesn't have a GlobalRouter interface it can't be the one
-// we're interested in.
-//
- if (rtr == 0)
- {
- continue;
- }
-
- if (rtr->GetRouterId () == routerId)
- {
-//
-// This is the node we're building the routing table for. We're going to need
-// the Ipv4 interface to look for the ipv4 interface index. Since this node
-// is participating in routing IP version 4 packets, it certainly must have
-// an Ipv4 interface.
-//
- Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
- NS_ASSERT_MSG (ipv4,
- "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
- "QI for <Ipv4> interface failed");
-//
-// Look through the interfaces on this node for one that has the IP address
-// we're looking for. If we find one, return the corresponding interface
-// index.
-//
- for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++)
- {
- if (ipv4->GetAddress (i) == a)
- {
- NS_DEBUG (
- "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
- "Interface match for " << a);
- return i;
- }
- }
- }
- }
-//
-// Couldn't find it.
-//
- return 0;
-}
-
-//
-// XXX This should probably be a method on Ipv4
-//
-// Return the interface index corresponding to a given IP address
+// This is a wrapper around GetIfIndexByIpv4Address(), but we first
+// have to find the right node pointer to pass to that function.
//
uint32_t
GlobalRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask)
@@ -1216,17 +1143,7 @@
// we're looking for. If we find one, return the corresponding interface
// index.
//
- for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++)
- {
- if (ipv4->GetAddress (i).CombineMask(amask) ==
- a.CombineMask(amask) )
- {
- NS_DEBUG (
- "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
- "Interface match for " << a);
- return i;
- }
- }
+ return (GetIfIndexByIpv4Address (node, a, amask) );
}
}
//
@@ -1490,27 +1407,6 @@
namespace ns3 {
-class GlobalRouterTestNode : public Node
-{
-public:
- GlobalRouterTestNode ();
-
-private:
- virtual void DoAddDevice (Ptr<NetDevice> device) const {};
- virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
-};
-
-GlobalRouterTestNode::GlobalRouterTestNode ()
-{
-// Ptr<Ipv4L3Protocol> ipv4 = Create<Ipv4L3Protocol> (this);
-}
-
- TraceResolver*
-GlobalRouterTestNode::DoCreateTraceResolver (TraceContext const &context)
-{
- return 0;
-}
-
class GlobalRouteManagerImplTest : public Test {
public:
GlobalRouteManagerImplTest ();
@@ -1693,6 +1589,9 @@
srm->DebugSPFCalculate (lsa0->GetLinkStateId ()); // node n0
Simulator::Run ();
+
+// XXX here we should do some verification of the routes built
+
Simulator::Destroy ();
// This delete clears the srm, which deletes the LSDB, which clears
@@ -1703,7 +1602,6 @@
}
// Instantiate this class for the unit tests
-// XXX here we should do some verification of the routes built
static GlobalRouteManagerImplTest g_globalRouteManagerTest;
} // namespace ns3
--- a/src/routing/global-routing/global-route-manager-impl.h Thu Sep 06 15:18:14 2007 +0100
+++ b/src/routing/global-routing/global-route-manager-impl.h Tue Sep 11 14:52:15 2007 +0100
@@ -754,8 +754,8 @@
GlobalRoutingLinkRecord* prev_link);
void SPFIntraAddRouter (SPFVertex* v);
void SPFIntraAddTransit (SPFVertex* v);
- uint32_t FindOutgoingInterfaceId (Ipv4Address a);
- uint32_t FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask);
+ uint32_t FindOutgoingInterfaceId (Ipv4Address a,
+ Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
};
} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/global-routing/waf Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../../waf "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/waf Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../waf "$@"
\ No newline at end of file
--- a/utils/bench-packets.cc Thu Sep 06 15:18:14 2007 +0100
+++ b/utils/bench-packets.cc Tue Sep 11 14:52:15 2007 +0100
@@ -32,12 +32,15 @@
public:
BenchHeader ();
bool IsOk (void) const;
+
+ static uint32_t GetUid (void);
+
+ static std::string GetName (void);
+ void Print (std::ostream &os) const;
+ uint32_t GetSerializedSize (void) const;
+ void Serialize (Buffer::Iterator start) const;
+ uint32_t Deserialize (Buffer::Iterator start);
private:
- virtual std::string DoGetName (void) const;
- virtual void PrintTo (std::ostream &os) const;
- virtual uint32_t GetSerializedSize (void) const;
- virtual void SerializeTo (Buffer::Iterator start) const;
- virtual uint32_t DeserializeFrom (Buffer::Iterator start);
bool m_ok;
};
@@ -54,17 +57,25 @@
}
template <int N>
+uint32_t
+BenchHeader<N>::GetUid (void)
+{
+ static uint32_t uid = AllocateUid<BenchHeader<N> > (GetName ());
+ return uid;
+}
+
+template <int N>
std::string
-BenchHeader<N>::DoGetName (void) const
+BenchHeader<N>::GetName (void)
{
std::ostringstream oss;
- oss << N;
+ oss << "BenchHeader" << N;
return oss.str ();
}
template <int N>
void
-BenchHeader<N>::PrintTo (std::ostream &os) const
+BenchHeader<N>::Print (std::ostream &os) const
{
NS_ASSERT (false);
}
@@ -76,13 +87,13 @@
}
template <int N>
void
-BenchHeader<N>::SerializeTo (Buffer::Iterator start) const
+BenchHeader<N>::Serialize (Buffer::Iterator start) const
{
start.WriteU8 (N, N);
}
template <int N>
uint32_t
-BenchHeader<N>::DeserializeFrom (Buffer::Iterator start)
+BenchHeader<N>::Deserialize (Buffer::Iterator start)
{
m_ok = true;
for (int i = 0; i < N; i++)
@@ -156,6 +167,7 @@
}
}
+#if 0
static void
benchPrint (uint32_t n)
{
@@ -171,6 +183,7 @@
p.Print (std::cerr, printer);
}
}
+#endif
static void
@@ -205,7 +218,7 @@
runBench (&benchPtrC, n, "c");
Packet::EnableMetadata ();
- runBench (&benchPrint, n, "print");
+ //runBench (&benchPrint, n, "print");
PacketMetadata::SetOptOne (false);
runBench (&benchPtrA, n, "meta-a");
runBench (&benchPtrB, n, "meta-b");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/print-trace-sources.cc Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,100 @@
+#include "ns3/internet-node.h"
+#include "ns3/ptr.h"
+#include "ns3/trace-resolver.h"
+#include "ns3/node-list.h"
+#include "ns3/point-to-point-net-device.h"
+#include "ns3/csma-net-device.h"
+#include "ns3/queue.h"
+#include "ns3/mobility-model-notifier.h"
+
+using namespace ns3;
+
+void
+PrintSimpleText (const TraceResolver::SourceCollection *sources, std::ostream &os)
+{
+ for (TraceResolver::SourceCollection::Iterator i = sources->Begin (); i != sources->End (); i++)
+ {
+ os << "source=" << i->path << std::endl;
+ os << "TraceContext=[";
+ i->context.PrintAvailable (os, ",");
+ os << "]" << std::endl;
+ os << "help=\"" << i->doc.GetHelp () << "\"" << std::endl;
+ os << "void TraceSinkCallback (const TraceContext &";
+ for (TraceDoc::Iterator k = i->doc.ArgsBegin (); k != i->doc.ArgsEnd (); k++)
+ {
+ os << ", " << k->first;
+ }
+ os << ")" << std::endl;
+ os << "argument 1 -- the trace context associated to the connected trace source." << std::endl;
+ uint32_t k = 2;
+ for (TraceDoc::Iterator j = i->doc.ArgsBegin (); j != i->doc.ArgsEnd (); j++)
+ {
+ os << "argument " << k << " -- " << j->second << "." << std::endl;
+ k++;
+ }
+ os << std::endl;
+ }
+}
+void
+PrintDoxygenText (const TraceResolver::SourceCollection *sources, std::ostream &os)
+{
+ uint32_t z = 0;
+ for (TraceResolver::SourceCollection::Iterator i = sources->Begin (); i != sources->End (); i++)
+ {
+ os << "///" << std::endl;
+ os << "/// \\ingroup TraceSourceList" << std::endl;
+ os << "/// \\brief " << i->doc.GetHelp () << std::endl;
+ os << "/// \\param arg1 the trace context associated to the connected trace source." << std::endl;
+ uint32_t j = 2;
+ for (TraceDoc::Iterator l = i->doc.ArgsBegin (); l != i->doc.ArgsEnd (); l++)
+ {
+ os << "/// \\param arg" << j << " " << l->second << "." << std::endl;
+ j++;
+ }
+ os << "///" << std::endl;
+ os << "///" << std::endl;
+ os << "/// The path to this trace source is: " << i->path << "." << std::endl;
+ os << "///" << std::endl;
+ if (i->context.Begin ().IsLast ())
+ {
+ os << "/// No data can be extracted from \\p arg1 with ns3::TraceContext::GetElement." << std::endl;
+ }
+ else
+ {
+ os << "/// The following classes can be extracted from \\p arg1 with " << std::endl;
+ os << "/// ns3::TraceContext::GetElement:" << std::endl;
+ for (TraceContext::Iterator m = i->context.Begin (); !m.IsLast (); m.Next ())
+ {
+ os << "/// - " << m.Get () << std::endl;
+ }
+ }
+ os << "void TraceSinkCallback" << z << " (const TraceContext & arg1" ;
+ j = 2;
+ for (TraceDoc::Iterator k = i->doc.ArgsBegin (); k != i->doc.ArgsEnd (); k++)
+ {
+ os << ", " << k->first << " arg" << j;
+ j++;
+ }
+ os << ");" << std::endl;
+ os << std::endl;
+ z++;
+ }
+}
+
+
+int main (int argc, char *argv[])
+{
+ Ptr<Node> node = Create<InternetNode> ();
+ node->AddInterface (Create<MobilityModelNotifier> ());
+
+ Ptr<PointToPointNetDevice> p2p = Create<PointToPointNetDevice> (node);
+ p2p->AddQueue (Queue::CreateDefault ());
+ Ptr<CsmaNetDevice> csma = Create<CsmaNetDevice> (node);
+ csma->AddQueue (Queue::CreateDefault ());
+
+ TraceResolver::SourceCollection collection;
+ NodeList::GetTraceResolver ()->CollectSources ("", TraceContext (), &collection);
+ PrintDoxygenText (&collection, std::cout);
+
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/waf Tue Sep 11 14:52:15 2007 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../waf "$@"
--- a/utils/wscript Thu Sep 06 15:18:14 2007 +0100
+++ b/utils/wscript Tue Sep 11 14:52:15 2007 +0100
@@ -14,5 +14,12 @@
obj = bld.create_ns3_program('bench-simulator', ['simulator'])
obj.source = 'bench-simulator.cc'
+ obj = bld.create_ns3_program('bench-packets', ['common'])
+ obj.source = 'bench-packets.cc'
+
obj = bld.create_ns3_program('replay-simulation', ['simulator'])
obj.source = 'replay-simulation.cc'
+
+ obj = bld.create_ns3_program('print-trace-sources',
+ ['internet-node', 'csma-cd', 'point-to-point'])
+ obj.source = 'print-trace-sources.cc'
--- a/wscript Thu Sep 06 15:18:14 2007 +0100
+++ b/wscript Tue Sep 11 14:52:15 2007 +0100
@@ -37,7 +37,7 @@
opt.add_option('-d', '--debug-level',
action='callback',
- type="string", dest='debug_level', default='debug',
+ type="string", dest='debug_level', default='ultradebug',
help=('Specify the debug level, does nothing if CFLAGS is set'
' in the environment. [Allowed Values: debug, optimized].'
' WARNING: this option only has effect '
@@ -114,7 +114,7 @@
if (os.path.basename(conf.env['CXX']).startswith("g++")
and 'CXXFLAGS' not in os.environ):
- variant_env.append_value('CXXFLAGS', ['-Wall', '-Werror'])
+ variant_env.append_value('CXXFLAGS', ['-Werror'])
if 'debug' in Params.g_options.debug_level.lower():
variant_env.append_value('CXXDEFINES', 'NS3_DEBUG_ENABLE')
@@ -129,6 +129,13 @@
if flag.startswith('-g'):
variant_env.append_value('CXXFLAGS', flag)
+ ## in optimized builds, replace -O2 with -O3
+ if 'optimized' in Params.g_options.debug_level.lower():
+ lst = variant_env['CXXFLAGS']
+ for i, flag in enumerate(lst):
+ if flag == '-O2':
+ lst[i] = '-O3'
+
if sys.platform == 'win32':
if os.path.basename(conf.env['CXX']).startswith("g++"):
variant_env.append_value("LINKFLAGS", "-Wl,--enable-runtime-pseudo-reloc")