#simulation3.tcl

set ns [new Simulator]

#Istanti di inizio e fine traffico 
set startTime 0.0
set startTimeHTTP0 0.0
set startTimeHTTP1 0.1
set startTimeHTTP2 0.5
set startTimeHTTP3 0.3
set startTimeHTTP4 0.6
set finishTime 300

#Apertura dei files di output
set nf [open simulation3.nam w]
#$ns namtrace-all $nf

set tf0 [open link.tr w]
set tf1 [open lcoda.tr w]
set tf2 [open drops.tr w]
set tf3 [open barrivals.tr w]
set tf4 [open bdepartures.tr w]
set log1 [open "http1.log" w]
set log2 [open "http2.log" w]

set totale 0

proc record {} {
        global tf3 tf4 queue4_5 totale finishTime rate
        set ns [Simulator instance]
        set time 1.0
        set arrivati [$queue4_5 set barrivals_]
        set partiti [$queue4_5 set bdepartures_]
        set totale [expr $totale+$partiti]
	set now [$ns now]
        puts $tf3 "$now [expr $arrivati/$time]"
        puts $tf4 "$now [expr $partiti/$time]"
        #Riazzero le variabili arrivati e partiti prima di richiamare la procedura
        $queue4_5 set barrivals_ 0
        $queue4_5 set bdepartures_ 0
        #Stampo su stdout la banda media occupata 
	if { $now == [expr $finishTime-$time] } {
	   set medio [expr $totale/$now]
	   set perc_banda [expr $medio*800/$rate]
	   puts "\nIl numero medio di bytes/s sul link ex-OMI (n4) Rettorato (n5) e': $medio" 
	   puts "\nLa percentuale media di banda occupata sul link e': $perc_banda %\n"
	}
        $ns at [expr $now+$time] "record" 
     
}

proc record_coda {} {
        global tf1 tf2 queue4_5 
        set ns [Simulator instance]
        set time 0.01
        set lunghezza [$queue4_5 set pkts_]
	set drops [$queue4_5 set pdrops_]
        set now [$ns now]
	puts $tf1 "$now $lunghezza"
	puts $tf2 "$now $drops"
        $ns at [expr $now+$time] "record_coda" 
     
}

#Procedure che avviano le connessioni http
proc start-connection0 { } {
              global ns server2 cache2 client0 
              $client0 connect $cache2
	      $cache2 connect $server2
              $client0 start-session $cache2 $server2
}
  
proc start-connection1 { } {
              global ns server2 cache2 client1 
              $client1 connect $cache2
	      $cache2 connect $server2
              $client1 start-session $cache2 $server2
}

proc start-connection2 { } {
              global ns server2 cache2 client2 
              $client2 connect $cache2
	      $cache2 connect $server2
              $client2 start-session $cache2 $server2
}

proc start-connection3 { } {
              global ns server2 cache2 client3 
              $client3 connect $cache2
	      $cache2 connect $server2
              $client3 start-session $cache2 $server2
}

proc start-connection4 { } {
              global ns server1 cache1 client4 
              $client4 connect $cache1
	      $cache1 connect $server1
              $client4 start-session $cache1 $server1
}              
proc finish {} {
        global ns nf 
	global log1 log2
        global tf0 tf1 tf2 tf3 tf4
        $ns flush-trace
	flush $log1
	flush $log2
        #Chiudo i trace files
        close $nf
	close $tf0
	close $tf1
	close $tf2
        close $tf3
        close $tf4
	close $log1
	close $log2
        #Eseguo nam e xgraph
        #exec nam simulation3.nam &
        exec xgraph lcoda.tr drops.tr -geometry 640x400 &
        exec xgraph barrivals.tr -geometry 640x400 &
        exec xgraph bdepartures.tr -geometry 640x400 &
	exit 0
}

#Creazione topologia
for {set i 0} {$i < 14} {incr i} {
	set n($i) [$ns node]
}	

$ns rtproto Session 

