#!/bin/sh
I2C=`basename /sys/devices/pci*/*1f.3/i2c*/ | awk -F'-' '{print $NF}'` || I2C=0
MAIN_PATH="/sys/bus/i2c/devices"
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=0
SET_OPEN=1
SET_BYPASS=2
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=2
WDT_ENABLE=3
WDT_NOT_OCCUR=0
WDT_OCCUR=1

print_help()
{
	#clear
	echo ""
	echo "Bypass Tool functionality usage:"
	echo "  sh bypass_tool.sh <address> <segment> [command] [option]"
	echo ""
	echo "address: controller I2C address"
	echo "segment: segment index in bypass address"
	for i in `seq 0 $(( BYPASS_SEG - 1 ))`
	do
		echo -n "  I2C Address=${model[$i]} "
		echo -n "  Model is $(cat /sys/bus/i2c/devices/${I2C}-00${model[$i]}/bp_type) "
		echo "  segment ${m_sel[$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_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()
{
	i=0
	for name in 20 24 21 25 22 26 23 27 74 75 76 77
	do
		cat ${MAIN_PATH}/${I2C}-00${name}/bp_type 1>/dev/null 2>&1
		[ $? = 0 ] && model[$i]=$name && m_sel[$i]=0 && i=$((i+1))
		cat ${MAIN_PATH}/${I2C}-00${name}/bypass1 1>/dev/null 2>&1
		[ $? = 0 ] && model[$i]=$name && m_sel[$i]=1 && i=$((i+1))
	done
	BYPASS_SEG=$i
}

set_bypass(){
	case $3 in
		"normal")
			if [ $2 = 0 ] ;then
				echo $SET_NORMAL > ${MAIN_PATH}/${I2C}-00$1/bypass0
			else
				echo $SET_NORMAL > ${MAIN_PATH}/${I2C}-00$1/bypass1
			fi
			[ $? = 1 ] && echo "write fail";;
		"bypass")
			if [ $2 = 0 ] ;then
				echo $SET_BYPASS > ${MAIN_PATH}/${I2C}-00$1/bypass0
			else
				echo $SET_BYPASS > ${MAIN_PATH}/${I2C}-00$1/bypass1
			fi
			[ $? = 1 ] && echo "write fail";;
		"open")
			if [ $2 = 0 ] ;then
				echo $SET_OPEN > ${MAIN_PATH}/${I2C}-00$1/bypass0
			else
				echo $SET_OPEN > ${MAIN_PATH}/${I2C}-00$1/bypass1
			fi
			[ $? = 1 ] && echo "write fail";;
		*)
			echo "Incorrect input options";;
	esac
}

get_bypass(){
	if [ $2 = 0 ] ;then
		ret="$(cat ${MAIN_PATH}/${I2C}-00$1/bypass0)"
	else
		ret="$(cat ${MAIN_PATH}/${I2C}-00$1/bypass1)"
	fi
	[ $? = 1 ] && echo "read fail" && exit 1
	print_bypass_status $ret
}

set_bpe(){
	case $3 in
		"bypass")
			if [ $2 = 0 ] ;then
				echo $SET_BPE_BYPASS > ${MAIN_PATH}/${I2C}-00$1/bpe0 
			else
				echo $SET_BPE_BYPASS > ${MAIN_PATH}/${I2C}-00$1/bpe1
			fi
			[ $? = 1 ] && echo "write fail" && exit 1
			;;
		"open")
			if [ $2 = 0 ] ;then
				echo $SET_BPE_OPEN > ${MAIN_PATH}/${I2C}-00$1/bpe0 
			else
				echo $SET_BPE_OPEN > ${MAIN_PATH}/${I2C}-00$1/bpe1
			fi
			[ $? = 1 ] && echo "write fail" && exit 1
			;;
		*)
			echo "Incorrect input options";;				
	esac
}

