#!/bin/sh

source /ciena/scripts/kernel_arg.sh

KRN_CONF=/mnt/sysfs/system/krn.conf
LEOS_USER_FIFO=/tmp/fifo/mon/saos

if [ -f $KRN_CONF ]; then
    . $KRN_CONF
fi

if [ -z "$KRN_MODE" ]; then KRN_MODE=normal; fi
if [ -z "$KRN_CONSOLE" ]; then KRN_CONSOLE=normal; fi
if [ -z "$KRN_AUTO" ]; then KRN_AUTO=enable; fi
if [ -z "$KRN_RESPAWN" ]; then KRN_RESPAWN=enable; fi

if [ "$(kernel_arg nosaos)" = "nosaos" ]; then
    KRN_MODE=debug;
    KRN_CONSOLE=debug;
    KRN_AUTO=disable;
    KRN_RESPAWN=disable;
fi

stopKrn()
{
    echo "$0: sending stop opcode to $LEOS_USER_FIFO..."
    echo -n 2 > $LEOS_USER_FIFO
}

startKrn()
{
    if [ -r /tmp/fifo/leos/LEOS_IPC_PID ] ; then
	if [ -d /proc/`cat /tmp/fifo/leos/LEOS_IPC_PID` ] ; then
	    echo "SAOS appears to already be running";
	else
	    echo "$0: sending start opcode to $LEOS_USER_FIFO..."
	    echo -n 1 > $LEOS_USER_FIFO
	fi
    else
	echo "$0: sending start opcode to $LEOS_USER_FIFO..."
	echo -n 1 > $LEOS_USER_FIFO
    fi
}

getChoice()
{
    echo -n "$1 [$2] "
    read choice
    case $choice in
    "")
        choice=$2
        return
    ;;
    *)
        for opt in $@; do
            if [ "$opt" = "$choice" ]; then return; fi
        done
        echo "Invalid option: $choice"
        exit 1
    ;;
    esac
}

# Forward collected settings to anyplace that needs them immediately.

propagate()
{
    $0 respawn $KRN_RESPAWN

    if [ -r /tmp/fifo/leos/LEOS_IPC_PID ] ; then
	if [ -d /proc/`cat /tmp/fifo/leos/LEOS_IPC_PID` ] ; then
	    if [ $KRN_CONSOLE = "debug" ]; then
		param swrite 9 1
	    else
		param swrite 9 0
	    fi
	else	# LEOS is not running.
	    if [ $KRN_CONSOLE = "debug" ]; then
		/mnt/apps/bin/saparam swrite 9 1
	    else
		/mnt/apps/bin/saparam swrite 9 0
	    fi
	fi
    else	# LEOS is not running.
	if [ $KRN_CONSOLE = "debug" ]; then
	    /mnt/apps/bin/saparam swrite 9 1
	else
	    /mnt/apps/bin/saparam swrite 9 0
	fi
    fi
}

case "$1" in
set)
    stty icrnl		# Just in case!
    echo "Configure kernel parameters."
    echo "Press <RETURN> for default values, if any."

    getChoice "Kernel Mode (normal,debug) :" $KRN_MODE normal debug
    KRN_MODE=$choice

    getChoice "Serial Port (normal,debug) :" $KRN_CONSOLE normal debug
    KRN_CONSOLE=$choice

    getChoice "AutoStart (enable,disable) :" $KRN_AUTO enable disable
    KRN_AUTO=$choice

    getChoice "Respawn (enable,disable)   :" $KRN_RESPAWN enable disable
    KRN_RESPAWN=$choice

    echo "KRN_MODE=$KRN_MODE" > $KRN_CONF
    echo "KRN_CONSOLE=$KRN_CONSOLE" >> $KRN_CONF
    echo "KRN_AUTO=$KRN_AUTO" >> $KRN_CONF
    echo "KRN_RESPAWN=$KRN_RESPAWN" >> $KRN_CONF
    propagate
;;

show)
    echo "Kernel Mode: $KRN_MODE"
    echo "Serial Port: $KRN_CONSOLE"
    echo "AutoStart  : $KRN_AUTO"
    echo "Respawn    : $KRN_RESPAWN"
;;

# start|stop|kill notes:
#	The monitor process accepts single-character (ASCII) opcodes
#	over a named-pipe.  The pipes are:
#		leos = /tmp/fifo/mon/leos
#
#	The opcodes are:
#		OPCODE	| action		| notes
#		---------------------------------------------------------------
#		0	| kill			| sends SIGKILL
#		1	| start			| launches program
#		2	| stop			| sends SIGTERM
#		3*	| respawn enable	| enable respawn on child death
#		4	| respawn disable	| disable respawn on child death
#
#	* default
kill)
    if [ "$KRN_RESPAWN" = "enable" ]; then
        OPSTRING=403
    else
        OPSTRING=0
    fi
    echo "$0: sending kill opstring $OPSTRING to $LEOS_USER_FIFO..."
    echo -n $OPSTRING > $LEOS_USER_FIFO
;;
restart)
    stopKrn
    startKrn
;;
start)
    startKrn
;;
stop)
    stopKrn
;;
res|respawn)
    case "$2" in
    en|enable|on)
	echo $0: sending respawn $2 opcode to $LEOS_USER_FIFO...
    	echo -n 3 > $LEOS_USER_FIFO
    ;;
    dis|disable|off)
        echo $0: sending respawn $2 opcode to $LEOS_USER_FIFO...
    	echo -n 4 > $LEOS_USER_FIFO
    ;;
    *)
    	echo "invalid argument: $2"
	exit 1
    ;;
    esac
;;
debug)
    case "$2" in
    on)
	if pidof gdbserver >/dev/null ; then
	    echo "Debug process already running, use \"krn debug off\"."
	    exit 1
	fi
	export LEOS_PID=`cat /tmp/fifo/leos/LEOS_IPC_PID 2>/dev/null`
	if [ -z "$LEOS_PID" ]; then
	    echo "Unable to find running leos server process!"
	    exit 1
	fi
	echo "Creating debug process..."
	if [ -c /dev/ttyS2 ] ; then # Not an Artamir class machine.
	    /usr/bin/gdbserver localhost:2159 --attach $LEOS_PID &
	else
	    /usr/bin/gdbserver /dev/ttyS1 --attach $LEOS_PID &
	    sleep 1
	    stty 115200 ixon ixoff </dev/ttyS1
	fi
    ;;
    off)
	if killall -9 gdbserver 2>/dev/null ; then
	    echo "Removing gdbserver debug process..."
	else
	    echo "Debug process gdbserver not running."
	fi
    ;;
    *)
	echo "invalid argument: $2"
	exit 1
    ;;
    esac
;;
getenv)
;;
*)
    echo "Kernel Executive Shell Commands"
    echo "================================================================================"
    echo "krn debug on|off              | enable/disable debug server"
    echo "krn kill                      | kill SAOS server"
    echo "krn restart                   | do stop followed by start"
    echo "krn set                       | configure kernel executive behavior"
    echo "krn show                      | show kernel executive configuration"
    echo "krn start                     | start SAOS server"
    echo "krn stop                      | graceful shutdown of SAOS server"
;;
esac
