##
#
# Generic setup header for all simulations.
#
# Copyright 2007-2008, Freie Universitaet Berlin. All rights reserved.
# Please refer to the COPYING file for detailed licensing information.
#
# Author: Georg Wittenburg
#
# $Id: header.tcl 2682 2008-06-25 14:11:08Z wittenbu $
#
##



# Create God
set god_ [create-god $val(nn)]
$god_ on

# Create simulator
set ns_ [new Simulator]

# Initialize random number generator with new seed (0 -> random seed)
set rng_ [new RNG]
$rng_ seed 0

# Create channel
set chan_ [new $val(chan)]

# Create topography
set topo_ [new Topography]
$topo_ load_flatgrid $val(x) $val(y)

# Setup node configuration
$ns_ node-config \
	-adhocRouting $val(rp) \
	-llType $val(ll) \
	-macType $val(mac) \
	-ifqType $val(ifq) \
	-ifqLen $val(ifqlen) \
	-antType $val(ant) \
	-propType $val(prop) \
	-phyType $val(netif) \
	-topoInstance $topo_ \
	-agentTrace OFF \
	-routerTrace OFF \
	-macTrace OFF \
	-movementTrace OFF \
	-channel $chan_

# Enable heuristic random seed in shadowing radio propagation.
if {[$ns_ set propType_] == "Propagation/Shadowing"} then {
	[$ns_ set propInstance_] seed heuristic 0
}

# Open trace files
#set tracefd_	[open out.tr w]
set tracefd_	[open /dev/null w]
$ns_ trace-all $tracefd_
#set namtracefd_ [open out.nam w]
set namtracefd_ [open /dev/null w]
$ns_ namtrace-all-wireless $namtracefd_ $val(x) $val(y)

# Remember start time
set start_time_ [clock seconds]

# Begin and end of start, simulation, stop and finalize phases.
set start_phase_begin		0.0
set start_phase_end		[expr $start_phase_begin + 600.0]
set simulation_begin		$start_phase_end
set simulation_end		[expr $simulation_begin + $simulation_duration]
set stop_phase_begin		$simulation_end
set stop_phase_end		[expr $stop_phase_begin + 600.0]
set finalize_phase_begin	[expr $stop_phase_end + 3600.0]
set finalize_phase_end		[expr $finalize_phase_begin + 600.0]



$ns_ at [expr $finalize_phase_end] "stop"

proc stop {} {
	global ns_ tracefd_ namtracefd_ start_time_
	$ns_ halt
	$ns_ nam-end-wireless [$ns_ now]
	$ns_ flush-trace
	close $tracefd_
	close $namtracefd_
	set elapased_time [expr [clock seconds] - $start_time_ - 3600]	;# Formatting miraculously adds one hour.
	puts [format "Simulation complete (%s)." [clock format $elapased_time -format "%T"]]
	#puts ""
	#printProcessStatus
	puts ""
	printStats
}

proc printProcessStatus {} {
	set stats [open /proc/self/status r]
	while { [gets $stats line] >= 0 } {
		puts $line
	}
	close $stats
}