get_bpe(){
	if [ $2 = 0 ] ;then
		ret="$(cat ${MAIN_PATH}/${I2C}-00$1/bpe0)"
	else
		ret="$(cat ${MAIN_PATH}/${I2C}-00$1/bpe1)"
	fi
	[ $? = 1 ] && echo "read fail" && exit 1
	print_bypass_status $((ret+1));			
}

set_nextboot(){
	case $3 in
		"normal")
			if [ $2 = 0 ] ;then
				echo $SET_NB_NORMAL > ${MAIN_PATH}/${I2C}-00$1/nextboot0 
			else
				echo $SET_NB_NORMAL > ${MAIN_PATH}/${I2C}-00$1/nextboot1
			fi
			[ $? = 1 ] && echo "write fail" && exit 1;;
		"non-normal")
			if [ $2 = 0 ] ;then
				echo $SET_NB_NO_NORMAL > ${MAIN_PATH}/${I2C}-00$1/nextboot0 
			else
				echo $SET_NB_NO_NORMAL > ${MAIN_PATH}/${I2C}-00$1/nextboot1
			fi
			[ $? = 1 ] && echo "write fail" && exit 1;;
		*)
			echo "Incorrect input options";;				
	esac
}

get_nextboot(){
	if [ $2 = 0 ] ;then
		ret="$(cat ${MAIN_PATH}/${I2C}-00$1/nextboot0)"
	else
		ret="$(cat ${MAIN_PATH}/${I2C}-00$1/nextboot1)"
	fi
	[ $? = 1 ] && echo "read fail" && exit 1
	print_nextboot_status $ret
}

set_wdt(){
	case $3 in
		"disable")
			if [ $2 = 0 ] ;then
				echo $WDT_DISABLE > ${MAIN_PATH}/${I2C}-00$1/wdt0 
			else
				echo $WDT_DISABLE > ${MAIN_PATH}/${I2C}-00$1/wdt1
			fi
			[ $? = 1 ] && echo "write fail" && exit 1;;
		"clear")
			if [ $2 = 0 ] ;then
				echo $WDT_CLEAR > ${MAIN_PATH}/${I2C}-00$1/wdt0
			else
				echo $WDT_CLEAR > ${MAIN_PATH}/${I2C}-00$1/wdt1
			fi
			[ $? = 1 ] && echo "write fail" && exit 1;;
		"refresh")
			if [ $2 = 0 ] ;then
				echo $WDT_ARM_REFRESH > ${MAIN_PATH}/${I2C}-00$1/wdt0
			else
				echo $WDT_ARM_REFRESH > ${MAIN_PATH}/${I2C}-00$1/wdt1
			fi
			[ $? = 1 ] && echo "write fail" && exit 1;;
		*)
			echo "Incorrect input options";;				
	esac
}

set_period(){
	bp_type=$(cat ${MAIN_PATH}/${I2C}-00$1/bp_type)
	case $bp_type in
		"NAR5650")
		segment=26
		;;
		"ABN484L"|"ABN484")
		[ $1 -ge 24 ] && segment=$(( $1 - 4 )) || segment=$1
		;;
		*)
		segment=$1
		;;
	esac

	if [ $2 = 0 ] ;then
		echo $3 > ${MAIN_PATH}/${I2C}-00$segment/period0
	else
		if [ $bp_type = "ABN1004" ] ; then
			echo $3 > ${MAIN_PATH}/${I2C}-00$segment/period0
		else
			echo $3 > ${MAIN_PATH}/${I2C}-00$segment/period1
		fi
	fi
	[ $? = 1 ] && echo "write fail && exit 1"
}

get_wdt(){
	if [ $2 = 0 ] ;then
		ret="$(cat ${MAIN_PATH}/${I2C}-00$1/timeout0)"
	else
		ret="$(cat ${MAIN_PATH}/${I2C}-00$1/timeout1)"
	fi
	[ $? = 1 ] && echo "read fail" && exit 1
	print_wdt_status $ret
}