#Colori dei nodi in nam
$n(7) color "Red"
$n(8) color "Red"
$n(9) color "DarkGreen"
$n(10) color "DarkGreen"
$n(13) color "Orange"

puts "\n\n####### Esempio di simulazione  ex-OMI -> Rettorato #######\n\n"
puts "Inserire la velocità della linea tra il router ex-OMI (n4) \n ed il router (n5) del Rettorato (in b/s):"
set rate [gets stdin]
puts "Inserire la dimensione della coda del router ex-OMI (n4) in uscita\n verso il Rettorato (in pacchetti):"
set dim_coda [gets stdin]
puts "\n\n"
#attende input da tastiera

#Definizione dei link
$ns duplex-link $n(0) $n(4) 10Mb 2us DropTail
$ns duplex-link $n(1) $n(4) 10Mb 2us DropTail
$ns duplex-link $n(2) $n(4) 10Mb 2us DropTail
$ns duplex-link $n(3) $n(4) 10Mb 2us DropTail
$ns duplex-link $n(11) $n(4) 10Mb 2us DropTail
$ns duplex-link $n(4) $n(5) $rate 10us DropTail
$ns duplex-link $n(5) $n(6) 512Kb 10us DropTail
$ns duplex-link $n(7) $n(4) 10Mb 2us DropTail
$ns duplex-link $n(8) $n(5) 128Kb 10us DropTail
$ns duplex-link $n(9) $n(4) 10Mb 2us DropTail
$ns duplex-link $n(10) $n(5) 128Kb 10us DropTail
$ns duplex-link $n(12) $n(5) 128Kb 10us DropTail
$ns duplex-link $n(13) $n(4) 10Mb 2us DropTail

#Dimensione della coda del router n4
$ns queue-limit $n(4) $n(5) $dim_coda
$ns queue-limit $n(5) $n(4) 75

#Visualizzazione della coda in nam
$ns duplex-link-op $n(4) $n(5) queuePos 0.5

#Monitoraggio dei pacchetti sul link da n4 a n5
$ns trace-queue $n(4) $n(5) $tf0

#Creazione di un oggetto QueueMonitor associato al link da n4 a n5
set queue4_5 [$ns monitor-queue $n(4) $n(5) [$ns get-ns-traceall]]

#
#HTTP
#

#Generatore delle pagine che potranno essere richieste
set pgp [new PagePool/Math]

#Generatore delle dimensioni delle pagine
set tmp [new RandomVariable/Constant]           
#Valore medio di una pagina
$tmp set val_ 10240                             
$pgp ranvar-size $tmp
#Generatore dell'eta' delle pagine
set tmp [new RandomVariable/Exponential]      
#Valore medio dell'eta'
$tmp set avg_ 5                                 
$pgp ranvar-age $tmp

#Creazione server1 e collegamento al generatore di pagine
set server1 [new Http/Server $ns $n(11)]
$server1 set-page-generator $pgp
$server1 log $log1

#Creazione server2 e collegamento al generatore di pagine
set server2 [new Http/Server $ns $n(6)]
$server2 set-page-generator $pgp
$server2 log $log2

#Creazione delle cache
set cache1 [new Http/Cache $ns $n(11)]
$cache1 log $log1

set cache2 [new Http/Cache $ns $n(6)]
$cache2 log $log2

#Creazione dei clients
set client0 [new Http/Client $ns $n(0)]
#Processo di Poisson per modellare la sequenza di richieste
set tmp0 [new RandomVariable/Exponential]
#Intervallo medio tra due richieste
$tmp0 set avg_ 0.2
$client0 set-interval-generator $tmp0
$client0 set-page-generator $pgp
$client0 log $log2

set client1 [new Http/Client $ns $n(1)]
#Processo di Poisson per modellare la sequenza di richieste
set tmp1 [new RandomVariable/Exponential]
#Intervallo medio tra due richieste
$tmp1 set avg_ 0.5
$client1 set-interval-generator $tmp1
$client1 set-page-generator $pgp
$client1 log $log2

