#!/usr/bin/perl -w
#
# Connect to the DTN telnet console in order to set/unset links availabilities
#
# Arguments :
# link1_name link1_uptime link1_downtime link2 link2_uptime link2_downtime delta
# time arguments must be provided in floating seconds.

use Net::Telnet ();
use Time::HiRes qw ( gettimeofday tv_interval sleep );


# Parameters defining the access to the DTND console
my $dtnhost1="192.168.3.2";
my $dtnport1="5050";
my $link1_random=0;

my $dtnhost2="127.0.0.1";
my $dtnport2="5050";
my $link2_random=0;

# Minimum sleep time in random mode
my $rand_min=1;

# One argument is missing => die
if(scalar(@ARGV)!=7) {
	die 'Syntax is ./dtn-up-down.pl link1_name link1_uptime link1_downtime link2 link2_uptime link2_downtime delta';
}

# Assign values to variables from command line
my $link1_name=$ARGV[0];
my $link1_uptime=$ARGV[1];
my $link1_downtime=$ARGV[2];

my $link2_name=$ARGV[3];
my $link2_uptime=$ARGV[4];
my $link2_downtime=$ARGV[5];

my $delta=$ARGV[6];


# Open socket to DTN console
sub dtnconnect
{
	($dtnhost, $dtnport, $dtnconsole) = @_;
	$$dtnconsole = new Net::Telnet (Telnetmode => 0);
	$$dtnconsole->open(Host => $dtnhost, Port => $dtnport);

	# Wait for first prompt "dtn%".
	$$dtnconsole->waitfor('/dtn\%.*$/');
}

# Change the link status dtnlink($link, $status)
# where $status = "true" or "false"
sub dtnlinkchange
{
	($dtnconsole,$link, $status) = @_;
	
	$$dtnconsole->print("link $status $link");
#	$$dtnconsole->print("link set_available $link $status");
}


sub expNeg() {

        local $the_mu=$_[0];
        local $the_urand;

        $the_urand=rand();
        while($the_urand==0) {
                $the_urand=rand();
        }

        $expNeg=-1*(1.0/$the_mu)*log($the_urand);
}




dtnconnect($dtnhost1, $dtnport1, "dtnconsole1");
print("dtnconnect $link1_name\n");

dtnconnect($dtnhost2, $dtnport2, "dtnconsole2");
print("dtnconnect $link2_name\n");


# Fork in order to manipulate the two links parameters in //

if ( my $pid = fork) {
    # le père
    
	while(1) {
		$t0 = [gettimeofday];
		dtnlinkchange("dtnconsole1",$link1_name,"open");
		
		if ($link1_random) {
			$duration=&expNeg(1/$link1_uptime) + $rand_min;
		}

		else {
			$duration=$link1_uptime;
		}

		print("$link1_name up for $duration seconds\n");

		$elapsed = tv_interval ($t0);

		# sleep link1_uptime	
		sleep($duration - $elapsed);
		
		$t0 = [gettimeofday];

		dtnlinkchange("dtnconsole1",$link1_name,"close");

		if ($link1_random) {
			$duration=&expNeg(1/$link1_downtime) + $rand_min;
		}

		else {
			$duration=$link1_uptime;
		}
		
		print("$link1_name down for $duration seconds\n");

		$elapsed = tv_interval ($t0);

		# sleep link1_downtime	
		sleep($duration - $elapsed);
	
	}
	waitpid( $pid, 0 )
}

else {
	die "duplication impossible : $!" unless defined $pid;

	# processus fils
	
	# sleep delta
	sleep($delta);
	
	while(1) {
		$t0 = [gettimeofday];
	
		dtnlinkchange("dtnconsole2",$link2_name,"open");

		if ($link2_random) {
			$duration=&expNeg(1/$link2_uptime) + $rand_min;
		}

		else {
			$duration=$link2_uptime;
		}
		
		print("$link2_name up for $duration seconds\n");
		
		$elapsed = tv_interval ($t0);
		
		# sleep link2_uptime
		sleep($duration - $elapsed);
		
		$t0 = [gettimeofday];

		dtnlinkchange("dtnconsole2",$link2_name,"close");

		if ($link2_random) {
			$duration=&expNeg(1/$link2_downtime) + $rand_min;
		}

		else {
			$duration=$link2_downtime;
		}
		
		print("$link2_name down for $duration seconds\n");
		
		$elapsed = tv_interval ($t0);

		# sleep link2_downtime
		sleep($duration - $elapsed);
	
	}

	exit 0;
}