bypass_test()
{
	echo "Force the card into (normal/open/bypass) relay mode"
	echo "I2C Address X status: 	result"
        for i in `seq 0 $(( BYPASS_SEG - 1 ))`
        do
        	status=0
                echo -n "I2C Address ${model[$i]} status: "
                for j in 0 1 2
                do
                        set_bypass ${model[$i]} ${m_sel[$i]} ${RMODEL[$j]}
                        usleep  30000
                        get_bypass ${model[$i]} ${m_sel[$i]} >/dev/null 2>&1
                        echo -n "$(get_bypass ${model[$i]} ${m_sel[$i]}) "
                        [ $? = 0 ] || status=$((status+1))
                        [ $j != $ret ] && status=$((status+1))
                done
                [ $status = 0 ] && echo "	PASSED" ||echo "	FAILED"
		status=0
        done
}

bpe_test(){
        echo "Set the default failure (Open/Bypass) mode"
	echo "I2C Address X status: 	result"
        for i in `seq 0 $(( BYPASS_SEG - 1 ))`
        do
        	status=0
                echo -n "I2C Address ${model[$i]} status: "
                for j in 0 1 
                do
                        set_bpe ${model[$i]} ${m_sel[$i]} ${RMODEL[$((j+1))]}
                        usleep  500000
                        get_bpe ${model[$i]} ${m_sel[$i]} >/dev/null 2>&1
                        echo -n "$(get_bpe ${model[$i]} ${m_sel[$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 "I2C Address X status:	result"
        for i in `seq 0 $(( BYPASS_SEG - 1 ))`
        do
                echo -n "I2C Address ${model[$i]} status: "
                for j in 1 0 
                do
                        set_nextboot ${model[$i]} ${m_sel[$i]} ${NMODEL[$j]}
                        usleep 500000
                        get_nextboot ${model[$i]} ${m_sel[$i]} >/dev/null 2>&1
                        echo -n "$(get_nextboot ${model[$i]} ${m_sel[$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 ))` 
		;;
		*)
			for x in `seq 0 $(( BYPASS_SEG - 1 ))`
			do
				if [ ${model[$x]} -eq $1 ] ; then
					segment=$x
				fi 
			done
		;;
	esac
	echo "Set period and arm wdt test timer"
	echo "I2C Address X  parameter=X run time=X result"
	for i in $segment
	do
		status=0
	        case $2 in
        	        all)
                        #set period max
                        type=$(cat ${MAIN_PATH}/${I2C}-00${model[$i]}/bp_type)
                        [ "$type" = "MEB392X" ] || [ "$type" = "ABN1010" ] && seg=10 || seg=63
                        period=`seq 1 $seg`
                        ;;
                	[1-9]*)
                        period=$2
                	;;
        	esac
		for j in $period
		do
		[ "$type" = "MEB392X" ] || [ "$type" = "ABN1010" ] && PERIOD=$((${PASS[$((j-1))]})) || PERIOD=$j
			#clear timeout bit
			set_wdt ${model[$i]} ${m_sel[$i]} clear >/dev/null 2>&1
			get_wdt ${model[$i]} ${m_sel[$i]} >/dev/null 2>&1
			[ $ret != 0 ] && status=$((status+1)) && exit 1
			#set period value
			set_period ${model[$i]} ${m_sel[$i]} $j
			echo -n "I2C Address ${model[$i]} parameter=$j run time="
			#refersh wdt
			set_wdt ${model[$i]} ${m_sel[$i]} refresh
			start=$(date +%s)
			usleep $((${PASS[$((j-1))]}*1000000))
			stop=$(date +%s)
			get_wdt ${model[$i]} ${m_sel[$i]} >/dev/null 2>&1
			[ $ret = 0 ] \
			&& PASS_NO=FAIL || PASS_NO=PASS
			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
}
test_all_func(){
	bypass_test
	bpe_test
	nextboot_test
	test_wdt
}

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

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

