#!/bin/sh
MAIN_PATH="/sys/class/bypass"
NORMAL="Normal"
NONNORMAL="Non-Normal"
BYPASS="Bypass"
OPEN="Open"
PASS=("1" "2" "3" "5" "10" "19" "38" "76" "154" "305")
BYPASS_SEG=""
RMODEL=("normal" "open" "bypass")
NMODEL=("normal" "non-normal")
ret=0

#For sysfs cmd
SET_NORMAL="n"
SET_OPEN="o"
SET_BYPASS="b"
SET_NB_NORMAL=0
SET_NB_NO_NORMAL=1
SET_BPE_OPEN=0
SET_BPE_BYPASS=1
WDT_DISABLE=0
WDT_ARM_REFRESH=1
WDT_CLEAR=0
WDT_ENABLE=1
WDT_NOT_OCCUR=0
WDT_OCCUR=1

print_help()
{
	#clear
	echo ""
	echo "Bypass Tool functionality usage:"
	echo "  sh bypass_tool.sh <segment> [command] [option]"
	echo ""
	echo "segment: segment index in bypass address"
	for i in `seq 0 $(( BYPASS_SEG - 1 ))`
	do
		echo "  segment: $i"
	done
	echo "[command]"
	echo "  -f [option] => Force the card into (bypass/normal/open) relay mode"
	echo "  -s => Display the current relay status (normal/open/bypass)"
	echo "  -d [option] => Set the default failure mode (open/bypass)"
	echo "  -m => Display the default mode set by the '-d' command"
	echo "  -b [option] => Set the system into (normal/nonormal) mode at next boot up"
	echo "  -p ==> Display the next-boot relay status(normal or abnormal)."
	echo "  -w [value] => Set the watchdog timer to value"
	echo "  -a => Arm or refresh the watchdog timer"
	echo "  -r => Reset the watchdog flag value of WDT"
	echo "  -c => Disarm watchdog and stay in current state/mode"
	echo "  -g => Display watchdog flag value && WDT status"
	echo "[option]"
	echo "  bypass   => bypass relay mode"
	echo "  open     => open relay mode"
	echo "  normal   => normal relay mode"
	echo "  non-normal => normal relay mode"
}

print_bypass_status()
{
	case $1 in
		$SET_NORMAL)
			echo $NORMAL;;
		$SET_BYPASS)
			echo $BYPASS;;
		$SET_OPEN)
			echo $OPEN;;
	esac
}

print_bpe_status()
{
	case $1 in
		$SET_BPE_OPEN)
			echo $OPEN;;
		$SET_BPE_BYPASS)
			echo $BYPASS;;
	esac
}

print_nextboot_status()
{
	case $1 in
		$SET_NB_NORMAL)
			echo $NORMAL;;
		$SET_NB_NO_NORMAL)
			echo $NONNORMAL;;
	esac
}

print_wdt_status()
{
	case $1 in
		$WDT_NOT_OCCUR)
			echo "WDT time-out not occur";;
		$WDT_OCCUR)
			echo "WDT time-out occur";;
	esac
}

init_valus()
{

	BYPASS_SEG=$(ls ${MAIN_PATH} | wc -l)
}

set_bypass(){
	case $2 in
		"normal")
			echo $SET_NORMAL > ${MAIN_PATH}/g3bp$1/bypass
			[ $? = 1 ] && echo "write fail";;
		"bypass")
			echo $SET_BYPASS > ${MAIN_PATH}/g3bp$1/bypass
			[ $? = 1 ] && echo "write fail";;
		"open")
			echo $SET_OPEN > ${MAIN_PATH}/g3bp$1/bypass
			[ $? = 1 ] && echo "write fail";;
		*)
			echo "Incorrect input options";;
	esac
}

get_bypass(){
	ret="$(cat ${MAIN_PATH}/g3bp$1/bypass)"
	[ $? = 1 ] && echo "read fail" && exit 1
	print_bypass_status $ret
}

