# HG changeset patch # User tjkopena@cs.drexel.edu # Date 1220030529 14400 # Node ID 44b0bc6817c67094a6f1d7ee66f0ff6cc992249e # Parent 728eb3f583b39612cd7b6c938db85423566ce576 Stats module and example merged in. diff -r 728eb3f583b3 -r 44b0bc6817c6 examples/stats/README --- /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 diff -r 728eb3f583b3 -r 44b0bc6817c6 examples/stats/data.db Binary file examples/stats/data.db has changed diff -r 728eb3f583b3 -r 44b0bc6817c6 examples/stats/wifi-default.data --- /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 diff -r 728eb3f583b3 -r 44b0bc6817c6 examples/stats/wifi-default.eps --- /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 diff -r 728eb3f583b3 -r 44b0bc6817c6 examples/stats/wifi-example-apps.cc --- /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 + * + * 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 + +#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 () + .AddConstructor () + .AddAttribute ("PacketSize", "The size of packets transmitted.", + UintegerValue(64), + MakeUintegerAccessor(&Sender::m_pktSize), + MakeUintegerChecker(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()) + .AddAttribute("NumPackets", "Total number of packets to send.", + UintegerValue(30), + MakeUintegerAccessor(&Sender::m_numPkts), + MakeUintegerChecker(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 = GetNode()->GetObject + (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 = Create(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 () + .AddConstructor () + .AddAttribute("Port", "Listening port.", + UintegerValue(1603), + MakeUintegerAccessor(&Receiver::m_port), + MakeUintegerChecker()) + ; + 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 = GetNode()->GetObject + (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 > ()); + } + + // end Receiver::StopApplication +} + +void +Receiver::SetCounter(Ptr > calc) +{ + m_calc = calc; + // end Receiver::SetCounter +} +void +Receiver::SetDelayTracker(Ptr delay) +{ + m_delay = delay; + // end Receiver::SetDelayTracker +} + +void +Receiver::Receive(Ptr socket) +{ + // NS_LOG_FUNCTION (this << socket << packet << from); + + Ptr 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 () + .AddConstructor () + .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; +} diff -r 728eb3f583b3 -r 44b0bc6817c6 examples/stats/wifi-example-apps.h --- /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 + * + * 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 m_socket; + EventId m_sendEvent; + + TracedCallback > m_txTrace; + + uint32_t m_count; + + // end class Sender +}; + + + + +//------------------------------------------------------ +class Receiver: public Application { +public: + static TypeId GetTypeId(void); + Receiver(); + virtual ~Receiver(); + + void SetCounter(Ptr > calc); + void SetDelayTracker(Ptr delay); + +protected: + virtual void DoDispose(void); + +private: + virtual void StartApplication(void); + virtual void StopApplication(void); + + void Receive(Ptr socket); + + Ptr m_socket; + + uint32_t m_port; + + Ptr > m_calc; + Ptr 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 +}; diff -r 728eb3f583b3 -r 44b0bc6817c6 examples/stats/wifi-example-db.sh --- /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" diff -r 728eb3f583b3 -r 44b0bc6817c6 examples/stats/wifi-example-sim.cc --- /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 + * + * 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 + +#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 > datac, + std::string path, Ptr 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 positionAlloc = + CreateObject(); + 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 appSource = NodeList::GetNode(0); + Ptr sender = CreateObject(); + appSource->AddApplication(sender); + sender->Start(Seconds(1)); + + Ptr appSink = NodeList::GetNode(1); + Ptr receiver = CreateObject(); + 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 > totalTx = + CreateObject >(); + 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 totalRx = + CreateObject(); + 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 appTx = + CreateObject(); + 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 > appRx = + CreateObject >(); + appRx->SetKey("receiver-rx-packets"); + receiver->SetCounter(appRx); + data.AddDataCalculator(appRx); + + + + + /** + * Just to show this is here... + Ptr > test = + CreateObject >(); + 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 appTxPkts = + CreateObject(); + 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 delayStat = + CreateObject(); + 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 output = 0; + if (format == "omnet") { + NS_LOG_INFO("Creating omnet formatted data output."); + output = CreateObject(); + } else if (format == "db") { + #ifdef STATS_HAS_SQLITE3 + NS_LOG_INFO("Creating sqlite formatted data output."); + output = CreateObject(); + #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 +} diff -r 728eb3f583b3 -r 44b0bc6817c6 examples/stats/wifi-example.gnuplot --- /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" diff -r 728eb3f583b3 -r 44b0bc6817c6 examples/stats/wscript --- /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'] diff -r 728eb3f583b3 -r 44b0bc6817c6 examples/wscript --- 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') diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/stats/basic-data-calculators.h --- /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 + 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 + MinMaxAvgTotalCalculator::MinMaxAvgTotalCalculator() + { + m_count = 0; + m_total = 0; + m_min = ~0; + m_max = 0; + } + + template + MinMaxAvgTotalCalculator::~MinMaxAvgTotalCalculator() + { + } + template + void + MinMaxAvgTotalCalculator::DoDispose(void) + { + DataCalculator::DoDispose(); + // MinMaxAvgTotalCalculator::DoDispose + } + + template + void + MinMaxAvgTotalCalculator::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 + void + MinMaxAvgTotalCalculator::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 + 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 + CounterCalculator::CounterCalculator() : + m_count(0) + { + } + + template + CounterCalculator::~CounterCalculator() + { + } + template + void + CounterCalculator::DoDispose(void) + { + DataCalculator::DoDispose(); + // CounterCalculator::DoDispose + } + + template + void + CounterCalculator::Update() + { + if (m_enabled) { + m_count++; + } + // end CounterCalculator::Update + } + + template + void + CounterCalculator::Update(const T i) + { + if (m_enabled) { + m_count += i; + } + // end CounterCalculator::Update + } + + template + T + CounterCalculator::GetCount() const + { + return m_count; + // end CounterCalculator::GetCount + } + + template + void + CounterCalculator::Output(DataOutputCallback &callback) const + { + callback.OutputSingleton(m_key, "count", m_count); + // end CounterCalculator::Output + } + + // end namespace ns3 +}; + + +#endif // __BASIC_DATA_CALCULATORS_H__ diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/stats/data-calculator.cc --- /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 +} diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/stats/data-calculator.h --- /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__ diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/stats/data-collector.cc --- /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 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 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 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 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 +} diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/stats/data-collector.h --- /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 +#include + +#include "ns3/object.h" + +namespace ns3 { + + class DataCalculator; + + //------------------------------------------------------------ + //-------------------------------------------- + typedef std::list > DataCalculatorList; + typedef std::list > 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 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__ diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/stats/data-output-interface.cc --- /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 +} diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/stats/data-output-interface.h --- /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__ diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/stats/omnet-data-output.cc --- /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 + +#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 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 +} diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/stats/omnet-data-output.h --- /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__ diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/stats/packet-data-calculators.cc --- /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::DoDispose(); + // PacketCounterCalculator::DoDispose +} + +void +PacketCounterCalculator::PacketUpdate(std::string path, + Ptr packet) +{ + NS_LOG_FUNCTION_NOARGS(); + + CounterCalculator::Update(); + + // PacketCounterCalculator::Update +} +void +PacketCounterCalculator::FrameUpdate(std::string path, + Ptr packet, + Mac48Address realto) +{ + NS_LOG_FUNCTION_NOARGS(); + + CounterCalculator::Update(); + + // PacketCounterCalculator::Update +} + + + + +//-------------------------------------------------------------- +//---------------------------------------------- +PacketSizeMinMaxAvgTotalCalculator::PacketSizeMinMaxAvgTotalCalculator() +{ + NS_LOG_FUNCTION_NOARGS(); +} + +PacketSizeMinMaxAvgTotalCalculator::~PacketSizeMinMaxAvgTotalCalculator() +{ + NS_LOG_FUNCTION_NOARGS(); +} +void +PacketSizeMinMaxAvgTotalCalculator::DoDispose(void) +{ + NS_LOG_FUNCTION_NOARGS(); + + MinMaxAvgTotalCalculator::DoDispose(); + // end PacketSizeMinMaxAvgTotalCalculator::DoDispose +} + +void +PacketSizeMinMaxAvgTotalCalculator::PacketUpdate(std::string path, + Ptr packet) +{ + NS_LOG_FUNCTION_NOARGS(); + + MinMaxAvgTotalCalculator::Update(packet->GetSize()); + + // end PacketSizeMinMaxAvgTotalCalculator::Update +} +void +PacketSizeMinMaxAvgTotalCalculator::FrameUpdate(std::string path, + Ptr packet, + Mac48Address realto) +{ + NS_LOG_FUNCTION_NOARGS(); + + MinMaxAvgTotalCalculator::Update(packet->GetSize()); + + // end PacketSizeMinMaxAvgTotalCalculator::Update +} diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/stats/packet-data-calculators.h --- /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 { + public: + PacketCounterCalculator(); + virtual ~PacketCounterCalculator(); + + void PacketUpdate(std::string path, Ptr packet); + void FrameUpdate(std::string path, Ptr packet, + Mac48Address realto); + + protected: + virtual void DoDispose(void); + + // end class PacketCounterCalculator + }; + + + class PacketSizeMinMaxAvgTotalCalculator : + public MinMaxAvgTotalCalculator { + public: + PacketSizeMinMaxAvgTotalCalculator(); + virtual ~PacketSizeMinMaxAvgTotalCalculator(); + + void PacketUpdate(std::string path, Ptr packet); + void FrameUpdate(std::string path, Ptr packet, + Mac48Address realto); + + protected: + virtual void DoDispose(void); + + // end class PacketSizeMinMaxAvgTotalCalculator + }; + + + // end namespace ns3 +}; + + +#endif // __PACKET_DATA_CALCULATORS_H__ diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/stats/sqlite-data-output.cc --- /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 + +#include + +#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 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 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 +} diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/stats/sqlite-data-output.h --- /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 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 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__ diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/stats/time-data-calculators.cc --- /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 +} diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/stats/time-data-calculators.h --- /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__ diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/stats/wscript --- /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' diff -r 728eb3f583b3 -r 44b0bc6817c6 src/contrib/wscript --- 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']) diff -r 728eb3f583b3 -r 44b0bc6817c6 src/wscript --- 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):