#!/bin/ash
. /usr/local/bin/ipmi.env

DEBUG_LOG="/var/log/debug"
COMMAND=""
SET_THRES_UDPATE_COMMAND=""
COMMAND_1=""
COMMAND_BANNER=""
POST_IPMI_COMMAND=""
WAIT_FOR_OUTPUT=""
POST_IPMI_RAW_COMMAND=""
COMMAND0_SILENSE=""
CMD_OUTPUT=""
CMD_RESULT=""
INIT_THRESHOLDS_COMMAND=""
VAR_1=0

ipmi_identify_command()
# $1: on/off/interval
{
	case "$1" in
		on)
			echo "chassis identify" ;;
		force)
			echo "chassis identify force" ;;
		off)
			echo "chassis identify off" ;;
		*)
			echo "chassis identify ""$1" ;;
	esac
}

ipmi_power_command()
# $1: power command
{
	case "$1" in
		on|cycle|status)
			echo "power ""$1" ;;
		off)
			# "/tmp/initiatedSystemPowerOff" is defined
			# as SEL_USER_INITIATED_SYSTEM_PWR_OFF_FILE 
			# in sel.h
			touch /tmp/initiatedSystemPowerOff
			echo "power ""$1" ;;
		diag)
			# "/tmp/initiatedSystemCore" is defined
			# as SEL_USER_INITIATED_SYSTEM_CORE_FILE 
			# in sel.h
			touch /tmp/initiatedSystemCore
			echo "power ""$1" ;;
		*) echo "" ;;	
	esac
}

check_sensor_monitor_status()
# $1: argument to monitor command
# $2: output from previous cmd
{
	#Check argument of "system sensor monitor" command
	if [ "$1" == "0" ]; then
		if [ $CMD_RESULT -eq 0 ]; then
			echo "echo -e WARNING: Disabling $OUTPUT_STR may lead to undesirable results.\nThe system $OUTPUT_STR has been disabled."
		else
			echo "echo Command executed with error $CMD_RESULT"
		fi
	elif [ "$1" == "1" ]; then
		if [ $CMD_RESULT -eq 0 ]; then
			echo "echo The system $OUTPUT_STR has been enabled."
		else
			echo "echo Command executed with error $CMD_RESULT"
		fi
	elif [ "$1" == "2" ]; then
		if [ $CMD_RESULT -eq 0 ]; then
			if [ "$2" == "00" ]; then 
				echo "echo The system $OUTPUT_STR is disabled."
			elif [ "$2" == "01" ]; then
				echo "echo The system $OUTPUT_STR is enabled."
			else 
				echo "echo Unexpected value $2."
			fi
		else
			echo "echo Command executed with error $CMD_RESULT"
		fi
	fi
}

check_sensor_monitor_status_default()
# $1: output from previous cmd
{
	if [ $CMD_RESULT -eq 0 ]; then
		if [ "$1" == "00" ]; then 
			echo "echo The system $OUTPUT_STR is disabled."
		elif [ "$1" == "01" ]; then
			echo "echo The system $OUTPUT_STR is enabled."
		else 
			echo "echo Unexpected value $1."
		fi
	else
		echo "echo Command executed with error $CMD_RESULT"
	fi
}

get_sensor_id()
# $1: sensor name
{
	$IPMITOOL_EXEC sensor get $1 | grep "Sensor ID" | cut -d'(' -f2 | cut -d')' -f1
}

sensors_set_fan_command()
# $1: sensor name
# $2: % duty cycle
{
	if [ "$2" -ge 0 ] && [ "$2" -le 100 ]; then 
		SENSOR_ID=`get_sensor_id $1`
		
		case "$1" in 
			Sysfan1_F1_Speed | \
			Sysfan1_F2_Speed | \
			Sysfan2_F1_Speed | \
			Sysfan2_F2_Speed | \
			Sysfan3_F1_Speed | \
			Sysfan3_F2_Speed | \
			IOfan1_F1_Speed | \
			IOfan1_F2_Speed | \
			IOfan2_F1_Speed | \
			IOfan2_F2_Speed | \
			IOfan3_F1_Speed | \
			IOfan3_F2_Speed) create_oem_ipmi_command 0x71 $SENSOR_ID $2 ;;
			*) echo "" ;;
		esac
	else
		echo ""
	fi
}

