###################################################################################
###################################################################################
#####     Simulace zavislosti zpozdeni na poctu skoku a delce trasy           #####      
#####            Jiri Balej, diplomova prace, 21.5.2010                       #####           
###################################################################################
###################################################################################

# vytvoreni instance simulatoru
remove-all-packet-headers;            # odstrani hlavicky paketu
add-packet-header IP TCP;             # prida TCP/IP hlavicky

set ns [new Simulator]

# vytvoreni trasovaciho souboru
set myTRACE [open out.tr w]
$ns trace-all $myTRACE

# vytvoreni souboru pro NAM
set myNAM [open out.nam w]
$ns namtrace-all $myNAM

###################################################################################
#####                      Zakladni nastaveni				      #####
###################################################################################

# pocet routeru v simulaci - ctverec  
set routers 20
# celkova delka trasy (jednotlive useky jsou kratsi v souctu, ale davaji celou delku)
set delkakm 20000		

# nastaveni doby zpozdeni smerovacu (v ms)
set routerMin 0.085	
set routerMax 0.085

# parametry TCP spojeni 
set paket 64		
set ttl 255		

# parametry linek
set bandwidth 10Gb	

# definice barev
$ns color 1 red
$ns color 2 blue

###################################################################################
###################################################################################

# vypocet dilcich delek pro prepocet na zpozdeni
set linkdelay 0
# nejmensi delka rozdelene celkove vzdalenosti
set konst [expr $delkakm * 2 / (($routers+1)*($routers+2))]
# prepocet kilometru na zpozdeni
set delka [expr $konst * 0.00000513]

# generator nahodneho (rovnomerneho) rozlozeni zpozdeni
global defaultRNG
$defaultRNG seed 999

 set routerDelay [new RandomVariable/Uniform];
 $routerDelay set min_ $routerMin
 $routerDelay set max_ $routerMax

# definice zdroje
set zdroj [$ns node]

# definice smerovacu (delay box) a linek mezi uzly
for {set i 1} {$i <= $routers} {incr i} {
	# linkova vrstva
	set r($i) [$ns DelayBox]
	$r($i) shape box
	# kazda dalsi linka je tak dlouha jak predchozi zvysena o konstantu
	set linkdelay [expr $linkdelay + $delka]
	if {$i==1} { 
		$ns duplex-link $zdroj $r($i) $bandwidth $linkdelay DropTail
	} else {
		$ns duplex-link $r([expr $i-1]) $r($i) $bandwidth $linkdelay DropTail
		}
}
# definice cile a linky k nemu
set cil [$ns node]
set linkdelay [expr $linkdelay + $delka]
$ns duplex-link $r($routers) $cil $bandwidth $linkdelay DropTail

# parametry delay boxu (smerovace)
for {set i 1} {$i <= $routers} {incr i} {
	$r($i) add-rule [$zdroj id] [$cil id] $routerDelay
	$r($i) set-delay-file "routers.out"
}

# zdroj a cil provozu
set src [new Agent/TCP/FullTcp]
set sink [new Agent/TCP/FullTcp]
$src set packetSize_ $paket
$src set ttl_ $ttl
$src set fid_ 1
$sink set fid_ 1

# pripojeni provozu k uzlum
$ns attach-agent $zdroj $src
$ns attach-agent $cil $sink

# spojeni zdroje s cilem
$ns connect $src $sink
$sink listen


# Definice procedury finish, spousti se v zdy na konci simulace
proc finish {} {
# definovano mimo proceduru (globalni promene)
global ns myTRACE myNAM konst
$ns flush-trace
close $myTRACE
close $myNAM
#AWK kod pro zpracovani zaznamenanych dat
# vytvori dvourozmerne pole dat pro 3D graf
	set awkCode {   
	    {	   
	    if ($1 == "+" && $12 == "0") {
		# cas odeslani paketu z jednotlivych uzlu ulozen jako pole
	    	cas[$3] = $2;
	    }
	    else if ($1 == "r" && $12 == "0") {
		distance = 0;
		routers = $3;
		# vypocet poctu skoku a delky linky
		for (i=$3; i>=0; i--) {
			routerhops = $3-i;
			distance = distance+i+1;
			# ulozeni zpozdeni mezi uzly do dvourozmerneho pol
			if (pocet[routerhops,distance] == 0 ) {
					delay[routerhops,distance] = $2 - cas[i];
					pocet[routerhops,distance] = 1;		
				} else {
			# pricteni doby zpozdeni k jednou zjistene dobe zpozdeni - napr pro 2 routery a 500km (ne km ale konstanta)
					delay[routerhops,distance] = delay[routerhops,switchhops] + $2 - cas[i];
					pocet[routerhops,distance]++;
				}
			}
	   	 } 
	}
	END {
	    for (i=0; i<=routers; i++) {
		# slouzitejsi pruchod polem pro konstantu vzdalenosti
		min = (i+1)*(i/2+1);
		max = (i+1)*(routers+1-i/2);
		for (j=min; j<=max; j=j+i+1) {	
			# pro kazdou kombinaci skuku a delky trasz vypocteno zpozdeni a ulozeno do souboru
			zpozdeni = delay[i,j]/pocet[i,j];
			delka = j*k;
			print i, delka, zpozdeni >> "routersLenght.tr" ;	
			if (i==0) {
			print delka, zpozdeni >> "lenght.tr" ;			
			}
		}
	     }
	}
  }
	# pripraveni souboru pro zapis dat
	  exec rm -f routersLenght.tr lenght.tr
  	  exec touch routersLenght.tr lenght.tr

	# spusteni awk skriptu s konstantou pro vypocet delky v km
  	  exec awk -v "k=$konst" $awkCode out.tr 

	# otevreni grafu - zakomentovane radky nefunguji dokonale...
	#exec xyz routersLenght.tr -x_range 0 10 -y_range 0 21 -z_range 0 0.04 
	#exec solidxyz routersLenght.tr 
	#exec contour routersLenght.tr 
	exec xgraph -x delka_trasy_(km) -y zpozdeni_(s) lenght.tr -geometry 800x400 &
	exec nam out.nam &
	exit 0
}
	# nastaveni casovace
	$ns at 0.5 "$src advance 1000"
	$ns at 5 "finish"

# spusteni simulace
$ns run