set_bpe(){
	case $2 in
		"bypass")
			echo $SET_BPE_BYPASS > ${MAIN_PATH}/g3bp$1/bpe
			[ $? = 1 ] && echo "write fail" && exit 1
			;;
		"open")
			echo $SET_BPE_OPEN > ${MAIN_PATH}/g3bp$1/bpe
			[ $? = 1 ] && echo "write fail" && exit 1
			;;
		*)
			echo "Incorrect input options";;
	esac
}

get_bpe(){
	ret="$(cat ${MAIN_PATH}/g3bp$1/bpe)"
	[ $? = 1 ] && echo "read fail" && exit 1
	print_bpe_status $ret
}

set_nextboot(){
	case $2 in
		"normal")
			echo $SET_NB_NORMAL > ${MAIN_PATH}/g3bp$1/nextboot
			[ $? = 1 ] && echo "write fail" && exit 1;;
		"non-normal")
			echo $SET_NB_NO_NORMAL > ${MAIN_PATH}/g3bp$1/nextboot
			[ $? = 1 ] && echo "write fail" && exit 1;;
		*)
			echo "Incorrect input options";;
	esac
}

get_nextboot(){
	ret="$(cat ${MAIN_PATH}/g3bp$1/nextboot)"
	[ $? = 1 ] && echo "read fail" && exit 1
	print_nextboot_status $ret
}

set_wdt(){
	case $2 in
		"disable")
			echo $WDT_DISABLE > ${MAIN_PATH}/g3bp$1/wdt
			[ $? = 1 ] && echo "write fail" && exit 1;;
		"clear")
			echo $WDT_CLEAR > ${MAIN_PATH}/g3bp$1/timeout
			[ $? = 1 ] && echo "write fail" && exit 1;;
		"refresh")
			echo $WDT_ARM_REFRESH > ${MAIN_PATH}/g3bp$1/wdt
			[ $? = 1 ] && echo "write fail" && exit 1;;
		*)
			echo "Incorrect input options";;
	esac
}

set_period(){
	echo $2 > ${MAIN_PATH}/g3bp$1/period
	[ $? = 1 ] && echo "write fail && exit 1"
}

get_wdt(){
	ret="$(cat ${MAIN_PATH}/g3bp$1/timeout)"
	[ $? = 1 ] && echo "read fail" && exit 1
	print_wdt_status $ret
}

bypass_test()
{
	echo "Force the card into (normal/open/bypass) relay mode"
	echo "Bypass Segment X     status:				result"
	for i in `seq 0 $(( BYPASS_SEG - 1 ))`
	do
		status=0
		echo -n "Bypass Segment g3bp$i status: "
		for j in 0 1 2
		do
			set_bypass $i ${RMODEL[$j]}
			sleep  0.03
			get_bypass $i >/dev/null 2>&1
			echo -n "$(get_bypass $i) "
		case $ret in
			$SET_NORMAL)
				mode=${RMODEL[0]};;
			$SET_OPEN)
				mode=${RMODEL[1]};;
			$SET_BYPASS)
				mode=${RMODEL[2]};;
		esac
		[ $? = 0 ] || status=$((status+1))
		[ $mode != ${RMODEL[$j]} ] && status=$((status+1))
	done
	[ $status = 0 ] && echo "	[PASSED]" ||echo "	[FAILED]"
		status=0
	done
}

bpe_test(){
	echo "Set the default failure (Open/Bypass) mode"
	echo "Bypass Segment X     status:				result"
	for i in `seq 0 $(( BYPASS_SEG - 1 ))`
	do
		status=0
		echo -n "Bypass Segment g3bp$i status: "
		for j in 0 1 
		do
			set_bpe $i ${RMODEL[$((j+1))]}
			sleep  0.5
			get_bpe $i >/dev/null 2>&1
			echo -n "$(get_bpe $i) "
			[ $? = 0 ] || status=$((status+1))
			[ $ret != $j ] && status=$((status+1))
		done
		[ $status = 0 ] && echo "		[PASSED]" ||echo "		[FAILED]"
	done
}