ipmi_sensors_command()
# $1: sub commands
{
	if [ $# == 0 ]  
	then
		echo "sensor"
	else 
		case "$1" in
			get) echo "sensor get $2" ;;
				# $2: sensor name
			set-thresh) echo "sensor thresh $2 $3 $4" ;;
				# $2 sensor name; $3: threshold; $4: setting
				# we are using ipmitool.  So if an invalid argument 
				# is entered, the ipmitool usage is displayed.
				# We can not use ch, wh, wl, cl for thresholds
				# as ipmitool will reject these.  Invalid sensor 
				# name is returned as not found.  No checking on 
				# setting.  This is a diag command.  So you need to 
				# know what you are doing.
			set-fan) 
				sensors_set_fan_command $2 $3
				;;

			monitor|thermal) 
				if [ "$1" == "monitor" ];
				then
					OEM_CMD=0x72
				else
					OEM_CMD=0x70
				fi

				if [ $# == 1 ]
				then
					# Request current status
					create_oem_ipmi_command $OEM_CMD 0x02
				elif [ $# == 2 ]
				then
					case "$2" in
						0|1|2)
							# $2: 0: disable; 1: enable ; 2: current status
							create_oem_ipmi_command $OEM_CMD $2
							;;
						*) echo "" ;;
					esac
				fi
				;;
			normal|critical)
				echo "sensor"
				;;
			filter) echo "sensor"
                ;;
			*) echo "" ;;
		esac
	fi
}

ipmi_reset_command()
# $1: reset type
{
	if [ $# == 0 ]
	then
		echo "chassis power reset" 
		return	
	fi
	case "$1" in
		prim) create_oem_ipmi_command 0x04 0x00 ;;
		back) create_oem_ipmi_command 0x04 0x01 ;;
		curr) echo "chassis power reset" ;;
		status) create_oem_ipmi_command 0x06 ;; # Need some work here
		*) echo "" ;;
	esac
}

ipmi_self_test()
{
	create_ipmi_raw_command 0x06 0x04
}

ipmi_i2c_read_write()
{
	create_ipmi_i2c_command $*
}

