#!/bin/sh
PATH=$PATH:/usr/local/bin
. sig_catcher
#set -x

# this is the value we're returning to the user
# to indicate if the operation worked based on what the programming tool returns
return_code=0
# Sel logging variables, please refer netapp/include/sel.h for more info
# values under sel_component_t & sel_sev_t
SEL_PARAM="SP.notice"
SEL_LOGGER="sel_logger"
BUSY_FLAG="/tmp/UPDATING_FPGA_CPLD_DEVICES"
usage() {
cat << USAGE_HERE
Usage: cpld_program.sh <get_version | program_device> <support_fpga | ebod> <binfile>"
	<get_version> option is for all devices.
		example: cpld_program.sh get_version support_fpga
		example: cpld_program.sh get_version ebod

	<program_device> option is for all devices
		example: cpld_program.sh program_device support_fpga <binfile>
		example: cpld_program.sh program_device ebod <binfile>

USAGE_HERE
}
cleanup_exit()
#$1: exit code
{
	local exit_val=$1
	if [ -f $BUSY_FLAG ];then
		rm -f $BUSY_FLAG
	fi
	exit $exit_val
}
disable_interrupt()
{
	#add the signal number which you want to disable it
	trap "" SIGHUP SIGINT SIGTERM
}
enable_interrupt()
{
	trap handlesignal SIGHUP SIGINT SIGTERM
}

#
# Signal handler, for when the user presses ctrl-c or the process gets a shutdown signal
#
handlesignal() {

    echo "**ctrl-c pressed, stopping**"
        cleanup_exit 1

        trap "echo ctrl-c already pressed, stopping in progress " SIGHUP SIGINT SIGTERM
}


get_device_version()
#1 : target
#2 : a flag to echo
{
	local version=""
	local rev_command=""
	local target=$1
	local echoflag=$2
	local rev_build=0
	case $target in
		support_fpga)
			echo "Retrieving version of support FPGA"
			rev_command=supportfpgatool
			;;
		ebod)
			if [ $platform == "RazorM" ]; then
				echo "Retrieving version of EBOD cpld"
				rev_command=razor_cpld_revisions.sh
			else
				echo "$target not supported for $platform platform."
				cleanup_exit 1
			fi
			;;
		*)  # Default case
			echo "$target not supported for $platform platform."
			usage
			cleanup_exit 1
			;;
	esac #case $target in

	if [ $rev_command ] ; then
		full_rev=$($rev_command --get-revision)
		if [ $echoflag -eq 1 ]; then
				echo $full_rev
		fi
		device_version=$full_rev
	else
		echo "version-unknown"
		device_version="NA"
	fi
}


update_return_code()
#1 : current return code
{
	#if current return code != 0, update it to return_code
	if [ $1 -ne 0 ];then
		return_code=$1
	fi
}
get_file_version()
#1: bin file name
{
	local file_name=""
	local version=""
	file_name=$(echo $1 | cut -d / -f 4)
	file_version=$(echo $file_name | awk -F_ '{printf $NF}'| sed -e 's/rev//g' | sed -e 's/.bin//g')
}

update_image()
# $1 binfile
{
	#Programming the image into the device
	echo "Programming the SFPGA can take some time. Do not interrupt!"
	#Output message to the console and also capture "Exit code" to update_status variable
	exec 3>&1
	update_status=$( { parallel_programmer program $1 0x00 2>&1 | awk '{print}''{if($1=="Exit" && $2=="code") print $4> "/dev/stderr"}' 1>&3; } 2>&1 )
	exec 3>&-
	update_status=$( echo $update_status | sed -e 's/\.//g')
	return $update_status
}


#main function
main ()
{
	local operation=$1
	local target=$2
	local binfile=$3
	local echoflag=0
	return_code=0
	platform=`cat /var/run/platform`

	case $operation in
		get_version|program_device)
		;;

		*)  # Default case
			echo "Invalid operation request."
			usage
			cleanup_exit 1
		;;
	esac

	case $platform in
		RazorL|RazorM)
		if [ $operation == "program_device" ]; then
			disable_interrupt
			echoflag=0
			get_device_version $target $echoflag
			get_file_version $binfile

			case $target in
				support_fpga)
					echo "Programming support FPGA"
					# enable support fpga path
					update_image $binfile
					update_return_code $?
				;;
				ebod)
					if [ $platform == "RazorM" ]; then
						echo "Programming EBOD cpld"
						# enable ebod cpld path
						/usr/local/bin/gpiotool 0 7 --set-data-low #Enable JTAG programming
						/usr/local/bin/gpiotool 2 4 --set-data-low #Select EBOD
						/usr/local/bin/cpldprog_altera -APROGRAM -ddo_real_time_isp=1 $binfile
						/usr/local/bin/gpiotool 0 7 --set-data-high #Disable JTAG programming
						/usr/local/bin/gpiotool 2 4 --set-data-high #Disable selection of EBOD
						return_code=$?
					else
						echo "$target not supported for $platform platform."
					fi
				;;
				*)  # Default case
					echo "$target not supported for $platform platform."
					usage
					cleanup_exit 1
				;;
			esac #case $target in
			if [ $return_code -ne 0 ]; then
				$SEL_LOGGER $SEL_PARAM "$target update: $device_version to $file_version failure"
			else
				$SEL_LOGGER $SEL_PARAM "$target update: Old: $device_version, New: $file_version"
			fi
			update_return_code $?
			enable_interrupt
		elif [ $operation == "get_version" ]; then
			echoflag=1
			get_device_version $target $echoflag
		fi
	;;
	*)  # Default case
		echo "This script is not supported on  $platform platform"
		return_code=1
	;;
	esac #case $platform in
	return $return_code
}

enable_interrupt

#Start of the script.
if [ $# -lt 2 ] || [ $# -gt 3 ]; then
	usage
	exit 1
fi
if [ -f $BUSY_FLAG ]; then
	echo "cpld_program.sh is currently running. Please try again later."
	exit 1
else
	touch $BUSY_FLAG
fi
main $1 $2 $3

cleanup_exit $return_code
