#!/usr/bin/perl

use IO::Socket::INET;

###############################################
#
# Configuration section

# Cheat mode selection
$CHEAT_MODE=0; # No cheating
#$CHEAT_MODE=1; # Use recorded sink packets

# Whether we actually send bundles or just display received
# data from the sink
$TX_BUNDLE=0;

# Where to read the packets to replay
# to the sink
$GUI_PACKET_TRACE="54 21 00 00 00 00 1E 04 00 08 7D 19 01 0B 00 00 00 00 00 00 00 00 00 F4 01 00 00 00 00 00 00 00 01 00 00 01 01 1E 04 00 08 7D 19 01 09 00 00 00 00 00 00 00 00 05 B8 0B 00 00 00 00 00 00 00 01 01 00 00 00 1E 04 00 08 7D 19 01 01 01 00 00 04 03 00 96 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1E 02 00 08 7D 19 01 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1E 03 00 08 7D 19 01 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1E 04 00 08 7D 19 01 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00";


@SINK_PACKET_TRACE= (
 
);

# Sink TCP socket
$SINK_IP="10.0.2.2";
$SINK_PORT="9001";

# EID for DTN communication
$SOURCE_EID="dtn://toulouse.dtn/satnex";
$DEST_EID="dtn://genoa.dtn/satnex";

# Bundle size (ie: how
# to packetize the TCP
# stream)
$BUNDLE_SIZE=25;

# Full pathname of the dtnsend application
$DTN_SEND="./dtnsend";

###############################################
#
# Real stuff starts here

# Transmit to the sink replay packets, 
# read replies from the sink and proxy
# these replies on bundle
sub noCheat() {

  my $PACKET_HANDLE, $BUNDLE_HANDLE;
  my $sink_socket,@packet_trace;
  my $sink_msg;

  # Open the file containing the 
  # packet dump

  print "Switching to no cheat mode\n";

  # Connect to the sink
  ($sink_socket=new IO::Socket::INET->new(PeerPort=>$SINK_PORT,
					Proto=>'tcp',
					PeerAddr=>$SINK_IP)) || die $!;

  # Replay the trace of packets
  # Fetch the packet trace to replay
  # and inject it in the socket
  @packet_trace=decodeHexString($GUI_PACKET_TRACE);

  $sink_socket->send(pack("c*",@packet_trace));
    
  ## At this point, we should be ready to receive data
  ## from the sens. net sink

  # Loop for receiving the data 
  # from the sink
  while(1) {
    
    # Read data from the sink
    $sink_msg='';
    $sink_socket->recv($sink_msg,$BUNDLE_SIZE,0);
    # Active wait ... not very clever but it works
    while(length($sink_msg)==0) {
      $sink_msg='';
      $sink_socket->recv($sink_msg,$BUNDLE_SIZE,0);
    }
    
    # Shall we send bundles or simply 
    # dump hex data on the screen ? 
    if($TX_BUNDLE==0) {
      @received_data=unpack("c*",$sink_msg);
    
      print "(0..$#received_data )> ";
      for($i=0;$i<=$#received_data;$i++) {
        print sprintf("%.2X ",$received_data[$i] & 0xFF);
      }
      print "\n";
    } else {

      # Create a file using the data read from the file
      open(BUNDLE_HANDLE,">bundle.dat") || die $!;
      write(BUNDLE_HANDLE,$sink_msg,length($sink_msg));
      close(BUNDLE_HANDLE);
    
      # Send this file as a bundle through
      # the long haul link
      system("$DTN_SEND -s $SOURCE_EID -d $DEST_EID -t f -p bundle.dat");
    
      # Delete the file
      system("rm bundle.dat"); 
    }
    
  } # End of the loop  
  
  # close the socket
  close(SINK_HANDLE);
}



# Do not transmit replay packets
# to the sink, read previously
# recorded replies from a file 
# and proxy these reply on bundle
sub cheatMode1() {

  my $BUNDLE_HANDLE;
  my $current_packet,$packet_trace;

  print "Switching to cheat mode 1\n";

  ## At this point, we should be ready to receive data
  ## from the sens. net sink

  # Loop for receiving the data 
  # from the sink
  $current_packet=0;
  while($current_packet<=$#SINK_PACKET_TRACE) {
    
    @packet_trace=&decodeHexString($SINK_PACKET_TRACE[$current_packet]);
   
    print "Read ".($#packet_trace+1)." bytes from the sink\n";
    
    # Create a file using the data read from the file
    open(BUNDLE_HANDLE,">bundle.dat") || die $!;

    print BUNDLE_HANDLE pack("c*",@packet_trace);

    close(BUNDLE_HANDLE);
    
    # Send this file as a bundle through
    # the long haul link
#    system("$DTN_SEND -s $SOURCE_EID -d $DEST_EID -t f -p bundle.dat");
    
    # Delete the file
 #   system("rm bundle.dat");

    $current_packet++;

  } # End of the loop  
  

}


# Decode a HEX string and return
# an array of integers
sub decodeHexString() {

  my $a_string=$_[0];
  my @the_chars;
  my $i;
  my @buffer=();

  @the_chars=split(" ",$a_string);
  for($i=0;$i<=$#the_chars;$i++) {

    $buffer[$#buffer+1]=hex($the_chars[$i]);
  }

  return(@buffer);
}


if($CHEAT_MODE==0) {
  do noCheat();
} elsif($CHEAT_MODE==1) {
  do cheatMode1();
}