#
# Main Loop
#
case "$1" in
	power) 
		if [ $# == 3 ] && [ "$3" != "-f" ]; then
		        echo "Invalid option: $3"
		        echo "Usage: system $1 $2 [-f]'"
		        exit 1
		fi

		bbsp_code=`cat /sys/class/hwmon/bbsp`
        	if [ \( "$3" != "-f" \) -a \( "$bbsp_code" == "21" -o "$bbsp_code" == "22" \) ]; then
			echo "Command disabled while BIOS is updating"
			exit 1
		else
			if [ \( "$2" == "diag" \)  -a \( "$bbsp_code" != "2f" \) -a  \( "$3" != "-f" \) ]; then
				if [ -f /var/run/os_str ]; then
					os_str=$(cat /var/run/os_str)
				else
					os_str="storage OS"
				fi
				echo "Command disabled when $os_str is not running."
				exit 1
			fi
			COMMAND=`ipmi_power_command $2`

			if [ $2 == "status" ]
			then
				POST_IPMI_COMMAND_0="sed s/Chassis/Host/g"
			elif [ $2 == "on" -o $2 == "cycle" ]
			then
				POST_IPMI_COMMAND_0=" "
				VAR_1=1
				if [ -f "/var/run/RazorS" ] || [ -f "/var/run/RazorM" ]  ; then
					INIT_THRESHOLDS_COMMAND='/usr/local/bin/oem_ipmi acp init_expander_thresholds &'
				fi
			else
				POST_IPMI_COMMAND_0=" "
				VAR_1=1
			fi
		fi
		;;
	sensors) 
		COMMAND=`ipmi_sensors_command $2 $3 $4 $5`
		if [ $# == 1 ]
		then
			COMMAND_BANNER_0="Sensor Name      | Current    | Unit       | Status     | LCR       | LNC       | UNC       | UCR"
			COMMAND_BANNER_1="-----------------+------------+------------+------------+-----------+-----------+-----------+-----------"
			POST_IPMI_COMMAND_0="cut -s -d| -f1-4,6-9"
		else
			case "$2" in
				monitor|thermal)
					WAIT_FOR_OUTPUT="1"
					#Note that we have post IPMI command to run
					POST_IPMI_COMMAND_0=" "

					if [ $2 == monitor ]; then
						OUTPUT_STR="sensors monitoring"
					else
						OUTPUT_STR="thermal management"
					fi
					;;

 				normal|critical)
                                        COMMAND_BANNER_0="Sensor Name      | Current    | Unit       | Status     | LCR       | LNC       | UNC       | UCR"
                                        COMMAND_BANNER_1="-----------------+------------+------------+------------+-----------+-----------+-----------+-----------"
                                        POST_IPMI_COMMAND_0="cut -s -d| -f1-4,6-9"
                                        if [ "$2" == "normal" ]; then
                                                POST_IPMI_COMMAND_1="grep -v -w cr"
                                        fi
                                        if [ "$2" == "critical" ]; then
                                                POST_IPMI_COMMAND_1="grep -w cr"
                                        fi
                                        ;;

                                lastcritical)

                                        # parse the sel log and display historical critical messages

                                        echo "Sensor Name      | Current    | Unit       | LCR       | LNC       | UNC       | UCR       | Curr Status | Crit Status         "
                                        echo "-----------------+------------+------------+-----------+-----------+-----------+-----------+-------------+---------------------"

                                        POST_IPMI_COMMAND_0=""
                                        POST_IPMI_COMMAND_1=""
                                        COMMAND="NOT_A_COMMAND"
                                        COUNT=1

                                        # get a list of sensors that have historical critical events
                                        CMD1=$(sel rd_all|grep Critical|cut -f4 -d\|)

                                        # save the current sensor data
                                        ipmi sensors>scr1

                                        # save the relevent critical data fields
                                        sel rd_all|grep Critical| awk '{print $4,$5,$6,$7 "|" $0}'|awk -F\| '{print $1,"|"$6}' >scr2

                                        # combine and display current sensor data and historical critical data
                                        for i in $CMD1
                                        do
                                        OP1=$(cat scr1|grep $i)
                                        OP2=$(cat scr2|head -$COUNT|tail -1)
                                        echo $OP1 "|" $OP2 |awk -F\| '{printf "%-17s|%-12s|%-12s|%-11s|%-11s|%-11s|%-11s|%-13s|%s->%s\n",$1,$2,$3,$5,$6,$7,$8,$4,$9,$10}'
                                        COUNT=$(($COUNT + 1))
                                        done

                                        rm scr1;
                                        rm scr2;
                                        ;;
                                set-thresh)
                                        WAIT_FOR_OUTPUT="1"
                                        POST_IPMI_RAW_COMMAND="1"
                                        COMMAND0_SILENSE="1"
                                        POST_IPMI_COMMAND_0="envcmdtool refresh_thresh "$3
                                        SLOT_NUMBER=$(cat /var/run/slot)
					if echo $5 | grep -Eq  '-' ; then
						# If the threshold is a negative value, use '--' delimiter
						# so that oem_ipmi does not treat the value as an option
						SET_THRES_UDPATE_COMMAND="oem_ipmi acp update_expander_thresholds $3 $4 -- $5"
					else
						SET_THRES_UDPATE_COMMAND="oem_ipmi acp update_expander_thresholds $3 $4 $5"
					fi
                                        COMMAND="NONE"
                                        ;;
				filter)
			        COMMAND_BANNER_0="Sensor Name      | Current    | Unit       | Status     | LCR       | LNC       | UNC       | UCR"
			        COMMAND_BANNER_1="-----------------+------------+------------+------------+-----------+-----------+-----------+-----------"
			        POST_IPMI_COMMAND_0="cut -s -d| -f1-4,6-9"
                    if [ "$3" != "" ]; then
			            POST_IPMI_COMMAND_1="grep -i "$3
                    fi
					;;
				*)
					POST_IPMI_COMMAND_0=""
					;;
			esac
		fi
		;;
	reset) 
		if [ $# == 3 ] && [ "$3" != "-f" ]; then
		        echo "Invalid option - $3"
		        echo "Usage: system $1 $2 [-f]'"
		        exit 1
		fi

		bbsp_code=`cat /sys/class/hwmon/bbsp`
		HOST_POWER_STATE=`$IPMITOOL_EXEC power status`
		if [ \( "$3" != "-f" \) -a \( "$bbsp_code" == "21" -o "$bbsp_code" == "22" \) ]; then
			echo "Command disabled while BIOS is updating"
			exit 1
		elif [ "$HOST_POWER_STATE" == "Chassis Power is off" ]; then
			echo "Command disabled when host power is off"
			exit 1
		else
			COMMAND=`ipmi_reset_command $2` 
			if [ $2 != "status" ]
			then
				POST_IPMI_COMMAND_0=" "
				VAR_1=1
			fi
		fi
		;;
	selftest) 
		COMMAND=`ipmi_self_test` 
		COMMAND_1="/usr/local/bin/decode_selftest.sh"
		;;

	i2c) 
		COMMAND=`ipmi_i2c_read_write $*` 
		;;
	identify)
		COMMAND=$(ipmi_identify_command $2)
		if [[ "$2" == "force" ]]; then
			echo "Please remember to turn off the identify LED when finished!"
		fi
		;;
	oem)
		shift
		$OEM_IPMI_EXEC $*
		exit 0
		;;
	raw)
		shift
		$IPMITOOL_EXEC $@
		exit 0
		;;
	sim)
		if [ "$2" == "start" ]; then
			touch /tmp/sim_sensors_start
			echo "Sensor simulation starting, check /tmp/sim_sensors_log.txt to ensure simulation started correctly"
		elif [ "$2" == "stop" ]; then
			rm /tmp/sim_sensors_start
			echo "Sensor simulation stopped"
		else
			echo "Please enter option start or stop"
		fi
		exit 0
		;;
	*) 
		echo "unknown command"
		;;
