#!/bin/sh
#
# 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

report_err() { echo "${MYNAME}: Error: $*" >&2 ; }

# 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)
	echo -n "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
			echo "(timed out waiting for mwave device file to be created)."
			exit 1
		fi
		[ -c "$MWDEV" ] && break
		sleep 1
	done
	# Check serial device configuration if possible
	check_tty >/dev/null || { case "$?" in (1) echo "(failed serial device configuration check)." ; exit 1 ;; esac ; }
	[ "$TTYXX" ] && SERDEV="/dev/${TTYXX}"
	# Check for the serial device file
	[ -c "$SERDEV" ] || { echo "(failed serial device presence check)." ; 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
			echo "(failed to start)."
			exit 1
		fi
	else
		echo "(already started)."
		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
			echo "(timed out waiting for daemon to start)."
			exit 1
		fi
		if [ -h "$LINK" ] ; then
			echo "${DAEMONNAME}."
			exit 0
		fi
		sleep 1
		PIDOF_MWAVEMD="$(pidof -x "$DAEMONPATHNAME")"
		if [ ! "$PIDOF_MWAVEMD" ] ; then
			if [ "$DAEMON_STARTED" != 0 ] ; then
				echo "(aborted early)."
			else
				echo "(failed to start)."
			fi
			exit 1
		else
			DAEMON_STARTED=1
		fi
	done
	report_err "Programming error"
	exit 99   # We shouldn't ever reach here
	;;
  stop)
  	EXITSTATUS=0
	echo -n "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
				echo "(timed out waiting for daemon to exit) KILLing: $DAEMONNAME."
				EXITSTATUS=1
				kill -9 "$(pidof $DAEMONPATHNAME)" >/dev/null 2>&1
				break
			fi
			if [ ! -f "$PIDFILE" ] ; then
				echo "${DAEMONNAME}."
				break
			fi
			sleep 1
		done
	else
		echo "(no daemon running)."
	fi
	kill -9 "$(pidof $MWAVEMANAGERPATHNAME)" >/dev/null 2>&1  # Just to make sure
	rm -f "$PIDFILE" "$LINK"   # Just to make sure
	exit $EXITSTATUS
	;;
  restart|reload|force-reload)
  	EXITSTATUS=0
	$0 stop || EXITSTATUS=1
	$0 start || EXITSTATUS=1
	exit $EXITSTATUS
	;;
  check)
	echo "Checking ${DESC}..."
	EXITSTATUS=0
	check_tty || EXITSTATUS=1
	check_process || EXITSTATUS=1
	echo "Done checking ${DESC}."
	exit $EXITSTATUS
	;;
  *)
	echo "Usage: $MYNAME {start|stop|restart|reload|force-reload|check}" >&2
	exit 3
esac