set client2 [new Http/Client $ns $n(2)]
#Processo di Poisson per modellare la sequenza di richieste
set tmp2 [new RandomVariable/Exponential]
#Intervallo medio tra due richieste
$tmp2 set avg_ 0.5
$client2 set-interval-generator $tmp2
$client2 set-page-generator $pgp
$client2 log $log2

set client3 [new Http/Client $ns $n(3)]
#Processo di Poisson per modellare la sequenza di richieste
set tmp3 [new RandomVariable/Exponential]
#Intervallo medio tra due richieste
$tmp3 set avg_ 1
$client3 set-interval-generator $tmp3
$client3 set-page-generator $pgp
$client3 log $log2

set client4 [new Http/Client $ns $n(12)]
#Processo di Poisson per modellare la sequenza di richieste
set tmp4 [new RandomVariable/Exponential]
#Intervallo medio tra due richieste
$tmp4 set avg_ 7.8
$client4 set-interval-generator $tmp4
$client4 set-page-generator $pgp
$client4 log $log1

#
#Fine HTTP
#

#Definizione degli agents
set tcp7 [new Agent/TCP]
$tcp7 set packetSize_ 1000
set tcp8 [new Agent/TCPSink]
set tcp9 [new Agent/TCP/FullTcp]
$tcp9 set segsize_ 1000
set tcp10 [new Agent/TCP/FullTcp]
$tcp10 set segsize_ 1000
set udp13 [new Agent/UDP]
set sink5 [new Agent/Null]

#Assegnazione colori ai vari flussi di traffico
$ns color 78 red
$tcp7 set fid_ 78
$ns color 9 darkgreen
$tcp9 set fid_ 9
$ns color 87 red
$tcp8 set fid_ 87
$ns color 10 darkgreen
$tcp10 set fid_ 10
$ns color 13 orange
$udp13 set fid_ 13

#Attacco gli agents ai nodi
$ns attach-agent $n(7) $tcp7
$ns attach-agent $n(8) $tcp8
$ns attach-agent $n(9) $tcp9
$ns attach-agent $n(10) $tcp10
$ns attach-agent $n(13) $udp13
$ns attach-agent $n(5) $sink5

#Connessioni degli agents
$ns connect $tcp8 $tcp7
$ns connect $tcp9 $tcp10
$ns connect $udp13 $sink5

$tcp10 listen

#Sorgente FTP
set ftp7 [new Application/FTP]
$ftp7 attach-agent $tcp7
$ns at [expr $finishTime/9] "$ftp7 start"
$ns at [expr $finishTime/9 + 1.5] "$ftp7 stop"
$ns at [expr $finishTime/5] "$ftp7 start"
$ns at [expr $finishTime/5 + 2] "$ftp7 stop"
$ns at [expr $finishTime/3] "$ftp7 start"
$ns at [expr $finishTime/3 + 1.5] "$ftp7 stop"
$ns at [expr $finishTime/1.5] "$ftp7 start"
$ns at [expr $finishTime/1.5 + 1.5] "$ftp7 stop"

#Sorgente Telnet
set tel9 [new Application/Telnet]
$tel9 attach-agent $tcp9
$tel9 set interval_ 0.5
$ns at $startTime "$tel9 start"

#Sorgente di traffico esponenziale
set exp13 [new Application/Traffic/Exponential]
$exp13 set packet_size_ 1000
$exp13 set burst_time_ 0.8s
$exp13 set idle_time_ 0.2s
$exp13 set rate_ 440k
$exp13 attach-agent $udp13
$ns at 0.0 "$exp13 start"

$ns at $startTime "record_coda"
$ns at $startTime "record"
$ns at $startTimeHTTP0 "start-connection0"
$ns at $startTimeHTTP1 "start-connection1"
$ns at $startTimeHTTP2 "start-connection2"
$ns at $startTimeHTTP3 "start-connection3"
$ns at $startTimeHTTP4 "start-connection4"
$ns at $finishTime "finish"

#Avvio la simulazione
$ns run