esac

if [ "$SET_THRES_UDPATE_COMMAND" != "" ]; then
	$SET_THRES_UDPATE_COMMAND
	$POST_IPMI_COMMAND_0
	exit 0
fi

if [ "$COMMAND" == "" ]
then
	echo "invalid argument" 
	exit 1
fi

# Print banner for the output
if [ "$COMMAND_BANNER_0" != "" ] 
then
	echo "$COMMAND_BANNER_0"
fi

if [ "$COMMAND_BANNER_1" != "" ] 
then
	echo "$COMMAND_BANNER_1"
fi

#Now execute the command
if [ "$POST_IPMI_COMMAND_0" != "" ]
then 
	if [ $VAR_1 == 1 ]
	then
		POST_IPMI_COMMAND_0=`echo > /dev/null`
	fi
	if [ "$POST_IPMI_COMMAND_1" != "" ]
	then
		$IPMITOOL_EXEC $COMMAND | $POST_IPMI_COMMAND_0 | $POST_IPMI_COMMAND_1
	else
		#sensors and sensors monitor cmds
		if [ "$WAIT_FOR_OUTPUT" != "" ]; then
			CMD_OUTPUT=`$IPMITOOL_EXEC $COMMAND` 
			CMD_RESULT=$?
			if [ "$POST_IPMI_RAW_COMMAND" == "" ]; then
				if [ "$3" != "" ]; then
					POST_IPMI_COMMAND_0=`check_sensor_monitor_status $3 $CMD_OUTPUT`
				else
					POST_IPMI_COMMAND_0=`check_sensor_monitor_status_default $CMD_OUTPUT`
				fi
			fi
			if [ "$COMMAND0_SILENSE" != "" ]; then
				$POST_IPMI_COMMAND_0 > /dev/null
			else
				$POST_IPMI_COMMAND_0
			fi
		else
			$IPMITOOL_EXEC $COMMAND | $POST_IPMI_COMMAND_0
			if [ "$INIT_THRESHOLDS_COMMAND" != "" ]; then
				eval $INIT_THRESHOLDS_COMMAND
			fi
		fi
	fi
else
	if [ "$COMMAND_1" == "" ]
	then
	if [ "$COMMAND" == "NOT_A_COMMAND" ]
	then 
		:
	else		
		$IPMITOOL_EXEC $COMMAND
	fi
	else
		VAR=`$IPMITOOL_EXEC $COMMAND`
		$COMMAND_1 $VAR
	fi
fi                 
