#!/usr/bin/env perl

## Signal strength meter using the 'ping' command.
## Used for wireless network antenna link testing. Uses no modules, and
## with the 'say' command from the rsynth package, will speak the ping
## millisecond output to you. Useful when you're on a tower aligning antennas

## This file Copyright 2000 <www.gbppr.org> under the GPL
## NO WARRANTY. Please send bug reports / patches / reports.

## User config
#
# ping command location
$ping = "/bin/ping";
# say command location, part the the rsynth package
# http://sunsite.unc.edu/pub/Linux/apps/sound/speech/rsynth-2.0.tgz
$say = "/usr/local/bin/say";
# screen width
$width = 80;
# reference time, 15 milliseconds
$ref = 15;
# ping time log file
$log = "ping.out";
#
## End config

# Setup
#
select STDOUT;
$| = 1;

sub flush {
  local($old) = select(shift);
  $| = 1;
  print "";
  $| = 0;
  select($old);
}

$bld = "\033[37m\033[1m";
$cyn = "\033[36m\033[1m";
$red = "\033[31m\033[1m";
$clr = "\033[0m";

# Start
#
$host = $ARGV[0];
$color = 1;
$beep = 1;

if ($host =~ m/^-/) {
  undef $host;
}

if (-x $say) {
  $speak = 1;
}
else {
  $speak = 0;
}

if ($ARGV[1] eq "-c") {
  $color = 0;
}

if ($ARGV[1] eq "-b") {
  $beep = 0;
}

if ($ARGV[1] eq "-s") {
  $speak = 0;
}

if ($ARGV[2] eq "-b") {
  $beep = 0;
}

if ($ARGV[2] eq "-c") {
  $color = 0;
}

if ($ARGV[2] eq "-s") {
  $speak = 0;
}

if ($ARGV[3] eq "-b") {
  $beep = 0;
}

if ($ARGV[3] eq "-c") {
  $color = 0;
}

if ($ARGV[3] eq "-s") {
  $speak = 0;
}

if (!$host) {
  print "Usage: $0 <hostname> [-c] [-b] [-s]\n".
        "\t-c\tNo color output\n".
        "\t-b\tNo stupid beeping\n".
        "\t-s\tSpeak millisecond value\n";
  exit;
}

if (-f $log) {
  $_ = scalar gmtime;
  $bak = (split)[3];
  rename $log, "$log.$bak";
}

open L, ">$log" || die "Can't open $log: $!\n";
open P, "$ping -n -s 56 $host|" || die "Can't open $ping: $!\n";

print L "# Host: $host\n";

while (<P>) {
  if (/^64/) {
# isolate millisecond output from ping
    $a = (split)[6];
    ($b, $ms) = split /=/, $a;
    print L "$ms | ", scalar gmtime, "\n";
    &flush(L);
    
# calculate percent signal strength based of reference
    $percent = 100 - ($ms * ($ref / 100));
    $percent = abs $percent;
    $chars = ($width / 100) * $percent;
    
# make pretty and range checks
    if ($ms < $ref) {
      $chars = 80;
    }
    else {
      $chars = sprintf "%1.0f", $chars;
    }
    
    if ($chars > $width) {
      $chars = 0;
    }
    
    if ($ms < $ref) {
      $percent = "100.0";
    }
    else {
      $percent = sprintf "%.1f", $percent;
    }
    
    if ($percent > 100) {
      if ($color) {
        $percent = "$red lost link$clr";
      }
      else {
        $percent = "lost link";
      }
    }
    
# print it
    if ($color) {
      print "\33[H\33[J".
            "\n\t\t\t$cyn Signal Strength Meter $clr\n\n\n\n".
            "Ping signal strength: $bld$percent$clr %   ($bld$ms$clr ms)".
            "   Host: $bld$host$clr\n\n";
      print "0%", " " x 74, "100%\n", "|", " " x 78, "|";
    }
    else {
      print "\33[H\33[J".
            "\n\t\t\tSignal Strength Meter\n\n\n\n".
            "Ping signal strength: $percent %   ($ms ms)".
            "   Host: $host\n\n";
      print "0%", " " x 74, "100%\n", "|", " " x 78, "|";
    }
    
# bar graph
    for ($i = $chars; $i != 0; $i--) {
      if ($color) {
        print "$bld#";
      }
      else {
        print "#";
      }
    }
    
    if ($beep) {
      print "$clr\n\n\n\a";
    }
    else {
      print "\n\n\n";
    }
    
    if ($speak) {
      $ms = sprintf "%1.0f", $ms;
      #($a,$b,$c) = split(/ */, $ms);
      #system "$say -q -f 9 -x 1250 $a $b $c >/dev/null";
      system "$say -q -f 9 -x 1250 $ms >/dev/null";
    }
  }
}

close L;
close P;
