#!/bin/sh

# Resetator management
# Copyright (c) Belgarat @klfree.net
# Use is subject to the Klfree Debian License terms.
# 
# The resetator documentation can be found at
# 	https://twiki.klfree.net/twiki/bin/view/SpravaSite/VyrobaResetatoru
# The HW resetator and its controlling sw is Copyright (c) Joe Hlavac, joe@hw.cz

### BEGIN INIT INFO
# Provides:          resetator
# Required-Start:    mountkernfs mountall
# Required-Stop:
# Default-Start:     S
# Default-Stop:
### END INIT INFO

CONFIGFILE=/etc/default/resetator
PIDFILE=/var/run/resetator.pid
STATEFILE=/var/state/resetator

WATCHDOG_FILE=/dev/watchdog
RESETATOR_TTY=/dev/ttyS1
RESETATOR_TTY_SETTINGS="2400 -inpck cs8 -crtscts -clocal -parenb -icanon -iexten -isig"

if [ -r $CONFIGFILE ] ; then
    . $CONFIGFILE
fi

print_help() {
echo <<HELP
resetator start|stop|reboot|suspend|resume

start - starts a daemon process, which feeds the resetator with \"I am alive\" 
	signal
stop  - stops the daemon, which causes the resetator to react after some time
suspend - suspends the resetator for 15 minutes
resume - resumes normal (one minute) operation
reboot - immediate, brute-force reboot.
HELP
}

suspend() {
    stty -F $RESETATOR_TTY $RESETATOR_TTY_SETTINGS
    echo "Suspending watchdog for 15 minutes"
    logger -p local0.notice "HW watchdog suspended for 15 minutes"
    echo -ne "RST0" > $RESETATOR_TTY
    echo "`date`" > $STATEFILE
}

resume() {
    stty -F $RESETATOR_TTY $RESETATOR_TTY_SETTINGS
    echo "Resuming watchdog operation"
    logger -p local0.notice "HW watchdog operation was resumed"
    echo -ne "RST1" > $RESETATOR_TTY
    rm -f $STATEFILE
}

reboot() {
    stty -F $RESETATOR_TTY $RESETATOR_TTY_SETTINGS
    echo "Rebooting using HW watchdog !" | wall
    logger -p local0.notice "Rebooting using HW watchdog"
    echo -ne "RSET" > $RESETATOR_TTY
}

control_loop() {
echo "Starting resetator control loop..."
echo $$ > $PIDFILE
stty -F $RESETATOR_TTY $RESETATOR_TTY_SETTINGS
watchinit=
while true; do
    if [ -z "$watchinig" -a -n "$WATCHDOG_FILE" -a -w "$WATCHDOG_FILE" ] ; then
	exec 10>$WATCHDOG_FILE
	watchinig=1
    fi
    if [ -n "$RESETATOR_TTY" ] ; then
	sleep 5
	echo -ne "LIVE" > $RESETATOR_TTY && {
	    [ "$RESETATOR_LOG_ACK" eq 1 ] && logger -p local0.notice -t "resetator" "Resetator ACK"
	}
    fi
    if [ -n "$WATCHDOG_FILE" -a -w "$WATCHDOG_FILE" ] ; then
	# Have to write "V", otherwise the softdog complains
	# about unexpected closes.
	echo -n "*" >&10 2> /dev/null
    fi
    sleep 10
done
}

case "$1" in
loop)
    control_loop
    ;;
    
start)
    echo "Starting resetator control..."
    echo "INFO: The HW watchdog control was started" | wall
    start-stop-daemon --background --start --quiet --pidfile $PIDFILE --exec /etc/init.d/resetator -- loop
    echo "."
    ;;
    
stop)
    echo "Stopping resetator control loop..."
    echo "WARNING: The HW watchdog control has been stopped." | wall
    logger -p local0.info "HW watchdog control stopped, reboot is expected shortly"
    start-stop-daemon --signal TERM --stop --quiet --pidfile $PIDFILE && rm $PIDFILE
    echo "."
    ;;
    
status)
    if [ -r $PIDFILE ] ; then
	echo "Running..."
    else
	echo "Stopped."
    fi
    if [ -r $STATEFILE ] ; then
	datestart=`cat $STATEFILE`
	seconds=`date --date "$datestart" +%s`
	newseconds=$(($seconds + 15 * 60))
	echo "The watchdog was suspended for until " `date -d "1970-01-01 UTC $newseconds seconds"`
    fi
    ;;
suspend)
    suspend
    ;;

resume)
    resume
    ;;
restart)
    /etc/init.d/resetator stop 
    /etc/init.d/resetator start
    ;;
reboot)
    reboot
    ;;
*)
    print_help
    ;;
esac