proc printStats {} {
	global val application_ node_

	set MAC_transmittedPackets			0
	set MAC_receivedPackets				0
	set MAC_droppedPackets_capture			0
	set MAC_droppedPackets_collision		0
	set MAC_droppedPackets_transmit			0
	set MAC_droppedPackets_bit_error		0
	set MAC_transmittedBytes			wide(0)
	set MAC_receivedBytes				wide(0)

	set APP_transmittedUnicastPackets		0
	set APP_receivedUnicastPackets			0
	set APP_unicastPDR				0.0
	set APP_transmittedBroadcastPackets		0
	set APP_receivedBroadcastPackets		0
	set APP_broadcastPDR				0.0
	set APP_transmittedBytes			wide(0)
	set APP_receivedBytes				wide(0)

	set DEBUG_ERRORs				0
	set DEBUG_WARNs					0

	set minNodeDegree				255
	set maxNodeDegree				0
	set directNeighbors				0
	set avgNodeDegree				0.0
	set directNeighborsList				[list]
	set medNodeDegree				0.0

	set longestRoute				0
	set averageRoute				0.0

	set RUDP_totalTransmissions			0
	set RUDP_successfulTransmissions		0
	set RUDP_pdr					0.0

	set ICMP_transmittedNops			0
	set ICMP_receivedNops				0

	set SLP_totalQueries				0
	set SLP_successfulQueries			0
	set SLP_recall					0.0

	set SERVICE_totalDataRequests			0
	set SERVICE_successfulDataRequests		0
	set SERVICE_dataRequestRecall			0.0
	set SERVICE_totalSuccessfulDataRequestDelay	0.0
	set SERVICE_averageSuccessfulDataRequestDelay	0.0
	set SERVICE_totalDataUpdates			0
	set SERVICE_successfulDataUpdates		0
	set SERVICE_dataUpdateRecall			0.0
	set SERVICE_totalStreamRequests			0
	set SERVICE_successfulStreamRequests		0
	set SERVICE_streamRequestRecall			0.0
	set SERVICE_expectedStreamPackets		0
	set SERVICE_receivedStreamPackets		0
	set SERVICE_streamPacketRecall			0.0
	set SERVICE_totalReplications			0
	set SERVICE_successfulReplications		0
	set SERVICE_replicationSuccessRate		0.0
	set SERVICE_totalMigrations			0
	set SERVICE_successfulMigrations		0
	set SERVICE_migrationSuccessRate		0.0

	for {set i 0} {$i < $val(nn)} {incr i} {
		set MAC_transmittedPackets [expr $MAC_transmittedPackets + [[$node_($i) set mac_(0)] set transmittedPackets_]]
		set MAC_receivedPackets [expr $MAC_receivedPackets + [[$node_($i) set mac_(0)] set receivedPackets_]]
		set MAC_droppedPackets_capture [expr $MAC_droppedPackets_capture + [[$node_($i) set mac_(0)] set droppedPackets_capture_]]
		set MAC_droppedPackets_collision [expr $MAC_droppedPackets_collision + [[$node_($i) set mac_(0)] set droppedPackets_collision_]]
		set MAC_droppedPackets_transmit [expr $MAC_droppedPackets_transmit + [[$node_($i) set mac_(0)] set droppedPackets_transmit_]]
		set MAC_droppedPackets_bit_error [expr $MAC_droppedPackets_bit_error + [[$node_($i) set mac_(0)] set droppedPackets_bit_error_]]
		set MAC_transmittedBytes [expr $MAC_transmittedBytes + [[$node_($i) set mac_(0)] set transmittedBytes_]]
		set MAC_receivedBytes [expr $MAC_receivedBytes + [[$node_($i) set mac_(0)] set receivedBytes_]]

		set APP_transmittedUnicastPackets [expr $APP_transmittedUnicastPackets + [$application_($i) set transmittedUnicastPackets_]]
		set APP_receivedUnicastPackets [expr $APP_receivedUnicastPackets + [$application_($i) set receivedUnicastPackets_]]
		set APP_transmittedBroadcastPackets [expr $APP_transmittedBroadcastPackets + [$application_($i) set transmittedBroadcastPackets_]]
		set APP_receivedBroadcastPackets [expr $APP_receivedBroadcastPackets + [$application_($i) set receivedBroadcastPackets_]]
		set APP_transmittedBytes [expr $APP_transmittedBytes + [$application_($i) set transmittedBytes_]]
		set APP_receivedBytes [expr $APP_receivedBytes + [$application_($i) set receivedBytes_]]

		set DEBUG_ERRORs [expr $DEBUG_ERRORs + [$application_($i) set DEBUG_ERRORs_]]
		set DEBUG_WARNs [expr $DEBUG_WARNs + [$application_($i) set DEBUG_WARNs_]]

		if {$minNodeDegree > [$application_($i) set directNeighbors_]} then {
			set minNodeDegree [$application_($i) set directNeighbors_]
		}
		if {$maxNodeDegree < [$application_($i) set directNeighbors_]} then {
			set maxNodeDegree [$application_($i) set directNeighbors_]
		}
		set directNeighbors [expr $directNeighbors + [$application_($i) set directNeighbors_]]
		lappend directNeighborsList [$application_($i) set directNeighbors_]

		if {$longestRoute < [$application_($i) set longestRoute_]} then {
			set longestRoute [$application_($i) set longestRoute_]
		}
		set averageRoute [expr $averageRoute + [$application_($i) set averageRoute_]]

		set RUDP_totalTransmissions [expr $RUDP_totalTransmissions + [$application_($i) set RUDP_totalTransmissions_]]
		set RUDP_successfulTransmissions [expr $RUDP_successfulTransmissions + [$application_($i) set RUDP_successfulTransmissions_]]

		set ICMP_transmittedNops [expr $ICMP_transmittedNops + [$application_($i) set ICMP_transmittedNops_]]
		set ICMP_receivedNops [expr $ICMP_receivedNops + [$application_($i) set ICMP_receivedNops_]]

		set SLP_totalQueries [expr $SLP_totalQueries + [$application_($i) set SLP_totalQueries_]]
		set SLP_successfulQueries [expr $SLP_successfulQueries + [$application_($i) set SLP_successfulQueries_]]

		set SERVICE_totalDataRequests [expr $SERVICE_totalDataRequests + [$application_($i) set SERVICE_totalDataRequests_]]
		set SERVICE_successfulDataRequests [expr $SERVICE_successfulDataRequests + [$application_($i) set SERVICE_successfulDataRequests_]]
		set SERVICE_totalSuccessfulDataRequestDelay [expr $SERVICE_totalSuccessfulDataRequestDelay + [$application_($i) set SERVICE_totalSuccessfulDataRequestDelay_]]
		set SERVICE_totalDataUpdates [expr $SERVICE_totalDataUpdates + [$application_($i) set SERVICE_totalDataUpdates_]]
		set SERVICE_successfulDataUpdates [expr $SERVICE_successfulDataUpdates + [$application_($i) set SERVICE_successfulDataUpdates_]]
		set SERVICE_totalStreamRequests [expr $SERVICE_totalStreamRequests + [$application_($i) set SERVICE_totalStreamRequests_]]
		set SERVICE_successfulStreamRequests [expr $SERVICE_successfulStreamRequests + [$application_($i) set SERVICE_successfulStreamRequests_]]
		set SERVICE_expectedStreamPackets [expr $SERVICE_expectedStreamPackets + [$application_($i) set SERVICE_expectedStreamPackets_]]
		set SERVICE_receivedStreamPackets [expr $SERVICE_receivedStreamPackets + [$application_($i) set SERVICE_receivedStreamPackets_]]
		set SERVICE_totalReplications [expr $SERVICE_totalReplications + [$application_($i) set SERVICE_totalReplications_]]
		set SERVICE_successfulReplications [expr $SERVICE_successfulReplications + [$application_($i) set SERVICE_successfulReplications_]]
		set SERVICE_totalMigrations [expr $SERVICE_totalMigrations + [$application_($i) set SERVICE_totalMigrations_]]
		set SERVICE_successfulMigrations [expr $SERVICE_successfulMigrations + [$application_($i) set SERVICE_successfulMigrations_]]
	}

	set avgNodeDegree [expr double($directNeighbors) / double($val(nn))]
	set directNeighborsList [lsort -integer $directNeighborsList]
	if {[expr [llength $directNeighborsList] % 2] == 0} then {
		set medNodeDegree [expr ([lindex $directNeighborsList [expr [llength $directNeighborsList] / 2 - 1]] + [lindex $directNeighborsList [expr [llength $directNeighborsList] / 2]]) / 2.0]
	} else {
		set medNodeDegree [lindex $directNeighborsList [expr ([llength $directNeighborsList] - 1) / 2]]
	}
	set averageRoute [expr $averageRoute / $val(nn)]

	if {$APP_transmittedUnicastPackets > 0} then {
		set APP_unicastPDR [expr double($APP_receivedUnicastPackets) / double($APP_transmittedUnicastPackets)]
	}
	if {$APP_transmittedBroadcastPackets > 0} then {
		set APP_broadcastPDR [expr double($APP_receivedBroadcastPackets) / double($APP_transmittedBroadcastPackets)]
	}

	if {$RUDP_totalTransmissions > 0} then {
		set RUDP_pdr [expr double($RUDP_successfulTransmissions) / double($RUDP_totalTransmissions)]
	}

	if {$SLP_totalQueries > 0} then {
		set SLP_recall [expr double($SLP_successfulQueries) / double($SLP_totalQueries)]
	}

	if {$SERVICE_totalDataRequests > 0} then {
		set SERVICE_dataRequestRecall [expr double($SERVICE_successfulDataRequests) / double($SERVICE_totalDataRequests)]
	}
	if {$SERVICE_successfulDataRequests > 0} then {
		set SERVICE_averageSuccessfulDataRequestDelay [expr double($SERVICE_totalSuccessfulDataRequestDelay) / double($SERVICE_successfulDataRequests)]
	}
	if {$SERVICE_totalDataUpdates > 0} then {
		set SERVICE_dataUpdateRecall [expr double($SERVICE_successfulDataUpdates) / double($SERVICE_totalDataUpdates)]
	}
	if {$SERVICE_totalStreamRequests > 0} then {
		set SERVICE_streamRequestRecall [expr double($SERVICE_successfulStreamRequests) / double($SERVICE_totalStreamRequests)]
	}
	if {$SERVICE_expectedStreamPackets > 0} then {
		set SERVICE_streamPacketRecall [expr double($SERVICE_receivedStreamPackets) / double($SERVICE_expectedStreamPackets)]
	}
	if {$SERVICE_totalReplications > 0} then {
		set SERVICE_replicationSuccessRate [expr double($SERVICE_successfulReplications) / double($SERVICE_totalReplications)]
	}
	if {$SERVICE_totalMigrations > 0} then {
		set SERVICE_migrationSuccessRate [expr double($SERVICE_successfulMigrations) / double($SERVICE_totalMigrations)]
	}



	puts [format "ERRORs:\t\t\t\t\t%d"				$DEBUG_ERRORs]
	puts [format "WARNings:\t\t\t\t%d"				$DEBUG_WARNs]
	puts ""
	puts [format "Nodes:\t\t\t\t\t%d"				$val(nn)]
	puts [format "Area:\t\t\t\t\t%dm x %dm"				$val(x) $val(y)]
	puts [format "Minimal node degree:\t\t\t%d"			$minNodeDegree]
	puts [format "Average node degree:\t\t\t%.2f"			$avgNodeDegree]
	puts [format "Median node degree:\t\t\t%.1f"			$medNodeDegree]
	puts [format "Maximal node degree:\t\t\t%d"			$maxNodeDegree]
	puts [format "Longest route:\t\t\t\t%d hops"			$longestRoute]
	puts [format "Average route:\t\t\t\t%.2f hops"			$averageRoute]
	puts ""
	puts [format "MAC transmitted packets:\t\t%d"			$MAC_transmittedPackets]
	puts [format "MAC received packets:\t\t\t%d"			$MAC_receivedPackets]
	puts [format "MAC dropped packets (capture):\t\t%d"		$MAC_droppedPackets_capture]
	puts [format "MAC dropped packets (collision):\t%d"		$MAC_droppedPackets_collision]
	puts [format "MAC dropped packets (transmit):\t\t%d"		$MAC_droppedPackets_transmit]
	puts [format "MAC dropped packets (bit error):\t%d"		$MAC_droppedPackets_bit_error]
	puts [format "MAC transmitted bytes:\t\t\t%d"			$MAC_transmittedBytes]
	puts [format "MAC received bytes:\t\t\t%d"			$MAC_receivedBytes]
	puts ""
	puts [format "APP transmitted unicast packets:\t%d"		$APP_transmittedUnicastPackets]
	puts [format "APP received unicast packets:\t\t%d"		$APP_receivedUnicastPackets]
	puts [format "APP unicast packet delivery ratio:\t%.2f%%"	[expr $APP_unicastPDR * 100]]
	puts [format "APP transmitted broadcast packets:\t%d"		$APP_transmittedBroadcastPackets]
	puts [format "APP received broadcast packets:\t\t%d"		$APP_receivedBroadcastPackets]
	puts [format "APP broadcast packet delivery ratio:\t%.2f%%"	[expr $APP_broadcastPDR * 100]]
	puts [format "APP transmitted bytes:\t\t\t%d"			$APP_transmittedBytes]
	puts [format "APP received bytes:\t\t\t%d"			$APP_receivedBytes]
	puts ""
	puts [format "RUDP total transmissions:\t\t%d"			$RUDP_totalTransmissions]
	puts [format "RUDP successful transmissions:\t\t%d"		$RUDP_successfulTransmissions]
	puts [format "RUDP packet delivery ratio:\t\t%.2f%%"		[expr $RUDP_pdr * 100]]
	puts ""
	puts [format "ICMP transmitted NOPs:\t\t\t%d"			$ICMP_transmittedNops]
	puts [format "ICMP received NOPs:\t\t\t%d"			$ICMP_receivedNops]
	if {$ICMP_transmittedNops > 0} then {
		for {set i 0} {$i < $val(nn)} {incr i} {
			puts [format "ICMP NOP packet delivery ratio at node #%d (%.2f, %.2f, %.2f):\t%.2f%%" $i [$node_($i) set X_] [$node_($i) set Y_] [$node_($i) set Z_] [expr double([$application_($i) set ICMP_receivedNops_]) / double($ICMP_transmittedNops) * 100.0]]
		}
	}
	puts ""
	puts [format "SLP total queries:\t\t\t%d"			$SLP_totalQueries]
	puts [format "SLP successful queries:\t\t\t%d"			$SLP_successfulQueries]
	puts [format "SLP recall:\t\t\t\t%.2f%%"			[expr $SLP_recall * 100]]
	puts ""
	puts [format "SERVICE total data requests:\t\t%d"		$SERVICE_totalDataRequests]
	puts [format "SERVICE successful data requests:\t%d"		$SERVICE_successfulDataRequests]
	puts [format "SERVICE data request recall:\t\t%.2f%%"		[expr $SERVICE_dataRequestRecall * 100]]
	puts [format "SERVICE total succ. data request delay:\t%.2fs"	$SERVICE_totalSuccessfulDataRequestDelay]
	puts [format "SERVICE avg. succ. data request delay:\t%.2fs"	$SERVICE_averageSuccessfulDataRequestDelay]
	puts [format "SERVICE total data updates:\t\t%d"		$SERVICE_totalDataUpdates]
	puts [format "SERVICE successful data updates:\t%d"		$SERVICE_successfulDataUpdates]
	puts [format "SERVICE data update recall:\t\t%.2f%%"		[expr $SERVICE_dataUpdateRecall * 100]]
	puts [format "SERVICE total stream requests:\t\t%d"		$SERVICE_totalStreamRequests]
	puts [format "SERVICE successful stream requests:\t%d"		$SERVICE_successfulStreamRequests]
	puts [format "SERVICE stream request recall:\t\t%.2f%%"		[expr $SERVICE_streamRequestRecall * 100]]
	puts [format "SERVICE expected stream packets:\t%d"		$SERVICE_expectedStreamPackets]
	puts [format "SERVICE received stream packets:\t%d"		$SERVICE_receivedStreamPackets]
	puts [format "SERVICE stream packet recall:\t\t%.2f%%"		[expr $SERVICE_streamPacketRecall * 100]]
	puts [format "SERVICE total replications:\t\t%d"		$SERVICE_totalReplications]
	puts [format "SERVICE successful replications:\t%d"		$SERVICE_successfulReplications]
	puts [format "SERVICE replications success rate:\t%.2f%%"	[expr $SERVICE_replicationSuccessRate * 100]]
	puts [format "SERVICE total migrations:\t\t%d"			$SERVICE_totalMigrations]
	puts [format "SERVICE successful migrations:\t\t%d"		$SERVICE_successfulMigrations]
	puts [format "SERVICE migrations success rate:\t%.2f%%"		[expr $SERVICE_migrationSuccessRate * 100]]

	puts ""
	puts "nodes,area_x,area_y,minNodeDegree,avgNodeDegree,medNodeDegree,maxNodeDegree,longestRoute,averageRoute,MAC_transmittedPackets,MAC_receivedPackets,MAC_droppedPackets_capture,MAC_droppedPackets_collision,MAC_droppedPackets_transmit,MAC_droppedPackets_bit_error,MAC_transmittedBytes,MAC_receivedBytes,APP_transmittedUnicastPackets,APP_receivedUnicastPackets,APP_unicastPDR,APP_transmittedBroadcastPackets,APP_receivedBroadcastPackets,APP_broadcastPDR,APP_transmittedBytes,APP_receivedBytes,RUDP_totalTransmissions,RUDP_successfulTransmissions,RUDP_pdr,ICMP_transmittedNops,ICMP_receivedNops,SLP_totalQueries,SLP_successfulQueries,SLP_recall,SERVICE_totalDataRequests,SERVICE_successfulDataRequests,SERVICE_dataRequestRecall,SERVICE_totalSuccessfulDataRequestDelay,SERVICE_averageSuccessfulDataRequestDelay,SERVICE_totalDataUpdates,SERVICE_successfulDataUpdates,SERVICE_dataUpdateRecall,SERVICE_totalStreamRequests,SERVICE_successfulStreamRequests,SERVICE_streamRequestRecall,SERVICE_expectedStreamPackets,SERVICE_receivedStreamPackets,SERVICE_streamPacketRecall,SERVICE_totalReplications,SERVICE_successfulReplications,SERVICE_replicationSuccessRate,SERVICE_totalMigrations,SERVICE_successfulMigrations,SERVICE_migrationSuccessRate"
	puts "$val(nn),$val(x),$val(y),$minNodeDegree,$avgNodeDegree,$medNodeDegree,$maxNodeDegree,$longestRoute,$averageRoute,$MAC_transmittedPackets,$MAC_receivedPackets,$MAC_droppedPackets_capture,$MAC_droppedPackets_collision,$MAC_droppedPackets_transmit,$MAC_droppedPackets_bit_error,$MAC_transmittedBytes,$MAC_receivedBytes,$APP_transmittedUnicastPackets,$APP_receivedUnicastPackets,$APP_unicastPDR,$APP_transmittedBroadcastPackets,$APP_receivedBroadcastPackets,$APP_broadcastPDR,$APP_transmittedBytes,$APP_receivedBytes,$RUDP_totalTransmissions,$RUDP_successfulTransmissions,$RUDP_pdr,$ICMP_transmittedNops,$ICMP_receivedNops,$SLP_totalQueries,$SLP_successfulQueries,$SLP_recall,$SERVICE_totalDataRequests,$SERVICE_successfulDataRequests,$SERVICE_dataRequestRecall,$SERVICE_totalSuccessfulDataRequestDelay,$SERVICE_averageSuccessfulDataRequestDelay,$SERVICE_totalDataUpdates,$SERVICE_successfulDataUpdates,$SERVICE_dataUpdateRecall,$SERVICE_totalStreamRequests,$SERVICE_successfulStreamRequests,$SERVICE_streamRequestRecall,$SERVICE_expectedStreamPackets,$SERVICE_receivedStreamPackets,$SERVICE_streamPacketRecall,$SERVICE_totalReplications,$SERVICE_successfulReplications,$SERVICE_replicationSuccessRate,$SERVICE_totalMigrations,$SERVICE_successfulMigrations,$SERVICE_migrationSuccessRate"
}
