#!/bin/sh

### BEGIN INIT INFO
# Provides:          mwavem
# Required-Start:    $local_fs $syslog
# Required-Stop:     $local_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Mwave modem support daemon
# Description:       Mwave modem support daemon
### END INIT INFO

#
# Initscript for mwavem
#
# Written by Thomas Hood <jdthood_AT_yahoo.co.uk>
# This file is part of the Debian mwavem package

MYNAME="/etc/init.d/mwavem"
MODULENAME=mwave
DESC="Mwave modem support"
DAEMONNAME=mwavemd
DAEMONPATHNAME="/usr/sbin/mwavemd"
PIDFILE=/var/run/mwavemd.pid
MWAVEMANAGERPATHNAME="/usr/sbin/mwavem"
MWAVEMANAGERNICENESS="-15"
MWAVEMANAGERCONFPATHNAME="/etc/mwavem/mwavem.conf"
MWDEV="/dev/mwave"
SERDEV="/dev/ttyS1"
LINK="/dev/Mwave-modem"

[ -x "$DAEMONPATHNAME" ] || exit 0
[ -x "$MWAVEMANAGERPATHNAME" ] || exit 0

. /lib/lsb/init-functions

# $1 EXITSTATUS
log_end_msg_and_exit()
{
	log_end_msg "$1"
	exit $1
}

# Return:
#   0 Got value (in UART_IO)
#   1 Did not get value
get_UART_IO()
{
	# The mwave driver in 2.4 kernels provides /proc/mwave
	if [ -e /proc/mwave ] ; then
		UART_IO_LINE="$(grep -m1 UART_IO /proc/mwave)"
		[ "$UART_IO_LINE" ] || return 1
		set $UART_IO_LINE
		UART_IO="$2"
	# The mwave driver in early 2.6 kernels provides /sys/devices/mwave/
	elif [ -e /sys/devices/mwave/uart_io ] ; then
		UART_IO_LINE="$(cat /sys/devices/mwave/uart_io)"
		[ "$UART_IO_LINE" ] || return 1
		set $UART_IO_LINE
		UART_IO="$1"
	else
		return 1
	fi
}

# Return:
#   0 Got value (in TTYXX)
#   1 Did not get value
get_TTYXX()
{
	get_UART_IO || return 1
	case "$UART_IO" in
	  "") return 1 ;;
	  0x03f8) TTYXX=ttyS0 ;;
	  0x02f8) TTYXX=ttyS1 ;;
	  0x03e8) TTYXX=ttyS2 ;;
	  0x02e8) TTYXX=ttyS3 ;;
	esac
	return 0
}


report_check() { echo "    $*" ; }

# Return:
#   0 OK
#   1 not OK
#   2 could not tell
# Print messages too
check_tty()
{
	get_TTYXX || { report_check "Could not discover tty device name" ; return 2 ; }
	[ -x "$(which setserial 2>/dev/null)" ] || { report_check "Cannot read tty resource configuration because setserial command not available" ; return 2 ; }
	set $(setserial /dev/$TTYXX)
	TTY_UART=${3%,}
	TTY_IO=${5%,}
	TTY_IRQ=$7
	if [ -e /proc/mwave ] ; then
		set $(grep -m1 UART_IO /proc/mwave)
		MWM_IO=$2
		set $(grep -m1 UART_IRQ /proc/mwave)
		MWM_IRQ=$2
	elif [ -e /sys/devices/mwave/uart_io ] ; then
		set $(cat /sys/devices/mwave/uart_io)
		MWM_IO=$1
		set $(cat /sys/devices/mwave/uart_irq)
		MWM_IRQ=$1
	else
		report_check "Cannot read Mwave resource configuration"
		return 2
	fi
	if [ "$TTY_UART" != 16550A ] && [ "$TTY_UART" != unknown ] ; then
		report_check "$TTYXX UART is invalid"
		return 1
	fi
	if [ "$TTY_IO" != "$MWM_IO" ]; then
		report_check "Mwave's IO $MWM_IO does not match $TTYXX IO $TTY_IO"
		return 1
	fi
	if [ "$TTY_IRQ" != "$MWM_IRQ" ]; then
		report_check "Mwave's IRQ $MWM_IRQ does not match $TTYXX IRQ $TTY_IRQ"
		return 1
	fi
	report_check "TTY configuration OK"
	return 0
}

# Return:
#   0 OK
#   1 not OK
check_process()
{
	if [ -f "$PIDFILE" ] && pidof -x "$DAEMONPATHNAME" >/dev/null 2>&1 ; then
		report_check "Support process running"

		return 0
	else
		report_check "Support process not running"
		return 1
	fi
}

