Stats module and example merged in.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/stats/README Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,16 @@
+
+ ns-3 stats example
+
+The example script wifi-example-db.sh in this directly will run
+through the entire process of running a simple experiment. It assumes
+sqlite3 is installed as it uses the sqlite3 data output format of the
+statistics package. It also assumes it is being run from the
+examples/stats/ subdirectory of the ns-3 package, together with its
+gnuplot script. When the script completes successfully, a graph will
+be have been produced in examples/stats/wifi-default.eps demonstrating
+output from this example.
+
+More information on the statistics package and this example is
+available online on the ns-3 wiki at:
+
+http://www.nsnam.org/wiki/index.php/Statistical_Framework_for_Network_Simulation
Binary file examples/stats/data.db has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/stats/wifi-default.data Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,20 @@
+25 0.0
+50 0.0
+75 0.0
+100 0.0
+125 0.0
+145 3.6
+147 6.8
+150 5.0
+152 12.6
+155 20.4
+157 31.6
+160 46.4
+162 58.8
+165 71.6
+167 81.0
+170 96.4
+172 99.4
+175 100.0
+177 100.0
+180 99.4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/stats/wifi-default.eps Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,643 @@
+%!PS-Adobe-2.0
+%%Title: wifi-default.eps
+%%Creator: gnuplot 4.2 patchlevel 0
+%%CreationDate: Fri Aug 29 13:16:08 2008
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 554 525
+%%Orientation: Portrait
+%%Pages: (atend)
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following 6 true/false flags may be edited by hand if required
+% The unit line width may also be changed
+%
+/Color false def
+/Blacktext false def
+/Solid false def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/TransparentPatterns false def
+/gnulinewidth 10.000 def
+/userlinewidth gnulinewidth def
+%
+/vshift -46 def
+/dl1 {
+ 10.0 Dashlength mul mul
+ Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+ 10.0 Dashlength mul mul
+ Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+Level1 {} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+ userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+ /Title (wifi-default.eps)
+ /Subject (gnuplot plot)
+ /Creator (gnuplot 4.2 patchlevel 0)
+ /Author (Joe Kopena,,,,)
+% /Producer (gnuplot)
+% /Keywords ()
+ /CreationDate (Fri Aug 29 13:16:08 2008)
+ /DOCINFO pdfmark
+end
+} ifelse
+%
+% Gnuplot Prolog Version 4.2 (August 2006)
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R
+ Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+ Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R
+ Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+ /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+ Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+ Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+ dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+ Rounded {1 setlinejoin 1 setlinecap} if} def
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+ hpt neg vpt neg V hpt vpt neg V
+ hpt vpt V hpt neg vpt V closepath stroke
+ Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+ currentpoint stroke M
+ hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+ 0 vpt2 neg V hpt2 0 V 0 vpt2 V
+ hpt2 neg 0 V closepath stroke
+ Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+ hpt2 vpt2 neg V currentpoint stroke M
+ hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+ hpt neg vpt -1.62 mul V
+ hpt 2 mul 0 V
+ hpt neg vpt 1.62 mul V closepath stroke
+ Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+ 0 vpt2 neg V hpt2 0 V 0 vpt2 V
+ hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+ hpt neg vpt -1.62 mul V
+ hpt 2 mul 0 V
+ hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+ hpt neg vpt 1.62 mul V
+ hpt 2 mul 0 V
+ hpt neg vpt -1.62 mul V closepath stroke
+ Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+ hpt neg vpt 1.62 mul V
+ hpt 2 mul 0 V
+ hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+ hpt neg vpt neg V hpt vpt neg V
+ hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+ translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+ closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+ translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+ closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+ hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 0 90 arc closepath fill
+ vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 90 180 arc closepath fill
+ vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 0 180 arc closepath fill
+ vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 180 270 arc closepath fill
+ vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 0 90 arc
+ 2 copy moveto
+ 2 copy vpt 180 270 arc closepath fill
+ vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 90 270 arc closepath fill
+ vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 0 270 arc closepath fill
+ vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 270 360 arc closepath fill
+ vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 270 450 arc closepath fill
+ vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+ 2 copy moveto
+ 2 copy vpt 90 180 arc closepath fill
+ vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 0 180 arc closepath fill
+ 2 copy moveto
+ 2 copy vpt 270 360 arc closepath fill
+ vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 180 360 arc closepath fill
+ vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 0 90 arc closepath fill
+ 2 copy moveto
+ 2 copy vpt 180 360 arc closepath fill
+ vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+ 2 copy vpt 90 360 arc closepath fill
+ vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+ vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+ neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+ exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+ 2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+ Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+ Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+ 2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+ 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+ hpt neg vpt neg V hpt vpt neg V
+ hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+ 0 vpt2 neg V hpt2 0 V 0 vpt2 V
+ hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+ hpt neg vpt -1.62 mul V
+ hpt 2 mul 0 V
+ hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+ hpt neg vpt 1.62 mul V
+ hpt 2 mul 0 V
+ hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+ translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+ closepath stroke grestore} def
+/CircE {stroke [] 0 setdash
+ hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+ hpt neg vpt neg V hpt vpt neg V
+ hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+ 0 vpt2 neg V hpt2 0 V 0 vpt2 V
+ hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+ hpt neg vpt -1.62 mul V
+ hpt 2 mul 0 V
+ hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+ hpt neg vpt 1.62 mul V
+ hpt 2 mul 0 V
+ hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+ translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+ Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash
+ hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+ /Fillden exch def
+ currentrgbcolor
+ /ColB exch def /ColG exch def /ColR exch def
+ /ColR ColR Fillden mul Fillden sub 1 add def
+ /ColG ColG Fillden mul Fillden sub 1 add def
+ /ColB ColB Fillden mul Fillden sub 1 add def
+ ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+% x,y = lower left corner of box to be filled
+% w,h = width and height of box
+% a = angle in degrees between lines and x-axis
+% XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+ PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+ PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+ gsave 1 setgray fill grestore clip
+ currentlinewidth 0.5 mul setlinewidth
+ /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+ 0 0 M PFa 5 get rotate PFs -2 div dup translate
+ 0 1 PFs PFa 4 get div 1 add floor cvi
+ {PFa 4 get mul 0 M 0 PFs V} for
+ 0 PFa 6 get ne {
+ 0 1 PFs PFa 4 get div 1 add floor cvi
+ {PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+ stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+ {/InterpretLevel1 true def}
+ {/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+ bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke}
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+ 0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+ 8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+ 0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+ 0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+ 0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+ 0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+ 12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+ -4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+ TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+/MFshow {
+ { dup 5 get 3 ge
+ { 5 get 3 eq {gsave} {grestore} ifelse }
+ {dup dup 0 get findfont exch 1 get scalefont setfont
+ [ currentpoint ] exch dup 2 get 0 exch R dup 5 get 2 ne {dup dup 6
+ get exch 4 get {show} {stringwidth pop 0 R} ifelse }if dup 5 get 0 eq
+ {dup 3 get {2 get neg 0 exch R pop} {pop aload pop M} ifelse} {dup 5
+ get 1 eq {dup 2 get exch dup 3 get exch 6 get stringwidth pop -2 div
+ dup 0 R} {dup 6 get stringwidth pop -2 div 0 R 6 get
+ show 2 index {aload pop M neg 3 -1 roll neg R pop pop} {pop pop pop
+ pop aload pop M} ifelse }ifelse }ifelse }
+ ifelse }
+ forall} bind def
+/MFwidth {0 exch { dup 5 get 3 ge { 5 get 3 eq { 0 } { pop } ifelse }
+ {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont
+ 6 get stringwidth pop add} {pop} ifelse} ifelse} forall} bind def
+/MLshow { currentpoint stroke M
+ 0 exch R
+ Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MRshow { currentpoint stroke M
+ exch dup MFwidth neg 3 -1 roll R
+ Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/MCshow { currentpoint stroke M
+ exch dup MFwidth -2 div 3 -1 roll R
+ Blacktext {gsave 0 setgray MFshow grestore} {MFshow} ifelse } bind def
+/XYsave { [( ) 1 2 true false 3 ()] } bind def
+/XYrestore { [( ) 1 2 true false 4 ()] } bind def
+end
+%%EndProlog
+%%Page: 1 1
+gnudict begin
+gsave
+50 50 translate
+0.100 0.100 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+1.000 UL
+LTb
+714 420 M
+63 0 V
+4025 0 R
+-63 0 V
+stroke
+630 420 M
+[ [(Helvetica) 140.0 0.0 true true 0 ( 0)]
+] -46.7 MRshow
+1.000 UL
+LTb
+714 1177 M
+63 0 V
+4025 0 R
+-63 0 V
+stroke
+630 1177 M
+[ [(Helvetica) 140.0 0.0 true true 0 ( 20)]
+] -46.7 MRshow
+1.000 UL
+LTb
+714 1934 M
+63 0 V
+4025 0 R
+-63 0 V
+stroke
+630 1934 M
+[ [(Helvetica) 140.0 0.0 true true 0 ( 40)]
+] -46.7 MRshow
+1.000 UL
+LTb
+714 2691 M
+63 0 V
+4025 0 R
+-63 0 V
+stroke
+630 2691 M
+[ [(Helvetica) 140.0 0.0 true true 0 ( 60)]
+] -46.7 MRshow
+1.000 UL
+LTb
+714 3448 M
+63 0 V
+4025 0 R
+-63 0 V
+stroke
+630 3448 M
+[ [(Helvetica) 140.0 0.0 true true 0 ( 80)]
+] -46.7 MRshow
+1.000 UL
+LTb
+714 4205 M
+63 0 V
+4025 0 R
+-63 0 V
+stroke
+630 4205 M
+[ [(Helvetica) 140.0 0.0 true true 0 ( 100)]
+] -46.7 MRshow
+1.000 UL
+LTb
+714 420 M
+0 63 V
+0 4101 R
+0 -63 V
+stroke
+714 280 M
+[ [(Helvetica) 140.0 0.0 true true 0 ( 0)]
+] -46.7 MCshow
+1.000 UL
+LTb
+1736 420 M
+0 63 V
+0 4101 R
+0 -63 V
+stroke
+1736 280 M
+[ [(Helvetica) 140.0 0.0 true true 0 ( 50)]
+] -46.7 MCshow
+1.000 UL
+LTb
+2758 420 M
+0 63 V
+0 4101 R
+0 -63 V
+stroke
+2758 280 M
+[ [(Helvetica) 140.0 0.0 true true 0 ( 100)]
+] -46.7 MCshow
+1.000 UL
+LTb
+3780 420 M
+0 63 V
+0 4101 R
+0 -63 V
+stroke
+3780 280 M
+[ [(Helvetica) 140.0 0.0 true true 0 ( 150)]
+] -46.7 MCshow
+1.000 UL
+LTb
+4802 420 M
+0 63 V
+0 4101 R
+0 -63 V
+stroke
+4802 280 M
+[ [(Helvetica) 140.0 0.0 true true 0 ( 200)]
+] -46.7 MCshow
+1.000 UL
+LTb
+1.000 UL
+LTb
+714 4584 N
+714 420 L
+4088 0 V
+0 4164 V
+-4088 0 V
+Z stroke
+LCb setrgbcolor
+140 2502 M
+currentpoint gsave translate 90 rotate 0 0 moveto
+[ [(Helvetica) 140.0 0.0 true true 0 (% Packet Loss --- average of 5 trials per distance)]
+] -46.7 MCshow
+grestore
+LTb
+LCb setrgbcolor
+2758 70 M
+[ [(Helvetica) 140.0 0.0 true true 0 (Distance \(m\))]
+] -46.7 MCshow
+LTb
+1.000 UP
+1.000 UL
+LTb
+1.000 UL
+LT0
+LTb
+4151 4451 M
+[ [(Helvetica) 140.0 0.0 true true 0 (WiFi Defaults)]
+] -46.7 MRshow
+LT0
+4235 4451 M
+399 0 V
+1225 420 M
+511 0 V
+511 0 V
+511 0 V
+511 0 V
+409 136 V
+41 121 V
+61 -68 V
+41 288 V
+61 295 V
+41 424 V
+61 560 V
+41 470 V
+62 484 V
+40 356 V
+62 583 V
+41 114 V
+61 22 V
+41 0 V
+61 -22 V
+stroke
+LTb
+714 4584 N
+714 420 L
+4088 0 V
+0 4164 V
+-4088 0 V
+Z stroke
+1.000 UP
+1.000 UL
+LTb
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
+%%Pages: 1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/stats/wifi-example-apps.cc Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,330 @@
+/* -*- 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
+ *
+ * Authors: Joe Kopena <tjkopena@cs.drexel.edu>
+ *
+ * These applications are used in the WiFi Distance Test experiment,
+ * described and implemented in test02.cc. That file should be in the
+ * same place as this file. The applications have two very simple
+ * jobs, they just generate and receive packets. We could use the
+ * standard Application classes included in the NS-3 distribution.
+ * These have been written just to change the behavior a little, and
+ * provide more examples.
+ *
+ */
+
+#include <ostream>
+
+#include "ns3/core-module.h"
+#include "ns3/common-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/internet-stack-module.h"
+
+#include "ns3/stats-module.h"
+
+#include "wifi-example-apps.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("WiFiDistanceApps");
+
+TypeId
+Sender::GetTypeId(void)
+{
+ static TypeId tid = TypeId ("Sender")
+ .SetParent<Application> ()
+ .AddConstructor<Sender> ()
+ .AddAttribute ("PacketSize", "The size of packets transmitted.",
+ UintegerValue(64),
+ MakeUintegerAccessor(&Sender::m_pktSize),
+ MakeUintegerChecker<uint32_t>(1))
+ .AddAttribute("Destination", "Target host address.",
+ Ipv4AddressValue("255.255.255.255"),
+ MakeIpv4AddressAccessor(&Sender::m_destAddr),
+ MakeIpv4AddressChecker())
+ .AddAttribute("Port", "Destination app port.",
+ UintegerValue(1603),
+ MakeUintegerAccessor(&Sender::m_destPort),
+ MakeUintegerChecker<uint32_t>())
+ .AddAttribute("NumPackets", "Total number of packets to send.",
+ UintegerValue(30),
+ MakeUintegerAccessor(&Sender::m_numPkts),
+ MakeUintegerChecker<uint32_t>(1))
+ .AddAttribute ("Interval", "Delay between transmissions.",
+ RandomVariableValue(ConstantVariable(0.5)),
+ MakeRandomVariableAccessor(&Sender::m_interval),
+ MakeRandomVariableChecker())
+ .AddTraceSource ("Tx", "A new packet is created and is sent",
+ MakeTraceSourceAccessor (&Sender::m_txTrace))
+ ;
+ return tid;
+}
+
+
+Sender::Sender()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_socket = 0;
+}
+
+Sender::~Sender()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+Sender::DoDispose (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ m_socket = 0;
+ // chain up
+ Application::DoDispose ();
+}
+
+void Sender::StartApplication()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (m_socket == 0) {
+ Ptr<SocketFactory> socketFactory = GetNode()->GetObject<SocketFactory>
+ (UdpSocketFactory::GetTypeId());
+ m_socket = socketFactory->CreateSocket ();
+ m_socket->Bind ();
+ }
+
+ m_count = 0;
+
+ Simulator::Cancel(m_sendEvent);
+ m_sendEvent = Simulator::ScheduleNow(&Sender::SendPacket, this);
+
+ // end Sender::StartApplication
+}
+
+void Sender::StopApplication()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Simulator::Cancel(m_sendEvent);
+ // end Sender::StopApplication
+}
+
+void Sender::SendPacket()
+{
+ // NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_INFO("Sending packet at " << Simulator::Now() << " to " <<
+ m_destAddr);
+
+ Ptr<Packet> packet = Create<Packet>(m_pktSize);
+
+ TimestampTag timestamp;
+ timestamp.SetTimestamp(Simulator::Now());
+ packet->AddTag(timestamp);
+
+ // Could connect the socket since the address never changes; using SendTo
+ // here simply because all of the standard apps do not.
+ m_socket->SendTo(packet, 0, InetSocketAddress(m_destAddr, m_destPort));
+
+ // Report the event to the trace.
+ m_txTrace(packet);
+
+ if (++m_count < m_numPkts) {
+ m_sendEvent = Simulator::Schedule(Seconds(m_interval.GetValue()),
+ &Sender::SendPacket, this);
+ }
+
+ // end Sender::SendPacket
+}
+
+
+
+
+//----------------------------------------------------------------------
+//-- Receiver
+//------------------------------------------------------
+TypeId
+Receiver::GetTypeId(void)
+{
+ static TypeId tid = TypeId ("Receiver")
+ .SetParent<Application> ()
+ .AddConstructor<Receiver> ()
+ .AddAttribute("Port", "Listening port.",
+ UintegerValue(1603),
+ MakeUintegerAccessor(&Receiver::m_port),
+ MakeUintegerChecker<uint32_t>())
+ ;
+ return tid;
+}
+
+Receiver::Receiver() :
+ m_calc(0),
+ m_delay(0)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_socket = 0;
+}
+
+Receiver::~Receiver()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+Receiver::DoDispose (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ m_socket = 0;
+ // chain up
+ Application::DoDispose ();
+}
+
+void
+Receiver::StartApplication()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (m_socket == 0) {
+ Ptr<SocketFactory> socketFactory = GetNode()->GetObject<SocketFactory>
+ (UdpSocketFactory::GetTypeId());
+ m_socket = socketFactory->CreateSocket();
+ InetSocketAddress local =
+ InetSocketAddress(Ipv4Address::GetAny(), m_port);
+ m_socket->Bind(local);
+ }
+
+ m_socket->SetRecvCallback(MakeCallback(&Receiver::Receive, this));
+
+ // end Receiver::StartApplication
+}
+
+void
+Receiver::StopApplication()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (m_socket != 0) {
+ m_socket->SetRecvCallback(MakeNullCallback<void, Ptr<Socket> > ());
+ }
+
+ // end Receiver::StopApplication
+}
+
+void
+Receiver::SetCounter(Ptr<CounterCalculator<> > calc)
+{
+ m_calc = calc;
+ // end Receiver::SetCounter
+}
+void
+Receiver::SetDelayTracker(Ptr<TimeMinMaxAvgTotalCalculator> delay)
+{
+ m_delay = delay;
+ // end Receiver::SetDelayTracker
+}
+
+void
+Receiver::Receive(Ptr<Socket> socket)
+{
+ // NS_LOG_FUNCTION (this << socket << packet << from);
+
+ Ptr<Packet> packet;
+ Address from;
+ while (packet = socket->RecvFrom(from)) {
+ if (InetSocketAddress::IsMatchingType (from)) {
+ InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
+ NS_LOG_INFO ("Received " << packet->GetSize() << " bytes from " <<
+ address.GetIpv4());
+ }
+
+ TimestampTag timestamp;
+ packet->FindFirstMatchingTag(timestamp);
+ Time tx = timestamp.GetTimestamp();
+
+ if (m_delay != 0) {
+ m_delay->Update(Simulator::Now() - tx);
+ }
+
+ if (m_calc != 0) {
+ m_calc->Update();
+ }
+
+ // end receiving packets
+ }
+
+ // end Receiver::Receive
+}
+
+
+
+
+//----------------------------------------------------------------------
+//-- TimestampTag
+//------------------------------------------------------
+TypeId
+TimestampTag::GetTypeId(void)
+{
+ static TypeId tid = TypeId ("TimestampTag")
+ .SetParent<Tag> ()
+ .AddConstructor<TimestampTag> ()
+ .AddAttribute ("Timestamp",
+ "Some momentous point in time!",
+ EmptyAttributeValue(),
+ MakeTimeAccessor(&TimestampTag::GetTimestamp),
+ MakeTimeChecker())
+ ;
+ return tid;
+}
+TypeId
+TimestampTag::GetInstanceTypeId(void) const
+{
+ return GetTypeId ();
+}
+
+uint32_t
+TimestampTag::GetSerializedSize (void) const
+{
+ return 8;
+}
+void
+TimestampTag::Serialize (TagBuffer i) const
+{
+ int64_t t = m_timestamp.GetNanoSeconds();
+ i.Write((const uint8_t *)&t, 8);
+}
+void
+TimestampTag::Deserialize (TagBuffer i)
+{
+ int64_t t;
+ i.Read((uint8_t *)&t, 8);
+ m_timestamp = NanoSeconds(t);
+}
+
+void
+TimestampTag::SetTimestamp(Time time)
+{
+ m_timestamp = time;
+}
+Time
+TimestampTag::GetTimestamp(void) const
+{
+ return m_timestamp;
+}
+
+void
+TimestampTag::Print(std::ostream &os) const
+{
+ os << "t=" << m_timestamp;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/stats/wifi-example-apps.h Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,126 @@
+/* -*- 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
+ *
+ * Authors: Joe Kopena <tjkopena@cs.drexel.edu>
+ *
+ * These applications are used in the WiFi Distance Test experiment,
+ * described and implemented in test02.cc. That file should be in the
+ * same place as this file. The applications have two very simple
+ * jobs, they just generate and receive packets. We could use the
+ * standard Application classes included in the NS-3 distribution.
+ * These have been written just to change the behavior a little, and
+ * provide more examples.
+ *
+ */
+
+// #define NS3_LOG_ENABLE // Now defined by Makefile
+
+#include "ns3/core-module.h"
+#include "ns3/common-module.h"
+#include "ns3/application.h"
+
+#include "ns3/stats-module.h"
+
+using namespace ns3;
+
+//----------------------------------------------------------------------
+//------------------------------------------------------
+class Sender: public Application {
+public:
+ static TypeId GetTypeId(void);
+ Sender();
+ virtual ~Sender();
+
+protected:
+ virtual void DoDispose(void);
+
+private:
+ virtual void StartApplication(void);
+ virtual void StopApplication(void);
+
+ void SendPacket();
+
+ uint32_t m_pktSize;
+ Ipv4Address m_destAddr;
+ uint32_t m_destPort;
+ RandomVariable m_interval;
+ uint32_t m_numPkts;
+
+ Ptr<Socket> m_socket;
+ EventId m_sendEvent;
+
+ TracedCallback<Ptr<const Packet> > m_txTrace;
+
+ uint32_t m_count;
+
+ // end class Sender
+};
+
+
+
+
+//------------------------------------------------------
+class Receiver: public Application {
+public:
+ static TypeId GetTypeId(void);
+ Receiver();
+ virtual ~Receiver();
+
+ void SetCounter(Ptr<CounterCalculator<> > calc);
+ void SetDelayTracker(Ptr<TimeMinMaxAvgTotalCalculator> delay);
+
+protected:
+ virtual void DoDispose(void);
+
+private:
+ virtual void StartApplication(void);
+ virtual void StopApplication(void);
+
+ void Receive(Ptr<Socket> socket);
+
+ Ptr<Socket> m_socket;
+
+ uint32_t m_port;
+
+ Ptr<CounterCalculator<> > m_calc;
+ Ptr<TimeMinMaxAvgTotalCalculator> m_delay;
+
+ // end class Receiver
+};
+
+
+
+
+//------------------------------------------------------
+class TimestampTag : public Tag {
+public:
+ static TypeId GetTypeId (void);
+ virtual TypeId GetInstanceTypeId (void) const;
+
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (TagBuffer i) const;
+ virtual void Deserialize (TagBuffer i);
+
+ // these are our accessors to our tag structure
+ void SetTimestamp(Time time);
+ Time GetTimestamp(void) const;
+
+ void Print(std::ostream &os) const;
+
+private:
+ Time m_timestamp;
+
+ // end class TimestampTag
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/stats/wifi-example-db.sh Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,76 @@
+#!/bin/sh
+
+DISTANCES="25 50 75 100 125 145 147 150 152 155 157 160 162 165 167 170 172 175 177 180"
+TRIALS="1 2 3 4 5"
+
+echo WiFi Experiment Example
+
+pCheck=`which sqlite3`
+if [ -z "$pCheck" ]
+then
+ echo "ERROR: This script requires sqlite3 (wifi-example-sim does not)."
+ exit 255
+fi
+
+pCheck=`which gnuplot`
+if [ -z "$pCheck" ]
+then
+ echo "ERROR: This script requires gnuplot (wifi-example-sim does not)."
+ exit 255
+fi
+
+pCheck=`which sed`
+if [ -z "$pCheck" ]
+then
+ echo "ERROR: This script requires sed (wifi-example-sim does not)."
+ exit 255
+fi
+
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:bin/
+
+if [ -e ../../data.db ]
+then
+ echo "Kill data.db? (y/n)"
+ read ANS
+ if [ "$ANS" = "yes" -o "$ANS" = "y" ]
+ then
+ echo Deleting database
+ rm ../../data.db
+ fi
+fi
+
+for trial in $TRIALS
+do
+ for distance in $DISTANCES
+ do
+ echo Trial $trial, distance $distance
+ ../../waf --run "wifi-example-sim --format=db --distance=$distance --run=run-$distance-$trial"
+ done
+done
+
+#
+#Another SQL command which just collects raw numbers of frames receved.
+#
+#CMD="select Experiments.input,avg(Singletons.value) \
+# from Singletons,Experiments \
+# where Singletons.run = Experiments.run AND \
+# Singletons.name='wifi-rx-frames' \
+# group by Experiments.input \
+# order by abs(Experiments.input) ASC;"
+
+mv ../../data.db .
+
+CMD="select exp.input,avg(100-((rx.value*100)/tx.value)) \
+ from Singletons rx, Singletons tx, Experiments exp \
+ where rx.run = tx.run AND \
+ rx.run = exp.run AND \
+ rx.name='receiver-rx-packets' AND \
+ tx.name='sender-tx-packets' \
+ group by exp.input \
+ order by abs(exp.input) ASC;"
+
+sqlite3 -noheader data.db "$CMD" > wifi-default.data
+sed -i "s/|/ /" wifi-default.data
+gnuplot wifi-example.gnuplot
+
+echo "Done; data in wifi-default.data, plot in wifi-default.eps"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/stats/wifi-example-sim.cc Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,318 @@
+/* -*- 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
+ *
+ * Authors: Joe Kopena <tjkopena@cs.drexel.edu>
+ *
+ * This program conducts a simple experiment: It places two nodes at a
+ * parameterized distance apart. One node generates packets and the
+ * other node receives. The stat framework collects data on packet
+ * loss. Outside of this program, a control script uses that data to
+ * produce graphs presenting performance at the varying distances.
+ * This isn't a typical simulation but is a common "experiment"
+ * performed in real life and serves as an accessible exemplar for the
+ * stat framework. It also gives some intuition on the behavior and
+ * basic reasonability of the NS-3 WiFi models.
+ *
+ * Applications used by this program are in test02-apps.h and
+ * test02-apps.cc, which should be in the same place as this file.
+ *
+ */
+
+// #define NS3_LOG_ENABLE // Now defined by Makefile
+
+#include <sstream>
+
+#include "ns3/core-module.h"
+#include "ns3/common-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/wifi-module.h"
+
+#include "ns3/stats-module.h"
+
+#include "wifi-example-apps.h"
+
+using namespace ns3;
+using namespace std;
+
+NS_LOG_COMPONENT_DEFINE ("WiFiDistanceExperiment");
+
+
+
+
+void TxCallback(Ptr<CounterCalculator<uint32_t> > datac,
+ std::string path, Ptr<const Packet> packet,
+ Mac48Address realto) {
+ NS_LOG_INFO("Sent frame to " << realto << "; counted in " <<
+ datac->GetKey());
+ datac->Update();
+ // end TxCallback
+}
+
+
+
+
+//----------------------------------------------------------------------
+//-- main
+//----------------------------------------------
+int main(int argc, char *argv[]) {
+
+ double distance = 50.0;
+ string format("omnet");
+
+ string experiment("wifi-distance-test");
+ string strategy("wifi-default");
+ string input;
+ string runID;
+
+ {
+ stringstream sstr;
+ sstr << "run-" << time(NULL);
+ runID = sstr.str();
+ }
+
+ // Set up command line parameters used to control the experiment.
+ CommandLine cmd;
+ cmd.AddValue("distance", "Distance apart to place nodes (in meters).",
+ distance);
+ cmd.AddValue("format", "Format to use for data output.",
+ format);
+ cmd.AddValue("experiment", "Identifier for experiment.",
+ experiment);
+ cmd.AddValue("strategy", "Identifier for strategy.",
+ strategy);
+ cmd.AddValue("run", "Identifier for run.",
+ runID);
+ cmd.Parse (argc, argv);
+
+ if (format != "omnet" && format != "db") {
+ NS_LOG_ERROR("Unknown output format '" << format << "'");
+ return -1;
+ }
+
+ #ifndef STATS_HAS_SQLITE3
+ if (format == "db") {
+ NS_LOG_ERROR("sqlite support not compiled in.");
+ return -1;
+ }
+ #endif
+
+ {
+ stringstream sstr("");
+ sstr << distance;
+ input = sstr.str();
+ }
+
+
+
+
+ //------------------------------------------------------------
+ //-- Create nodes and network stacks
+ //--------------------------------------------
+ NS_LOG_INFO("Creating nodes.");
+ NodeContainer nodes;
+ nodes.Create(2);
+
+ NS_LOG_INFO("Installing WiFi and Internet stack.");
+ WifiHelper wifi;
+ wifi.SetMac("ns3::AdhocWifiMac");
+ wifi.SetPhy("ns3::WifiPhy");
+ NetDeviceContainer nodeDevices = wifi.Install(nodes);
+
+ InternetStackHelper internet;
+ internet.Install(nodes);
+ Ipv4AddressHelper ipAddrs;
+ ipAddrs.SetBase("192.168.0.0", "255.255.255.0");
+ ipAddrs.Assign(nodeDevices);
+
+
+
+
+ //------------------------------------------------------------
+ //-- Setup physical layout
+ //--------------------------------------------
+ NS_LOG_INFO("Installing static mobility; distance " << distance << " .");
+ MobilityHelper mobility;
+ Ptr<ListPositionAllocator> positionAlloc =
+ CreateObject<ListPositionAllocator>();
+ positionAlloc->Add(Vector(0.0, 0.0, 0.0));
+ positionAlloc->Add(Vector(0.0, distance, 0.0));
+ mobility.SetPositionAllocator(positionAlloc);
+ mobility.Install(nodes);
+
+
+
+
+ //------------------------------------------------------------
+ //-- Create a custom traffic source and sink
+ //--------------------------------------------
+ NS_LOG_INFO ("Create traffic source & sink.");
+ Ptr<Node> appSource = NodeList::GetNode(0);
+ Ptr<Sender> sender = CreateObject<Sender>();
+ appSource->AddApplication(sender);
+ sender->Start(Seconds(1));
+
+ Ptr<Node> appSink = NodeList::GetNode(1);
+ Ptr<Receiver> receiver = CreateObject<Receiver>();
+ appSink->AddApplication(receiver);
+ receiver->Start(Seconds(0));
+
+ // Config::Set("/NodeList/*/ApplicationList/*/$Sender/Destination",
+ // Ipv4AddressValue("192.168.0.2"));
+
+
+
+
+ //------------------------------------------------------------
+ //-- Setup stats and data collection
+ //--------------------------------------------
+
+ // Create a DataCollector object to hold information about this run.
+ DataCollector data;
+ data.DescribeRun(experiment,
+ strategy,
+ input,
+ runID);
+
+ // Add any information we wish to record about this run.
+ data.AddMetadata("author", "tjkopena");
+
+
+ // Create a counter to track how many frames are generated. Updates
+ // are triggered by the trace signal generated by the WiFi MAC model
+ // object. Here we connect the counter to the signal via the simple
+ // TxCallback() glue function defined above.
+ Ptr<CounterCalculator<uint32_t> > totalTx =
+ CreateObject<CounterCalculator<uint32_t> >();
+ totalTx->SetKey("wifi-tx-frames");
+ Config::Connect("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Tx",
+ MakeBoundCallback(&TxCallback, totalTx));
+ data.AddDataCalculator(totalTx);
+
+ // This is similar, but creates a counter to track how many frames
+ // are received. Instead of our own glue function, this uses a
+ // method of an adapter class to connect a counter directly to the
+ // trace signal generated by the WiFi MAC.
+ Ptr<PacketCounterCalculator> totalRx =
+ CreateObject<PacketCounterCalculator>();
+ totalRx->SetKey("wifi-rx-frames");
+ Config::Connect("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Rx",
+ MakeCallback(&PacketCounterCalculator::FrameUpdate,
+ totalRx));
+ data.AddDataCalculator(totalRx);
+
+
+
+
+ // This counter tracks how many packets---as opposed to frames---are
+ // generated. This is connected directly to a trace signal provided
+ // by our Sender class.
+ Ptr<PacketCounterCalculator> appTx =
+ CreateObject<PacketCounterCalculator>();
+ appTx->SetKey("sender-tx-packets");
+ Config::Connect("/NodeList/0/ApplicationList/*/$Sender/Tx",
+ MakeCallback(&PacketCounterCalculator::PacketUpdate,
+ appTx));
+ data.AddDataCalculator(appTx);
+
+ // Here a counter for received packets is directly manipulated by
+ // one of the custom objects in our simulation, the Receiver
+ // Application. The Receiver object is given a pointer to the
+ // counter and calls its Update() method whenever a packet arrives.
+ Ptr<CounterCalculator<> > appRx =
+ CreateObject<CounterCalculator<> >();
+ appRx->SetKey("receiver-rx-packets");
+ receiver->SetCounter(appRx);
+ data.AddDataCalculator(appRx);
+
+
+
+
+ /**
+ * Just to show this is here...
+ Ptr<MinMaxAvgTotalCalculator<uint32_t> > test =
+ CreateObject<MinMaxAvgTotalCalculator<uint32_t> >();
+ test->SetKey("test-dc");
+ data.AddDataCalculator(test);
+
+ test->Update(4);
+ test->Update(8);
+ test->Update(24);
+ test->Update(12);
+ **/
+
+ // This DataCalculator connects directly to the transmit trace
+ // provided by our Sender Application. It records some basic
+ // statistics about the sizes of the packets received (min, max,
+ // avg, total # bytes), although in this scenaro they're fixed.
+ Ptr<PacketSizeMinMaxAvgTotalCalculator> appTxPkts =
+ CreateObject<PacketSizeMinMaxAvgTotalCalculator>();
+ appTxPkts->SetKey("tx-pkt-size");
+ Config::Connect("/NodeList/0/ApplicationList/*/$Sender/Tx",
+ MakeCallback
+ (&PacketSizeMinMaxAvgTotalCalculator::PacketUpdate,
+ appTxPkts));
+ data.AddDataCalculator(appTxPkts);
+
+
+ // Here we directly manipulate another DataCollector tracking min,
+ // max, total, and average propagation delays. Check out the Sender
+ // and Receiver classes to see how packets are tagged with
+ // timestamps to do this.
+ Ptr<TimeMinMaxAvgTotalCalculator> delayStat =
+ CreateObject<TimeMinMaxAvgTotalCalculator>();
+ delayStat->SetKey("delay");
+ receiver->SetDelayTracker(delayStat);
+ data.AddDataCalculator(delayStat);
+
+
+
+
+ //------------------------------------------------------------
+ //-- Run the simulation
+ //--------------------------------------------
+ NS_LOG_INFO("Run Simulation.");
+ Simulator::Run();
+ Simulator::Destroy();
+
+
+
+
+ //------------------------------------------------------------
+ //-- Generate statistics output.
+ //--------------------------------------------
+
+ // Pick an output writer based in the requested format.
+ Ptr<DataOutputInterface> output = 0;
+ if (format == "omnet") {
+ NS_LOG_INFO("Creating omnet formatted data output.");
+ output = CreateObject<OmnetDataOutput>();
+ } else if (format == "db") {
+ #ifdef STATS_HAS_SQLITE3
+ NS_LOG_INFO("Creating sqlite formatted data output.");
+ output = CreateObject<SqliteDataOutput>();
+ #endif
+ } else {
+ NS_LOG_ERROR("Unknown output format " << format);
+ }
+
+ // Finally, have that writer interrogate the DataCollector and save
+ // the results.
+ if (output != 0)
+ output->Output(data);
+
+ // end main
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/stats/wifi-example.gnuplot Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,13 @@
+set terminal postscript portrait enhanced lw 2 "Helvetica" 14
+
+set size 1.0, 0.66
+
+#-------------------------------------------------------
+set out "wifi-default.eps"
+#set title "Packet Loss Over Distance"
+set xlabel "Distance (m)"
+set xrange [0:200]
+set ylabel "% Packet Loss --- average of 5 trials per distance"
+set yrange [0:110]
+
+plot "wifi-default.data" with lines title "WiFi Defaults"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/stats/wscript Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,6 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+ obj = bld.create_ns3_program('wifi-example-sim', ['stats'])
+ obj.source = ['wifi-example-sim.cc',
+ 'wifi-example-apps.cc']
--- a/examples/wscript Fri Aug 29 14:56:24 2008 +0100
+++ b/examples/wscript Fri Aug 29 13:22:09 2008 -0400
@@ -76,4 +76,4 @@
['core', 'simulator', 'mobility', 'wifi'])
obj.source = 'wifi-ap.cc'
-
+ bld.add_subdirs('stats')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/stats/basic-data-calculators.h Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,189 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Drexel University
+ *
+ * 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: Joe Kopena (tjkopena@cs.drexel.edu)
+ */
+
+#ifndef __BASIC_DATA_CALCULATORS_H__
+#define __BASIC_DATA_CALCULATORS_H__
+
+#include "data-calculator.h"
+#include "data-output-interface.h"
+
+namespace ns3 {
+
+ //------------------------------------------------------------
+ //--------------------------------------------
+ template <typename T = uint32_t>
+ class MinMaxAvgTotalCalculator : public DataCalculator {
+ public:
+ MinMaxAvgTotalCalculator();
+ virtual ~MinMaxAvgTotalCalculator();
+
+ void Update(const T i);
+
+ virtual void Output(DataOutputCallback &callback) const;
+
+ protected:
+ virtual void DoDispose(void);
+
+ uint32_t m_count;
+ T m_total, m_min, m_max;
+
+ // end MinMaxAvgTotalCalculator
+ };
+
+ //----------------------------------------------
+ template <typename T>
+ MinMaxAvgTotalCalculator<T>::MinMaxAvgTotalCalculator()
+ {
+ m_count = 0;
+ m_total = 0;
+ m_min = ~0;
+ m_max = 0;
+ }
+
+ template <typename T>
+ MinMaxAvgTotalCalculator<T>::~MinMaxAvgTotalCalculator()
+ {
+ }
+ template <typename T>
+ void
+ MinMaxAvgTotalCalculator<T>::DoDispose(void)
+ {
+ DataCalculator::DoDispose();
+ // MinMaxAvgTotalCalculator::DoDispose
+ }
+
+ template <typename T>
+ void
+ MinMaxAvgTotalCalculator<T>::Update(const T i)
+ {
+ if (m_enabled) {
+ m_total += i;
+
+ if (i < m_min)
+ m_min = i;
+
+ if (i > m_max)
+ m_max = i;
+
+ m_count++;
+ }
+ // end MinMaxAvgTotalCalculator::Update
+ }
+ template <typename T>
+ void
+ MinMaxAvgTotalCalculator<T>::Output(DataOutputCallback &callback) const
+ {
+ callback.OutputSingleton(m_key, "count", m_count);
+ if (m_count > 0) {
+ callback.OutputSingleton(m_key, "total", m_total);
+ callback.OutputSingleton(m_key, "average", m_total/m_count);
+ callback.OutputSingleton(m_key, "max", m_max);
+ callback.OutputSingleton(m_key, "min", m_min);
+ }
+ // end MinMaxAvgTotalCalculator::Output
+ }
+
+
+
+
+ //------------------------------------------------------------
+ //--------------------------------------------
+ template <typename T = uint32_t>
+ class CounterCalculator : public DataCalculator {
+ public:
+ CounterCalculator();
+ virtual ~CounterCalculator();
+
+ void Update();
+ void Update(const T i);
+
+ T GetCount() const;
+
+ virtual void Output(DataOutputCallback &callback) const;
+
+ protected:
+ virtual void DoDispose(void);
+
+ T m_count;
+
+ // end CounterCalculator
+ };
+
+
+ //--------------------------------------------
+ template <typename T>
+ CounterCalculator<T>::CounterCalculator() :
+ m_count(0)
+ {
+ }
+
+ template <typename T>
+ CounterCalculator<T>::~CounterCalculator()
+ {
+ }
+ template <typename T>
+ void
+ CounterCalculator<T>::DoDispose(void)
+ {
+ DataCalculator::DoDispose();
+ // CounterCalculator::DoDispose
+ }
+
+ template <typename T>
+ void
+ CounterCalculator<T>::Update()
+ {
+ if (m_enabled) {
+ m_count++;
+ }
+ // end CounterCalculator::Update
+ }
+
+ template <typename T>
+ void
+ CounterCalculator<T>::Update(const T i)
+ {
+ if (m_enabled) {
+ m_count += i;
+ }
+ // end CounterCalculator::Update
+ }
+
+ template <typename T>
+ T
+ CounterCalculator<T>::GetCount() const
+ {
+ return m_count;
+ // end CounterCalculator::GetCount
+ }
+
+ template <typename T>
+ void
+ CounterCalculator<T>::Output(DataOutputCallback &callback) const
+ {
+ callback.OutputSingleton(m_key, "count", m_count);
+ // end CounterCalculator::Output
+ }
+
+ // end namespace ns3
+};
+
+
+#endif // __BASIC_DATA_CALCULATORS_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/stats/data-calculator.cc Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,110 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Drexel University
+ *
+ * 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: Joe Kopena (tjkopena@cs.drexel.edu)
+ */
+
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+
+#include "data-calculator.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE("DataCalculator");
+
+
+//--------------------------------------------------------------
+//----------------------------------------------
+DataCalculator::DataCalculator() :
+ m_enabled(true)
+{
+ NS_LOG_FUNCTION_NOARGS();
+}
+
+DataCalculator::~DataCalculator()
+{
+ NS_LOG_FUNCTION_NOARGS();
+}
+
+void
+DataCalculator::DoDispose(void)
+{
+ NS_LOG_FUNCTION_NOARGS();
+
+ Simulator::Cancel(m_startEvent);
+ Simulator::Cancel(m_stopEvent);
+
+ Object::DoDispose();
+ // DataCalculator::DoDispose
+}
+
+//----------------------------------------------
+void
+DataCalculator::SetKey(const std::string key)
+{
+ m_key = key;
+ // end DataCalculator::SetKey
+}
+
+const std::string
+DataCalculator::GetKey() const
+{
+ return m_key;
+ // end DataCalculator::GetKey
+}
+
+//----------------------------------------------
+void
+DataCalculator::Enable()
+{
+ m_enabled = true;
+ // end DataCalculator::Enable
+}
+
+void
+DataCalculator::Disable()
+{
+ m_enabled = false;
+ // end DataCalculator::Disable
+}
+
+bool
+DataCalculator::GetEnabled() const
+{
+ return m_enabled;
+ // end DataCalculator::GetEnabled
+}
+
+//----------------------------------------------
+void
+DataCalculator::Start(const Time& startTime)
+{
+
+ m_startEvent = Simulator::Schedule(startTime,
+ &DataCalculator::Enable, this);
+
+ // end DataCalculator::Start
+}
+
+void
+DataCalculator::Stop(const Time& stopTime)
+{
+ m_stopEvent = Simulator::Schedule(stopTime,
+ &DataCalculator::Disable, this);
+ // end DataCalculator::Stop
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/stats/data-calculator.h Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,70 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Drexel University
+ *
+ * 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: Joe Kopena (tjkopena@cs.drexel.edu)
+ */
+
+#ifndef __DATA_CALCULATOR_H__
+#define __DATA_CALCULATOR_H__
+
+#include "ns3/object.h"
+#include "ns3/nstime.h"
+#include "ns3/simulator.h"
+
+namespace ns3 {
+
+ class DataOutputCallback;
+
+ //------------------------------------------------------------
+ //--------------------------------------------
+ class DataCalculator : public Object {
+ public:
+ DataCalculator();
+ virtual ~DataCalculator();
+
+ bool GetEnabled() const;
+ void Enable();
+ void Disable();
+
+ void SetKey(const std::string key);
+ const std::string GetKey() const;
+
+ virtual void Start(const Time& startTime);
+ virtual void Stop(const Time& stopTime);
+
+ virtual void Output(DataOutputCallback &callback) const = 0;
+
+ protected:
+ bool m_enabled; // Descendant classes *must* check & respect m_enabled!
+
+ std::string m_key;
+
+ virtual void DoDispose(void);
+
+ private:
+ EventId m_startEvent;
+ EventId m_stopEvent;
+
+ // end class DataCalculator
+ };
+
+
+ // end namespace ns3
+};
+
+
+#endif // __DATA_CALCULATOR_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/stats/data-collector.cc Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,131 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Drexel University
+ *
+ * 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: Joe Kopena (tjkopena@cs.drexel.edu)
+ */
+
+#include "ns3/object.h"
+#include "ns3/log.h"
+
+#include "data-collector.h"
+#include "data-calculator.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE("DataCollector");
+
+//--------------------------------------------------------------
+//----------------------------------------------
+DataCollector::DataCollector() {
+ NS_LOG_FUNCTION_NOARGS();
+ // end DataCollector::DataCollector
+}
+
+DataCollector::~DataCollector() {
+ NS_LOG_FUNCTION_NOARGS();
+ // end DataCollector::~DataCollector
+}
+
+void DataCollector::DoDispose() {
+ NS_LOG_FUNCTION_NOARGS();
+
+ m_calcList.clear();
+ m_metadata.clear();
+
+ Object::DoDispose();
+ // end DataCollector::DoDispose
+}
+
+void
+DataCollector::DescribeRun(std::string experiment,
+ std::string strategy,
+ std::string input,
+ std::string runID,
+ std::string description)
+{
+
+ m_experimentLabel = experiment;
+ m_strategyLabel = strategy;
+ m_inputLabel = input;
+ m_runLabel = runID;
+ m_description = description;
+
+ // end DataCollector::DescribeRun
+}
+
+void
+DataCollector::AddDataCalculator(Ptr<DataCalculator> datac)
+{
+
+ m_calcList.push_back(datac);
+
+ // end DataCollector::AddDataCalculator
+}
+
+DataCalculatorList::iterator
+DataCollector::DataCalculatorBegin()
+{
+ return m_calcList.begin();
+ // end DataCollector::DataCalculatorBegin
+}
+DataCalculatorList::iterator
+DataCollector::DataCalculatorEnd()
+{
+ return m_calcList.end();
+ // end DataCollector::DataCalculatorEnd
+}
+
+void
+DataCollector::AddMetadata(std::string key, std::string value)
+{
+ std::pair<std::string, std::string> blob(key, value);
+ m_metadata.push_back(blob);
+ // end DataCollector::AddMetadata
+}
+void
+DataCollector::AddMetadata(std::string key, uint32_t value)
+{
+ std::stringstream st;
+ st << value;
+
+ std::pair<std::string, std::string> blob(key, st.str());
+ m_metadata.push_back(blob);
+ // end DataCollector::AddMetadata
+}
+void
+DataCollector::AddMetadata(std::string key, double value)
+{
+ std::stringstream st;
+ st << value;
+
+ std::pair<std::string, std::string> blob(key, st.str());
+ m_metadata.push_back(blob);
+ // end DataCollector::AddMetadata
+}
+
+MetadataList::iterator
+DataCollector::MetadataBegin()
+{
+ return m_metadata.begin();
+ // end DataCollector::MetadataBegin
+}
+MetadataList::iterator
+DataCollector::MetadataEnd()
+{
+ return m_metadata.end();
+ // end DataCollector::MetadataEnd
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/stats/data-collector.h Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,84 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Drexel University
+ *
+ * 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: Joe Kopena (tjkopena@cs.drexel.edu)
+ */
+
+#ifndef __DATA_COLLECTOR_H__
+#define __DATA_COLLECTOR_H__
+
+#include <list>
+#include <string>
+
+#include "ns3/object.h"
+
+namespace ns3 {
+
+ class DataCalculator;
+
+ //------------------------------------------------------------
+ //--------------------------------------------
+ typedef std::list<Ptr<DataCalculator> > DataCalculatorList;
+ typedef std::list<std::pair<std::string, std::string> > MetadataList;
+
+ class DataCollector : public Object {
+ public:
+ DataCollector();
+ virtual ~DataCollector();
+
+ void DescribeRun(std::string experiment,
+ std::string strategy,
+ std::string input,
+ std::string runID,
+ std::string description = "");
+
+ std::string GetExperimentLabel() const { return m_experimentLabel; }
+ std::string GetStrategyLabel() const { return m_strategyLabel; }
+ std::string GetInputLabel() const { return m_inputLabel; }
+ std::string GetRunLabel() const { return m_runLabel; }
+ std::string GetDescription() const { return m_description; }
+
+ void AddMetadata(std::string key, std::string value);
+ void AddMetadata(std::string key, double value);
+ void AddMetadata(std::string key, uint32_t value);
+ MetadataList::iterator MetadataBegin();
+ MetadataList::iterator MetadataEnd();
+
+ void AddDataCalculator(Ptr<DataCalculator> datac);
+ DataCalculatorList::iterator DataCalculatorBegin();
+ DataCalculatorList::iterator DataCalculatorEnd();
+
+ protected:
+ virtual void DoDispose();
+
+ private:
+ std::string m_experimentLabel;
+ std::string m_strategyLabel;
+ std::string m_inputLabel;
+ std::string m_runLabel;
+ std::string m_description;
+
+ MetadataList m_metadata;
+ DataCalculatorList m_calcList;
+
+ // end class DataCollector
+ };
+
+ // end namespace ns3
+};
+
+#endif // __DATA_COLLECTOR_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/stats/data-output-interface.cc Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,47 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Drexel University
+ *
+ * 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: Joe Kopena (tjkopena@cs.drexel.edu)
+ */
+
+#include "ns3/log.h"
+
+#include "data-output-interface.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE("DataOutputInterface");
+
+
+//--------------------------------------------------------------
+//----------------------------------------------
+DataOutputInterface::DataOutputInterface()
+{
+ NS_LOG_FUNCTION_NOARGS();
+}
+DataOutputInterface::~DataOutputInterface()
+{
+ NS_LOG_FUNCTION_NOARGS();
+}
+void
+DataOutputInterface::DoDispose()
+{
+ NS_LOG_FUNCTION_NOARGS();
+
+ Object::DoDispose();
+ // end DataOutputInterface::DoDispose
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/stats/data-output-interface.h Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,76 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Drexel University
+ *
+ * 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: Joe Kopena (tjkopena@cs.drexel.edu)
+ */
+
+#ifndef __DATA_OUTPUT_INTERFACE_H__
+#define __DATA_OUTPUT_INTERFACE_H__
+
+#include "ns3/object.h"
+#include "ns3/nstime.h"
+
+namespace ns3 {
+
+ class DataCollector;
+
+ //------------------------------------------------------------
+ //--------------------------------------------
+ class DataOutputInterface : public Object {
+ public:
+ DataOutputInterface();
+ virtual ~DataOutputInterface();
+
+ virtual void Output(DataCollector &dc) = 0;
+
+ protected:
+ virtual void DoDispose();
+
+ // end class DataOutputInterface
+ };
+
+ class DataOutputCallback {
+ public:
+ virtual ~DataOutputCallback() {}
+
+ virtual void OutputSingleton(std::string key,
+ std::string variable,
+ int val) = 0;
+
+ virtual void OutputSingleton(std::string key,
+ std::string variable,
+ uint32_t val) = 0;
+
+ virtual void OutputSingleton(std::string key,
+ std::string variable,
+ double val) = 0;
+
+ virtual void OutputSingleton(std::string key,
+ std::string variable,
+ std::string val) = 0;
+
+ virtual void OutputSingleton(std::string key,
+ std::string variable,
+ Time val) = 0;
+ // end class DataOutputCallback
+ };
+
+ // end namespace ns3
+};
+
+
+#endif // __DATA_OUTPUT_INTERFACE_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/stats/omnet-data-output.cc Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,155 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Drexel University
+ *
+ * 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: Joe Kopena (tjkopena@cs.drexel.edu)
+ */
+
+#include <fstream>
+
+#include "ns3/log.h"
+#include "ns3/nstime.h"
+
+#include "data-collector.h"
+#include "data-calculator.h"
+#include "omnet-data-output.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE("OmnetDataOutput");
+
+
+//--------------------------------------------------------------
+//----------------------------------------------
+OmnetDataOutput::OmnetDataOutput() :
+ m_filePrefix("data")
+{
+ NS_LOG_FUNCTION_NOARGS();
+}
+OmnetDataOutput::~OmnetDataOutput()
+{
+ NS_LOG_FUNCTION_NOARGS();
+}
+void
+OmnetDataOutput::DoDispose()
+{
+ NS_LOG_FUNCTION_NOARGS();
+
+ DataOutputInterface::DoDispose();
+ // end OmnetDataOutput::DoDispose
+}
+
+void
+OmnetDataOutput::SetFilePrefix(const std::string prefix)
+{
+ m_filePrefix = prefix;
+}
+std::string
+OmnetDataOutput::GetFilePrefix() const
+{
+ return m_filePrefix;
+}
+
+//----------------------------------------------
+void
+OmnetDataOutput::Output(DataCollector &dc)
+{
+
+ std::ofstream scalarFile;
+ std::string fn = m_filePrefix + ".sca";
+ scalarFile.open(fn.c_str(), std::ios_base::app);
+
+ scalarFile << std::endl;
+ scalarFile << "run " << dc.GetRunLabel() << std::endl;
+ scalarFile << std::endl;
+ scalarFile << "attr experiment \"" << dc.GetExperimentLabel()
+ << "\"" << std::endl;
+ scalarFile << "attr strategy \"" << dc.GetStrategyLabel()
+ << "\"" << std::endl;
+ scalarFile << "attr input \"" << dc.GetInputLabel()
+ << "\"" << std::endl;
+ scalarFile << "attr description \"" << dc.GetDescription()
+ << "\"" << std::endl;
+ scalarFile << std::endl;
+
+ for (MetadataList::iterator i = dc.MetadataBegin();
+ i != dc.MetadataEnd(); i++) {
+ std::pair<std::string, std::string> blob = (*i);
+ scalarFile << "attr \"" << blob.first << "\" \"" << blob.second << "\""
+ << std::endl;
+ }
+
+ scalarFile << std::endl;
+
+ OmnetOutputCallback callback(&scalarFile);
+
+ for (DataCalculatorList::iterator i = dc.DataCalculatorBegin();
+ i != dc.DataCalculatorEnd(); i++) {
+ (*i)->Output(callback);
+ }
+
+ scalarFile << std::endl << std::endl;
+ scalarFile.close();
+
+ // end OmnetDataOutput::Output
+}
+
+OmnetDataOutput::OmnetOutputCallback::OmnetOutputCallback
+ (std::ostream *scalar) :
+ m_scalar(scalar)
+{
+}
+
+void
+OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string key,
+ std::string variable,
+ int val)
+{
+ (*m_scalar) << "scalar " << key << " " << variable << " " << val << std::endl;
+ // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
+}
+void
+OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string key,
+ std::string variable,
+ uint32_t val)
+{
+ (*m_scalar) << "scalar " << key << " " << variable << " " << val << std::endl;
+ // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
+}
+void
+OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string key,
+ std::string variable,
+ double val)
+{
+ (*m_scalar) << "scalar " << key << " " << variable << " " << val << std::endl;
+ // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
+}
+void
+OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string key,
+ std::string variable,
+ std::string val)
+{
+ (*m_scalar) << "scalar " << key << " " << variable << " " << val << std::endl;
+ // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
+}
+void
+OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string key,
+ std::string variable,
+ Time val)
+{
+ (*m_scalar) << "scalar " << key << " " << variable << " " << val << std::endl;
+ // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/stats/omnet-data-output.h Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,84 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Drexel University
+ *
+ * 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: Joe Kopena (tjkopena@cs.drexel.edu)
+ */
+
+#ifndef __OMNET_DATA_OUTPUT_H__
+#define __OMNET_DATA_OUTPUT_H__
+
+#include "ns3/nstime.h"
+
+#include "data-output-interface.h"
+
+namespace ns3 {
+
+
+ //------------------------------------------------------------
+ //--------------------------------------------
+ class OmnetDataOutput : public DataOutputInterface {
+ public:
+ OmnetDataOutput();
+ virtual ~OmnetDataOutput();
+
+ virtual void Output(DataCollector &dc);
+
+ void SetFilePrefix(const std::string prefix);
+ std::string GetFilePrefix() const;
+
+ protected:
+ virtual void DoDispose();
+
+ private:
+ class OmnetOutputCallback : public DataOutputCallback {
+ public:
+ OmnetOutputCallback(std::ostream *scalar);
+
+ void OutputSingleton(std::string key,
+ std::string variable,
+ int val);
+
+ void OutputSingleton(std::string key,
+ std::string variable,
+ uint32_t val);
+
+ void OutputSingleton(std::string key,
+ std::string variable,
+ double val);
+
+ void OutputSingleton(std::string key,
+ std::string variable,
+ std::string val);
+
+ void OutputSingleton(std::string key,
+ std::string variable,
+ Time val);
+
+ private:
+ std::ostream *m_scalar;
+ // end class OmnetOutputCallback
+ };
+
+ std::string m_filePrefix;
+ // end class OmnetDataOutput
+ };
+
+ // end namespace ns3
+};
+
+
+#endif // __OMNET_DATA_OUTPUT_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/stats/packet-data-calculators.cc Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,118 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Drexel University
+ *
+ * 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: Joe Kopena (tjkopena@cs.drexel.edu)
+ */
+
+#include "ns3/log.h"
+#include "ns3/packet.h"
+#include "ns3/mac48-address.h"
+
+#include "basic-data-calculators.h"
+#include "packet-data-calculators.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE("PacketDataCalculators");
+
+
+//--------------------------------------------------------------
+//----------------------------------------------
+PacketCounterCalculator::PacketCounterCalculator()
+{
+ NS_LOG_FUNCTION_NOARGS();
+}
+
+PacketCounterCalculator::~PacketCounterCalculator()
+{
+ NS_LOG_FUNCTION_NOARGS();
+}
+void
+PacketCounterCalculator::DoDispose(void)
+{
+ NS_LOG_FUNCTION_NOARGS();
+
+ CounterCalculator<uint32_t>::DoDispose();
+ // PacketCounterCalculator::DoDispose
+}
+
+void
+PacketCounterCalculator::PacketUpdate(std::string path,
+ Ptr<const Packet> packet)
+{
+ NS_LOG_FUNCTION_NOARGS();
+
+ CounterCalculator<uint32_t>::Update();
+
+ // PacketCounterCalculator::Update
+}
+void
+PacketCounterCalculator::FrameUpdate(std::string path,
+ Ptr<const Packet> packet,
+ Mac48Address realto)
+{
+ NS_LOG_FUNCTION_NOARGS();
+
+ CounterCalculator<uint32_t>::Update();
+
+ // PacketCounterCalculator::Update
+}
+
+
+
+
+//--------------------------------------------------------------
+//----------------------------------------------
+PacketSizeMinMaxAvgTotalCalculator::PacketSizeMinMaxAvgTotalCalculator()
+{
+ NS_LOG_FUNCTION_NOARGS();
+}
+
+PacketSizeMinMaxAvgTotalCalculator::~PacketSizeMinMaxAvgTotalCalculator()
+{
+ NS_LOG_FUNCTION_NOARGS();
+}
+void
+PacketSizeMinMaxAvgTotalCalculator::DoDispose(void)
+{
+ NS_LOG_FUNCTION_NOARGS();
+
+ MinMaxAvgTotalCalculator<uint32_t>::DoDispose();
+ // end PacketSizeMinMaxAvgTotalCalculator::DoDispose
+}
+
+void
+PacketSizeMinMaxAvgTotalCalculator::PacketUpdate(std::string path,
+ Ptr<const Packet> packet)
+{
+ NS_LOG_FUNCTION_NOARGS();
+
+ MinMaxAvgTotalCalculator<uint32_t>::Update(packet->GetSize());
+
+ // end PacketSizeMinMaxAvgTotalCalculator::Update
+}
+void
+PacketSizeMinMaxAvgTotalCalculator::FrameUpdate(std::string path,
+ Ptr<const Packet> packet,
+ Mac48Address realto)
+{
+ NS_LOG_FUNCTION_NOARGS();
+
+ MinMaxAvgTotalCalculator<uint32_t>::Update(packet->GetSize());
+
+ // end PacketSizeMinMaxAvgTotalCalculator::Update
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/stats/packet-data-calculators.h Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,68 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Drexel University
+ *
+ * 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: Joe Kopena (tjkopena@cs.drexel.edu)
+ */
+
+#ifndef __PACKET_DATA_CALCULATORS_H__
+#define __PACKET_DATA_CALCULATORS_H__
+
+#include "ns3/packet.h"
+#include "ns3/mac48-address.h"
+
+#include "data-calculator.h"
+
+namespace ns3 {
+
+ class PacketCounterCalculator : public CounterCalculator<uint32_t> {
+ public:
+ PacketCounterCalculator();
+ virtual ~PacketCounterCalculator();
+
+ void PacketUpdate(std::string path, Ptr<const Packet> packet);
+ void FrameUpdate(std::string path, Ptr<const Packet> packet,
+ Mac48Address realto);
+
+ protected:
+ virtual void DoDispose(void);
+
+ // end class PacketCounterCalculator
+ };
+
+
+ class PacketSizeMinMaxAvgTotalCalculator :
+ public MinMaxAvgTotalCalculator<uint32_t> {
+ public:
+ PacketSizeMinMaxAvgTotalCalculator();
+ virtual ~PacketSizeMinMaxAvgTotalCalculator();
+
+ void PacketUpdate(std::string path, Ptr<const Packet> packet);
+ void FrameUpdate(std::string path, Ptr<const Packet> packet,
+ Mac48Address realto);
+
+ protected:
+ virtual void DoDispose(void);
+
+ // end class PacketSizeMinMaxAvgTotalCalculator
+ };
+
+
+ // end namespace ns3
+};
+
+
+#endif // __PACKET_DATA_CALCULATORS_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/stats/sqlite-data-output.cc Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,238 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Drexel University
+ *
+ * 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: Joe Kopena (tjkopena@cs.drexel.edu)
+ */
+
+#include <sstream>
+
+#include <sqlite3.h>
+
+#include "ns3/log.h"
+#include "ns3/nstime.h"
+
+#include "data-collector.h"
+#include "data-calculator.h"
+#include "sqlite-data-output.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE("SqliteDataOutput");
+
+
+//--------------------------------------------------------------
+//----------------------------------------------
+SqliteDataOutput::SqliteDataOutput() :
+ m_dbFile("data.db")
+{
+ NS_LOG_FUNCTION_NOARGS();
+}
+SqliteDataOutput::~SqliteDataOutput()
+{
+ NS_LOG_FUNCTION_NOARGS();
+}
+void
+SqliteDataOutput::DoDispose()
+{
+ NS_LOG_FUNCTION_NOARGS();
+
+ DataOutputInterface::DoDispose();
+ // end SqliteDataOutput::DoDispose
+}
+
+void
+SqliteDataOutput::SetDBFile(const std::string file)
+{
+ m_dbFile = file;
+}
+std::string
+SqliteDataOutput::GetDBFile() const
+{
+ return m_dbFile;
+}
+
+int
+SqliteDataOutput::Exec(std::string exe) {
+ int res;
+ char **result;
+ int nrows, ncols;
+ char *errMsg = 0;
+
+ NS_LOG_INFO("executing '" << exe << "'");
+
+ res = sqlite3_get_table(m_db,
+ exe.c_str(),
+ &result, &nrows, &ncols,
+ &errMsg);
+
+ if (res != SQLITE_OK) {
+ NS_LOG_ERROR("sqlite3 error: \"" << errMsg << "\"");
+ /*
+ } else {
+ // std::cout << "nrows " << nrows << " ncols " << ncols << std::endl;
+
+ if (nrows > 0) {
+ for (int i = 0; i < ncols; i++) {
+ std::cout << " " << result[i];
+ }
+ std::cout << std::endl;
+
+ for (int r = 1; r <= nrows; r++) {
+ for (int c = 0; c < ncols; c++) {
+ std::cout << " " << result[(r*ncols)+c];
+ }
+ std::cout << std::endl;
+ }
+ std::cout << std::endl;
+ }
+ */
+ }
+
+ sqlite3_free_table(result);
+ return res;
+
+ // end SqliteDataOutput::Exec
+}
+
+//----------------------------------------------
+void
+SqliteDataOutput::Output(DataCollector &dc)
+{
+
+ if (sqlite3_open(m_dbFile.c_str(), &m_db)) {
+ NS_LOG_ERROR("Could not open sqlite3 database \"" << m_dbFile << "\"");
+ NS_LOG_ERROR("sqlite3 error \"" << sqlite3_errmsg(m_db) << "\"");
+ sqlite3_close(m_db);
+ // TODO: Better error reporting, management!
+ return;
+ }
+
+ std::string run = dc.GetRunLabel();
+
+ Exec("create table if not exists Experiments (run, experiment, strategy, input, description text)");
+ Exec("insert into Experiments (run,experiment,strategy,input,description) values ('" +
+ run + "', '" +
+ dc.GetExperimentLabel() + "', '" +
+ dc.GetStrategyLabel() + "', '" +
+ dc.GetInputLabel() + "', '" +
+ dc.GetDescription() + "')");
+
+ Exec("create table if not exists Metadata ( run text, key text, value)");
+
+ for (MetadataList::iterator i = dc.MetadataBegin();
+ i != dc.MetadataEnd(); i++) {
+ std::pair<std::string, std::string> blob = (*i);
+ Exec("insert into Metadata (run,key,value) values ('" +
+ run + "', '" +
+ blob.first + "', '" +
+ blob.second + "')");
+ }
+
+ SqliteOutputCallback callback(this, run);
+ for (DataCalculatorList::iterator i = dc.DataCalculatorBegin();
+ i != dc.DataCalculatorEnd(); i++) {
+ (*i)->Output(callback);
+ }
+
+ sqlite3_close(m_db);
+
+ // end SqliteDataOutput::Output
+}
+
+SqliteDataOutput::SqliteOutputCallback::SqliteOutputCallback
+ (Ptr<SqliteDataOutput> owner, std::string run) :
+ m_owner(owner),
+ m_runLabel(run)
+{
+
+ m_owner->Exec("create table if not exists Singletons ( run text, name text, variable text, value )");
+
+ // end SqliteDataOutput::SqliteOutputCallback::SqliteOutputCallback
+}
+
+void
+SqliteDataOutput::SqliteOutputCallback::OutputSingleton(std::string key,
+ std::string variable,
+ int val)
+{
+
+ std::stringstream sstr;
+ sstr << "insert into Singletons (run,name,variable,value) values ('" <<
+ m_runLabel << "', '" <<
+ key << "', '" <<
+ variable << "', " <<
+ val << ")";
+ m_owner->Exec(sstr.str());
+
+ // end SqliteDataOutput::SqliteOutputCallback::OutputSingleton
+}
+void
+SqliteDataOutput::SqliteOutputCallback::OutputSingleton(std::string key,
+ std::string variable,
+ uint32_t val)
+{
+ std::stringstream sstr;
+ sstr << "insert into Singletons (run,name,variable,value) values ('" <<
+ m_runLabel << "', '" <<
+ key << "', '" <<
+ variable << "', " <<
+ val << ")";
+ m_owner->Exec(sstr.str());
+ // end SqliteDataOutput::SqliteOutputCallback::OutputSingleton
+}
+void
+SqliteDataOutput::SqliteOutputCallback::OutputSingleton(std::string key,
+ std::string variable,
+ double val)
+{
+ std::stringstream sstr;
+ sstr << "insert into Singletons (run,name,variable,value) values ('" <<
+ m_runLabel << "', '" <<
+ key << "', '" <<
+ variable << "', " <<
+ val << ")";
+ m_owner->Exec(sstr.str());
+ // end SqliteDataOutput::SqliteOutputCallback::OutputSingleton
+}
+void
+SqliteDataOutput::SqliteOutputCallback::OutputSingleton(std::string key,
+ std::string variable,
+ std::string val)
+{
+ std::stringstream sstr;
+ sstr << "insert into Singletons (run,name,variable,value) values ('" <<
+ m_runLabel << "', '" <<
+ key << "', '" <<
+ variable << "', '" <<
+ val << "')";
+ m_owner->Exec(sstr.str());
+ // end SqliteDataOutput::SqliteOutputCallback::OutputSingleton
+}
+void
+SqliteDataOutput::SqliteOutputCallback::OutputSingleton(std::string key,
+ std::string variable,
+ Time val)
+{
+ std::stringstream sstr;
+ sstr << "insert into Singletons (run,name,variable,value) values ('" <<
+ m_runLabel << "', '" <<
+ key << "', '" <<
+ variable << "', " <<
+ val << ")";
+ m_owner->Exec(sstr.str());
+ // end SqliteDataOutput::SqliteOutputCallback::OutputSingleton
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/stats/sqlite-data-output.h Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,93 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Drexel University
+ *
+ * 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: Joe Kopena (tjkopena@cs.drexel.edu)
+ */
+
+#ifndef __SQLITE_DATA_OUTPUT_H__
+#define __SQLITE_DATA_OUTPUT_H__
+
+#include "ns3/nstime.h"
+
+#include "data-output-interface.h"
+
+#define STATS_HAS_SQLITE3
+
+class sqlite3;
+
+namespace ns3 {
+
+ //------------------------------------------------------------
+ //--------------------------------------------
+ class SqliteDataOutput : public DataOutputInterface {
+ public:
+ SqliteDataOutput();
+ virtual ~SqliteDataOutput();
+
+ virtual void Output(DataCollector &dc);
+
+ void SetDBFile(const std::string file);
+ std::string GetDBFile() const;
+
+ protected:
+ virtual void DoDispose();
+
+ private:
+ class SqliteOutputCallback : public DataOutputCallback {
+ public:
+ SqliteOutputCallback(Ptr<SqliteDataOutput> owner, std::string run);
+
+ void OutputSingleton(std::string key,
+ std::string variable,
+ int val);
+
+ void OutputSingleton(std::string key,
+ std::string variable,
+ uint32_t val);
+
+ void OutputSingleton(std::string key,
+ std::string variable,
+ double val);
+
+ void OutputSingleton(std::string key,
+ std::string variable,
+ std::string val);
+
+ void OutputSingleton(std::string key,
+ std::string variable,
+ Time val);
+
+ private:
+ Ptr<SqliteDataOutput> m_owner;
+ std::string m_runLabel;
+
+ // end class SqliteOutputCallback
+ };
+
+
+ sqlite3 *m_db;
+ int Exec(std::string exe);
+
+ std::string m_dbFile;
+ // end class SqliteDataOutput
+ };
+
+ // end namespace ns3
+};
+
+
+#endif // __SQLITE_DATA_OUTPUT_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/stats/time-data-calculators.cc Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,81 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Drexel University
+ *
+ * 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: Joe Kopena (tjkopena@cs.drexel.edu)
+ */
+
+#include "ns3/log.h"
+#include "ns3/nstime.h"
+
+#include "time-data-calculators.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE("TimeDataCalculators");
+
+
+//--------------------------------------------------------------
+//----------------------------------------------
+TimeMinMaxAvgTotalCalculator::TimeMinMaxAvgTotalCalculator()
+{
+ m_count = 0;
+}
+TimeMinMaxAvgTotalCalculator::~TimeMinMaxAvgTotalCalculator()
+{
+}
+void
+TimeMinMaxAvgTotalCalculator::DoDispose(void)
+{
+ DataCalculator::DoDispose();
+ // TimeMinMaxAvgTotalCalculator::DoDispose
+}
+
+void
+TimeMinMaxAvgTotalCalculator::Update(const Time i)
+{
+ if (m_enabled) {
+ if (m_count) {
+ m_total += i;
+
+ if (i < m_min)
+ m_min = i;
+
+ if (i > m_max)
+ m_max = i;
+
+ } else {
+ m_min = i;
+ m_max = i;
+ m_total = i;
+ }
+ m_count++;
+
+ }
+ // end TimeMinMaxAvgTotalCalculator::Update
+}
+void
+TimeMinMaxAvgTotalCalculator::Output(DataOutputCallback &callback) const
+{
+ callback.OutputSingleton(m_key, "count", m_count);
+ if (m_count > 0) {
+ callback.OutputSingleton(m_key, "total", m_total);
+ callback.OutputSingleton(m_key, "average", m_total/Scalar(m_count));
+ callback.OutputSingleton(m_key, "max", m_max);
+ callback.OutputSingleton(m_key, "min", m_min);
+ }
+ // end TimeMinMaxAvgTotalCalculator::Output
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/stats/time-data-calculators.h Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,62 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Drexel University
+ *
+ * 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: Joe Kopena (tjkopena@cs.drexel.edu)
+ */
+
+#ifndef __TIME_DATA_CALCULATORS_H__
+#define __TIME_DATA_CALCULATORS_H__
+
+#include "ns3/nstime.h"
+
+#include "data-calculator.h"
+#include "data-output-interface.h"
+
+namespace ns3 {
+
+ //------------------------------------------------------------
+ //--------------------------------------------
+ /**
+ * Unfortunately, templating the base MinMaxAvgTotalCalculator to
+ * operate over Time values isn't straightforward. The main issues
+ * are setting the maximum value, which can be worked around easily
+ * as it done here, and dividing to get the average, which is not as
+ * easily worked around.
+ */
+ class TimeMinMaxAvgTotalCalculator : public DataCalculator {
+ public:
+ TimeMinMaxAvgTotalCalculator();
+ virtual ~TimeMinMaxAvgTotalCalculator();
+
+ void Update(const Time i);
+
+ virtual void Output(DataOutputCallback &callback) const;
+
+ protected:
+ virtual void DoDispose(void);
+
+ uint32_t m_count;
+ Time m_total, m_min, m_max;
+
+ // end class TimeMinMaxAvgTotalCalculator
+ };
+
+ // end namespace ns3
+};
+
+
+#endif // __TIME_DATA_CALCULATORS_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/stats/wscript Fri Aug 29 13:22:09 2008 -0400
@@ -0,0 +1,36 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def configure(conf):
+ e = conf.create_library_configurator()
+ e.mandatory = False
+ e.name = 'sqlite3'
+ e.define = 'SQLITE3'
+ e.uselib = 'SQLITE3'
+ conf.env['SQLITE_STATS'] = e.run()
+
+def build(bld):
+ obj = bld.create_ns3_module('stats', ['node'])
+ obj.source = [
+ 'data-calculator.cc',
+ 'packet-data-calculators.cc',
+ 'time-data-calculators.cc',
+ 'data-output-interface.cc',
+ 'omnet-data-output.cc',
+ 'data-collector.cc',
+ ]
+ headers = bld.create_obj('ns3header')
+ headers.module = 'stats'
+ headers.source = [
+ 'data-calculator.h',
+ 'packet-data-calculators.h',
+ 'time-data-calculators.h',
+ 'basic-data-calculators.h',
+ 'data-output-interface.h',
+ 'omnet-data-output.h',
+ 'data-collector.h',
+ ]
+
+ if bld.env()['SQLITE_STATS']:
+ headers.source.append('sqlite-data-output.h')
+ obj.source.append('sqlite-data-output.cc')
+ obj.uselib = 'SQLITE3'
--- a/src/contrib/wscript Fri Aug 29 14:56:24 2008 +0100
+++ b/src/contrib/wscript Fri Aug 29 13:22:09 2008 -0400
@@ -6,7 +6,7 @@
check.uselib = 'GTK_CONFIG_STORE'
check.mandatory = False
conf.env['ENABLE_GTK_CONFIG_STORE'] = check.run()
-
+ conf.sub_config('stats')
def build(bld):
module = bld.create_ns3_module('contrib', ['simulator'])
--- a/src/wscript Fri Aug 29 14:56:24 2008 +0100
+++ b/src/wscript Fri Aug 29 13:22:09 2008 -0400
@@ -28,6 +28,7 @@
'devices/wifi',
'helper',
'devices/bridge',
+ 'contrib/stats',
)
def set_options(opt):