#!/usr/bin/perl -w use strict; use Device::SerialPort; use ControlX10::CM11; use Net::Ping; use Net::Syslog; use POSIX; # DAEMON stuff my $pid=fork; exit if $pid; die "Couldn't fork: $!" unless defined $pid; POSIX::setsid() or die "Can't start a new session: $!"; # end DAEMON stuff my $s=new Net::Syslog(Facility=>'local5', Priority=>'notice', Name=>'dslmonitor'); $SIG{TERM}=sub { $s->send('DSL monitoring stopping'); exit; }; $s->send('DSL monitoring started'); my $i; my $m; my $ctr=0; my $tdown; while(1){ $m=is_modem_up(); if(!$m){ $s->send("modem not responding to ping"); } $i=is_internet_up() if(($ctr==0)||(!$m)); if((!$i)||(!$m)){ $s->send('lost internet connection'); $tdown=time(); } while((!$i)||(!$m)){ $s->send('stopping pppoe'); stop_pppoe(); $m=0; while(!$m){ $s->send('power cycling DSL modem'); power_cycle_modem(); $s->send('power cycling complete, waiting for modem to respond to ping'); my $b=time; my $tdiff=time()-$b; while(($tdiff<30)&&(!$m)){ sleep 1; $m=is_modem_up(); $tdiff=time()-$b; } if($m){ $s->send("modem up $tdiff sec after cycle\n"); }else{ $s->send("modem not responding to pings $tdiff seconds after reboot, power cycle modem again"); } } $s->send("waiting 30 seconds for modem DSL negotiation to occur"); sleep 30; $s->send("starting pppoe"); start_pppoe(); $s->send("pppoe start complete, waiting 5 seconds"); sleep 5; $s->send("probing for connectivity"); $i=is_internet_up(); $m=is_modem_up(); if(!$m){ $s->send("modem not responding to ping"); } if(($i)&&($m)){ $tdown=time()-$tdown; my $se=$tdown%60; my $m=(int($tdown/(60)))%60; my $h=(int($tdown/(60*60)))%24; my $d=(int($tdown/(60*60*24))); $s->send("internet connection restored after $d days, $h hours, $m minutes and $se seconds of downtime"); }else{ $s->send("pppoe negotiation failed"); } } sleep 30; $ctr=($ctr+1)%10; } sub is_modem_up{ my $p=new Net::Ping("icmp"); for(my $c=0;$c<3;$c++){ my $i=$p->ping('10.0.0.1',2);; return $i if($i); } return 0; } sub is_internet_up{ my $p=new Net::Ping("icmp"); my @inethosts=('192.5.5.241','202.12.27.33','128.63.2.53'); for(my $c=0;$c<3;$c++){ foreach(@inethosts){ my $i= $p->ping($_,5); return $i if($i); } } $s->send("internet not responding to ping"); return 0; } sub stop_pppoe{ system '/etc/rc.d/init.d/adsl stop >/dev/null 2>/dev/null'; } sub start_pppoe{ system '/etc/rc.d/init.d/adsl start >/dev/null 2>/dev/null'; # checking output would be a good idea } sub power_cycle_modem{ #my $serial_port = new Device::SerialPort('/dev/x10'); my $serial_port = new Device::SerialPort('/dev/ttyS0'); if(!defined $serial_port){ die "error openign serial \"$!\""; } $serial_port->baudrate(4800); $serial_port->databits(8); $serial_port->parity('none'); $serial_port->stopbits(1); $serial_port->handshake('none'); $serial_port->stty_echo(0); $serial_port->read_const_time(5000); $serial_port->read_char_time(5); &ControlX10::CM11::send($serial_port, 'B1'); &ControlX10::CM11::send($serial_port, 'BK'); sleep 5; &ControlX10::CM11::send($serial_port, 'B1'); &ControlX10::CM11::send($serial_port, 'BJ'); }