#!/usr/bin/perl -w

#
# Script to log time and interrogate a Sonardyne homer beacon with
# hardcoded addresses.  
# 
# NOTES: 
#        - If this script is run on a Windows machine under Cygwin, remember that
#          serial port 1 (according to windows) will actually be /dev/ttyS0 as far
#          as Perl knows. Subtract 1 for use on windows (e.g. com8 = /dev/ttyS7)  
#  
#        - This script is intedned to be run in such a way that its output is captured
#          in a log (e.g. | tee, > logfile, etc). The script itself does not create
#          its own log file in an effort to provide flexibility to the end user. 
#
#
### 05/09/13 - Initial creation                                           B. Kieft
### 04/2014 - Hardcoded multiple addresses. Need to make 
# 						flexible at a later date																		B. Kieft
#

use POSIX qw/strftime/; 

$now_string = strftime "%a %b %e %Y %H:%M:%S ", gmtime;
printf("System time GMT is: " . $now_string . "\nSet time to match GPS.\n");

# Prompt the user for the serial port number 
$PortNum = &promptUser("Enter the serial port number to which the iUSBL is attached (0 1 2 3 4 5 6 7 8 9)", 0);

# Serial port being used 
$SP = "/dev/ttyS$PortNum";

printf("Using serial port $SP \n");
printf("9600 Bps, 8-n-1 \n");


# This script requires the use of a serial package from CPAN
# This package is available in the project's test folder. Follow 
# the instructions in the README file in the folder named
# Device-SerialPort-1.002. 
use Device::SerialPort 0.12; 


# Setup serial port properties
# Writes to $ob are followed by a sleep for flushing
#
$ob = Device::SerialPort->new ($SP) || die "Can't Open $SP: $!";
$ob->baudrate(9600)    || die "failed setting baudrate";
$ob->parity("none")    || die "failed setting parity";
$ob->databits(8)       || die "failed setting databits";
$ob->handshake("none") || die "failed setting handshake";
$ob->write_settings    || die "no settings";
##


# Create the strings to send to the iUSBL
$input_1 = "POS V8,4\n"; # Homer 44
$input_2 = "POS V11,2\n"; # Homer 27
$input_3 = "POS V4,9\n"; # Homer 90
$input_4 = "POS V8,3\n"; # Homer 34

$ob->read_char_time(0);     # don't wait for each character
$ob->read_const_time(500); # .5 second per unfulfilled "read" call
$chars=0;
$buffer="";
my $STALL_DEFAULT=7; # how many seconds to wait for new input
my $timeout=$STALL_DEFAULT;

# To poll for response
$timeout=$STALL_DEFAULT;


# First query the unit for power level and gain so it's logged
$ob->write("PL\n"); # query power level
    while ($timeout>0) {
      ($count,$saw)=$ob->read(25); # will read _up to_ 25 chars
      if ($count > 0) {
        $chars+=$count;
        $buffer.=$saw;
        # Check here to see if what we want is in the $buffer
        # say "last" if we find it
        last if(length($buffer) > 21);
        }
      else {
        $timeout--;
      }
    }
  printf("Power Level: " . $buffer . "\n");
  $chars=0;
  $buffer="";
  $timeout=$STALL_DEFAULT;
  
$ob->write("PG\n"); # query gain
    while ($timeout>0) {
      ($count,$saw)=$ob->read(25); # will read _up to_ 25 chars
      if ($count > 0) {
        $chars+=$count;
        $buffer.=$saw;
        # Check here to see if what we want is in the $buffer
        # say "last" if we find it
        last if(length($buffer) > 21);
        }
      else {
        $timeout--;
      }
    }
  printf("Gain: " . $buffer . "\n");
  $chars=0;
  $buffer="";
  $timeout=$STALL_DEFAULT;