nextboot_test(){
	status=0
	echo "Set the system into (non_normal/normal) mode at next boot up"
	echo "Bypass Segment X     status:				result"
	for i in `seq 0 $(( BYPASS_SEG - 1 ))`
	do
		echo -n "Bypass Segment g3bp$i status: "
		for j in 1 0 
		do
			set_nextboot $i ${NMODEL[$j]}
			sleep 0.5
			get_nextboot $i >/dev/null 2>&1
			echo -n "$(get_nextboot $i) "
			[ $? = 0 ] || status=$((status+1))
			[ $ret != $j ] && status=$((status+1))
		done
		[ $status = "0" ] && echo "		[PASSED]" ||echo "		[FAILED]"
	done
}

test_all_wdt(){
	case $1 in
		all)
			segment=`seq 0 $(( BYPASS_SEG - 1 ))`
		;;
		*)
			segment=$1
		;;
	esac
	echo "Set period and arm wdt test timer"
	echo "Bypass Segment X     parameter=X run time=X		result"
	for i in $segment
	do
		status=0
		case $2 in
		all)
			seg=63
			period=`seq 1 $seg`
			;;
		[1-9]*)
			period=$2
			;;
		esac
		for j in $period
		do
			PERIOD=$j
			#clear timeout bit
			set_wdt $i clear >/dev/null 2>&1
			get_wdt $i >/dev/null 2>&1
			[ $ret != 0 ] && status=$((status+1)) && exit 1
			#set period value
			set_period $i $j
			echo -n "Bypass Segment g3bp$i parameter=$j run time="
			#refersh wdt
			set_wdt $i refresh
			start=$(date +%s)
			sleep $((${PASS[$((j-1))]}*1))
			stop=$(date +%s)
			get_wdt $i >/dev/null 2>&1
			[ $ret = 0 ] \
			&& PASS_NO=FAILED || PASS_NO=PASSED
			echo "$((stop-start))		[$PASS_NO]"
			[ $ret = 0 ] && status=$((status+1)) && exit 1
		done
	done
}

test_wdt(){
	if [ -z $1 ] ; then
		 test_all_wdt all 4
	else
	test_all_wdt $1 $2
	fi
}

default_setting()
{
    for i in `seq 0 $(( BYPASS_SEG - 1 ))`
    do
        set_bypass $i normal
        set_wdt $i clear
        sleep 0.03
    done
}

test_all_func(){
	bypass_test
	bpe_test
	nextboot_test
	test_wdt
	default_setting
}

function_select()
{
	[ "$1" = "-h" ] || [ "$1" = "" ] && print_help && exit 1

	if [ "$1" = "all" ] ; then
		test_all_func
		exit 1
	fi
	cat ${MAIN_PATH}/g3bp$1/bptype 1>/dev/null
	[ $? != 0 ] && echo "Segment number not found" && exit 1
	case $2 in 
	-f|f)   # Force the card into (bypass/normal/open) relay mode
		set_bypass $1 $3
		;;
	-d|d)   #Set the default failure mode (open/bypass)
		set_bpe $1 $3
		;;
	-b|b)   #Set the system into (normal/nonormal) mode at next boot up
		set_nextboot $1 $3
		;;
	-w|w)   #Set the watchdog timer to a value
		set_period $1 $3
		;;
	-a|a)   #Arm or refresh the watchdog timer
		set_wdt $1 refresh
		;;
	-c|c)   #Disarm watchdog and stay in current state/mode
		set_wdt $1 disable
		;;
	-r|r)   #Reset the watchdog flag value of WDT
		set_wdt $1 clear
		;;
	-s|s)   #Display the current relay status (normal/open/bypass)
		get_bypass $1
		;;
	-g|g)   #Display watchdog flag value && WDT status
		get_wdt $1
		;;
	-m|m)   #Display the default mode set by the '-d' command
		get_bpe $1
		;;
	-p|p)   #Display the next-boot relay status(normal or abnormal)
		get_nextboot $1
		;;
	-h|h)   #Display the help information
		print_help
		;;
	wdt)
		test_wdt $1 $3
		;;
	esac
}
#main
init_valus
function_select $1 $2 $3

