#!/usr/bin/perl -w
#
#====================================
#
#  Fulko van Westrenen
#  Umantec, 2005
#
#  http://www.umantec.nl/varia/
#
#  A very simple programme to use a Speedtouch ADSL Modem
#  with ADSL Time: connecting and disconnecting
#
#  Perl 5
#    2 modules:
#    Perl/Tk
#    Net-Telnet (CPAN, Debian package: libnet-telnet-perl)

#  Tested with a Speedtouch 510 V4.2.3 en Debian GNU/Linux 3.1 (Sarge)
#  Uses a telnet connection with the modem
#
#  Will disconnect at startup.
#  Will disconnect after a user selectable time.
#
#  Watch-out: the programme may not disconnect properly with
#  -logout
#  -shutdown
#  -when killing the programme


#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
#  The GNU General Public License is also available from
#  http://www.gnu.org/licenses/licenses.html#GPL
#

#  history:
#  Version 0.1, 1 June 2005
#  Version 0.2, 7 June 2005: ADSL-login info in script
#  Version 0.3, 8 June 2005: Alarm 30 second before disconnect
#  Version 0.3.1 14 June 2005: translated to English
#
#====================================

#set these for your situation
my $user='my_modem_login'; #modem username
my $passw='my_modem_password'; #modem password
my $adsl_user='my_adsl_login'; #ADSL username
my $adsl_password='my_adsl_password'; #ADSL password
my $ip='10.0.0.138'; #modem ip-number
my $maxtime=1200; #max connect time (seconds)
my $warntime=30; #warning before disconnect

#--------------------------
# code
#--------------------------

#normally there is no need to change anything below this point
my $starttime=0;
my $cpoll=0; #poll-count
my $selected_status=0;
my $actual_status=0;
my $overtime=0;

use Net::Telnet();
my $SpeedTouch = new Net::Telnet( Timeout=>10, Prompt=>'/=>/');

use Tk;
my $mw = MainWindow->new;
my $fs = $mw->Label(-textvariable => \$time,
                   -justify => 'center',
                   -foreground => 'white',
                   -background => 'black',
                  );
my $bc = $mw->Button(-text=>"on", -command=>sub{&do_connect});
my $bd = $mw->Button(-text=>"off", -command=>sub{&do_disconnect});

$fs->grid(-row=>0,-column=>0,-columnspan=>2,-sticky=>'nsew');
$bc->grid(-row=>1,-column=>0,-sticky=>'nsew');
$bd->grid(-row=>1,-column=>1,-sticky=>'nsew');

&do_set_adsl_login;
&do_disconnect;
&get_status;

$mw->repeat(1000 => \&update_display); #poll 1/s
MainLoop;

sub update_display{
  my $tdiff=time-$starttime;
  if ($actual_status==1) {
    if ($tdiff>($maxtime-$warntime)) { 
      #alarm 30 second before disconnect
      if ($overtime==0) {
        &do_overtime;
      }
    }
    if ($tdiff>$maxtime) {
      &do_disconnect;
    }
    if ($selected_status==1) {
      $time=hms($tdiff)
    } 
  }
  else {
    $time=' -.--:--';
  }
  if ($selected_status != $actual_status) {
    $time='waiting';
    $starttime=time;
    &get_status;
  }
  if ($cpoll--<=0) {
    &get_status;
    $cpoll=5;
  }
}

sub get_status{
  $SpeedTouch->open("$ip");
  $SpeedTouch->login("$user", "$passw");
  @lines = $SpeedTouch->cmd( "pppoa iflist");
  foreach ( @lines ) {
    chomp;
    s/^ +//;
    @fields = split/\s\s+/;
    if ((scalar(@fields)>2)&&( $fields[1] =~ /oper state/ )) {
      if ($fields[1] =~ /down/){
        $actual_status=0;
        $fs->configure(-foreground => 'white',
                       -background => 'black');
      } elsif ($overtime==0) {
        $actual_status=1;
        $fs->configure(-foreground => 'black',
                       -background => 'green');
      } else {
        $actual_status=1;
        $fs->configure(-foreground => 'black',
                       -background => 'red');
      }
    }
  }
  $SpeedTouch->cmd(String=>"exit", Errmode=>"return");
  $SpeedTouch->close;
}

sub hms {
  my $sec=$_[0];
  my ($h,$m,$s)=(0,0,0);
  $h=int($sec/3600.0);
  $sec=$sec%3600;
  $m=int($sec/60.0);
  $sec=$sec%60;
  $s=int($sec);
  return sprintf "%2d.%02d:%02d",$h,$m,$s;
}

sub do_overtime{
  $mw->bell;
  $bc->configure(-text=>"cnt");
  $fs->configure(-foreground => 'black',
                 -background => 'red');
  $overtime=1;
}

sub do_connect{
  $SpeedTouch->open("$ip");
  $SpeedTouch->login("$user", "$passw");
  $SpeedTouch->cmd( "pppoa ifattach intf=PPPoA_1");
  $selected_status=1;
  $SpeedTouch->close;
  if ($overtime==1){
    $bc->configure(-text=>"on");
    $overtime=0;
    $starttime=time;
  }
}

sub do_disconnect{
  $SpeedTouch->open("$ip");
  $SpeedTouch->login("$user", "$passw");
  $SpeedTouch->cmd( "pppoa ifdetach intf=PPPoA_1");
  $selected_status=0;
  $SpeedTouch->close;
  if ($overtime==1){
    $bc->configure(-text=>"on");
    $overtime=0;
  }
}

sub do_set_adsl_login{
  $SpeedTouch->open("$ip");
  $SpeedTouch->login("$user", "$passw");
  $SpeedTouch->cmd( "pppoa ifconfig intf=PPPoA_1 user=$adsl_user password=$adsl_password");
  $SpeedTouch->close;
}

END{
  &do_disconnect;
}