while (1) {

	# Input 1
	printf("querying Homer 44\n");
  $ob->write($input_1); # query for position
    while ($timeout>0) {
      ($count,$saw)=$ob->read(25); # will read _up to_ 25 chars
      if ($count > 0) {
        $chars+=$count;
        $buffer.=$saw;
        # Check here to see if what we want is in the $buffer
        # say "last" if we find it
        last if(length($buffer) > 12);
        }
      else {
        $timeout--;
      }
    }
   # Put TOD in there as well
  $now_string = strftime "%a %b %e %Y %H:%M:%S ", gmtime;
  printf($now_string . $buffer . "\n");
  
  $chars=0;
  $buffer="";
  $timeout=$STALL_DEFAULT;

	# Input 2
	printf("querying Homer 27\n");
  $ob->write($input_2); # query for position
    while ($timeout>0) {
      ($count,$saw)=$ob->read(25); # will read _up to_ 25 chars
      if ($count > 0) {
        $chars+=$count;
        $buffer.=$saw;
        # Check here to see if what we want is in the $buffer
        # say "last" if we find it
        last if(length($buffer) > 12);
        }
      else {
        $timeout--;
      }
    }
   # Put TOD in there as well
  $now_string = strftime "%a %b %e %Y %H:%M:%S ", gmtime;
  printf($now_string . $buffer . "\n");
  
  $chars=0;
  $buffer="";
  $timeout=$STALL_DEFAULT;

	# Input 3
	printf("querying Homer 90\n");
  $ob->write($input_3); # query for position
    while ($timeout>0) {
      ($count,$saw)=$ob->read(25); # will read _up to_ 25 chars
      if ($count > 0) {
        $chars+=$count;
        $buffer.=$saw;
        # Check here to see if what we want is in the $buffer
        # say "last" if we find it
        last if(length($buffer) > 12);
        }
      else {
        $timeout--;
      }
    }
   # Put TOD in there as well
  $now_string = strftime "%a %b %e %Y %H:%M:%S ", gmtime;
  printf($now_string . $buffer . "\n");
  
  $chars=0;
  $buffer="";
  $timeout=$STALL_DEFAULT;

	# Input 4
	printf("querying Homer 34\n");
  $ob->write($input_4); # query for position
    while ($timeout>0) {
      ($count,$saw)=$ob->read(25); # will read _up to_ 25 chars
      if ($count > 0) {
        $chars+=$count;
        $buffer.=$saw;
        # Check here to see if what we want is in the $buffer
        # say "last" if we find it
        last if(length($buffer) > 12);
        }
      else {
        $timeout--;
      }
    }
   # Put TOD in there as well
  $now_string = strftime "%a %b %e %Y %H:%M:%S ", gmtime;
  printf($now_string . $buffer . "\n");
  
  $chars=0;
  $buffer="";
  $timeout=$STALL_DEFAULT;  
  
}



#
#
#
#
#----------------------------(  promptUser  )-----------------------------#
#                                                                         #
#  FUNCTION:	promptUser                                                #
#                                                                         #
#  PURPOSE:	Prompt the user for some type of input, and return the    #
#		input back to the calling program.                        #
#                                                                         #
#  ARGS:	$promptString - what you want to prompt the user with     #
#		$defaultValue - (optional) a default value for the prompt #
#                                                                         #
#-------------------------------------------------------------------------#

sub promptUser {

   #-------------------------------------------------------------------#
   #  two possible input arguments - $promptString, and $defaultValue  #
   #  make the input arguments local variables.                        #
   #-------------------------------------------------------------------#

   local($promptString,$defaultValue) = @_;

   #-------------------------------------------------------------------#
   #  if there is a default value, use the first print statement; if   #
   #  no default is provided, print the second string.                 #
   #-------------------------------------------------------------------#

   if ($defaultValue) {
      print $promptString, "[", $defaultValue, "]: ";
   } else {
      print $promptString, ": ";
   }

   $| = 1;               # force a flush after our print
   $_ = <STDIN>;         # get the input from STDIN (presumably the keyboard)


   #------------------------------------------------------------------#
   # remove the newline character from the end of the input the user  #
   # gave us.                                                         #
   #------------------------------------------------------------------#

   chomp;

   #-----------------------------------------------------------------#
   #  if we had a $default value, and the user gave us input, then   #
   #  return the input; if we had a default, and they gave us no     #
   #  no input, return the $defaultValue.                            #
   #                                                                 # 
   #  if we did not have a default value, then just return whatever  #
   #  the user gave us.  if they just hit the <enter> key,           #
   #  the calling routine will have to deal with that.               #
   #-----------------------------------------------------------------#

   if ("$defaultValue") {
      return $_ ? $_ : $defaultValue;    # return $_ if it has a value
   } else {
      return $_;
   }
}