case "$1" in
  start)
	log_daemon_msg "Starting $DESC"
	# Do not remove $LINK here because daemon may already be running.
	# Check for the mwave device
	for w in 0 1 2 3 4 giveup ; do
		if [ "$w" = "giveup" ] ; then
			log_progress_msg "(timed out waiting for mwave device file to be created)"
			log_end_msg_and_exit 1
		fi
		[ -c "$MWDEV" ] && break
		sleep 1
	done
	# Check serial device configuration if possible
	check_tty >/dev/null || { case "$?" in (1) log_progress_msg "(failed serial device configuration check)" ; log_end_msg_and_exit 1 ;; esac ; }
	[ "$TTYXX" ] && SERDEV="/dev/${TTYXX}"
	# Check for the serial device file
	[ -c "$SERDEV" ] || { log_progress_msg "(failed serial device presence check)" ; log_end_msg_and_exit 1 ; }
	# Start $DAEMONPATHNAME which creates $PIDFILE containing its own process i.d.
	# and symbolically links $LINK to $SERDEV if and when the modem is ready.
	if start-stop-daemon --test --start --pidfile "$PIDFILE" --startas "$DAEMONPATHNAME" --background >/dev/null 2>&1 ; then
		if ! start-stop-daemon --start --pidfile "$PIDFILE" --startas "$DAEMONPATHNAME" --background -- \
			"$SERDEV" "$LINK" "$PIDFILE" "$MWAVEMANAGERPATHNAME" "$MWAVEMANAGERCONFPATHNAME" "$MWDEV" "$MWAVEMANAGERNICENESS"
		then
			log_progress_msg "(did not start)"
			log_end_msg_and_exit 1
		fi
	else
		log_progress_msg "(already started)"
		log_end_msg_and_exit 0
	fi
	# start-stop-daemon succeeded in starting $DAEMONPATHNAME
	#
	# Wait for either:
	# thirty seconds to elapse, or
	# $DAEMONPATHNAME to exit without creating $LINK (due to some error), or
	# $LINK to be created, indicating that the modem is ready to use.
	DAEMON_STARTED=0
	for w in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 timeout ; do
		if [ "$w" = "timeout" ] ; then
			log_progress_msg "(timed out waiting for daemon to start)"
			log_end_msg_and_exit 1
		fi
		if [ -h "$LINK" ] ; then
			log_progress_msg "$DAEMONNAME"
			log_end_msg_and_exit 0
		fi
		PIDOF_MWAVEMD="$(pidof -x "$DAEMONPATHNAME")"
		if [ "$PIDOF_MWAVEMD" ] ;  then
			DAEMON_STARTED=1
		else
			# Daemon is not running
			if [ "$DAEMON_STARTED" = 0 ] ; then
				log_progress_msg "(did not start)"
			else
				log_progress_msg "(aborted early)"
			fi
			log_end_msg_and_exit 1
		fi
		sleep 1
	done
	log_failure_msg "Programming error"
	exit 99   # We shouldn't ever reach here
	;;
  stop)
  	EXITSTATUS=0
	log_daemon_msg "Stopping $DESC"
	if start-stop-daemon --test --stop --quiet --pidfile "$PIDFILE" >/dev/null 2>&1 ; then
		start-stop-daemon --stop --quiet --pidfile "$PIDFILE"
		# daemon was sent signal 15.  Wait for it to die.
		for w in 0 1 2 3 giveup ; do
			if [ "$w" = "giveup" ] ; then
				log_progess_msg "(timed out waiting for daemon to exit) KILLing: $DAEMONNAME"
				EXITSTATUS=1
				kill -s KILL "$(pidof $DAEMONPATHNAME)" >/dev/null 2>&1
				break
			fi
			if [ ! -f "$PIDFILE" ] ; then
				log_progess_msg "$DAEMONNAME"
				break
			fi
			sleep 1
		done
	else
		log_progress_msg "(no daemon running)"
	fi
	kill -s KILL "$(pidof $MWAVEMANAGERPATHNAME)" >/dev/null 2>&1  # Just to make sure
	rm -f "$PIDFILE" "$LINK"   # Just to make sure
	log_end_msg_and_exit $EXITSTATUS
	;;
  restart|reload|force-reload)
  	EXITSTATUS=0
	$0 stop || EXITSTATUS=1
	$0 start || EXITSTATUS=1
	exit $EXITSTATUS
	;;
  check)
	log_action_msg "Start check of $DESC"
	EXITSTATUS=0
	check_tty || EXITSTATUS=1
	check_process || EXITSTATUS=1
	log_action_msg "End check of $DESC"
	exit $EXITSTATUS
	;;
  *)
	echo "Usage: $MYNAME {start|stop|restart|reload|force-reload|check}" >&2
	exit 3
esac
