#!/bin/sh
#
# Copyright (c) 2019-2020 Citrix Systems, Inc. All rights reserved.
# This software and documentation contain valuable trade
# secrets and proprietary property belonging to Citrix Systems, Inc.
# None of this software and documentation may be copied,
# duplicated or disclosed without the express
# written permission of Citrix Systems, Inc.
#
# 01/28/20
#
# This file contains shell script code needed for
# Fortville NIC firmware update.
#
# usage:  (Put usage here)
#

BASE_DIR=/var/tmp/Fortville_Silicom_Intel
SCRIPTS_DIR=${BASE_DIR}/scripts
FW_PARM_FILE_NAME=.fortville_firmware_upgrade_parm_file
PARM_FILE=${SCRIPTS_DIR}/${FW_PARM_FILE_NAME}
NSCONFIG=/nsconfig

FW_UPDATE_SUBR="./fortville_fw_update_subr"


cd ${SCRIPTS_DIR}

#
# Load the subroutine file
#
if [ -f ${FW_UPDATE_SUBR} ]
then
	. ${FW_UPDATE_SUBR}
else
	echo "Missing ${FW_UPDATE_SUBR} file!"
	echo ">>> Exiting..."
	exit 100
fi

log_msg ">>> fortville_fw_update_state_machine script:  Invoked $(date)"

has_silicom_nics
HAS_SILICOM=$?
has_intel_nics
HAS_INTEL=$?

FW_UPDATE_VERS=000
FW_UPDATE_STATE=-1
FW_UPDATE_LOOP_COUNT=-1

# Fixme:  Range check
# Fixme:  Make sure file exists.  Put in read function?

read_parms_from_file ${PARM_FILE}

#
# Make sure a firmware version argument is read from the parms file
#
if [ "${FW_UPDATE_VERS}" = "000" ]
then
	log_msg ">>> Target firmware version not provided!"
	exit 2
else
	log_msg ">>> Target firmware version provided: " \
	    "${FW_UPDATE_VERS}"
fi

# Fixme
FIRMWARE_VERSION=${FW_UPDATE_VERS}


# Increment the loop count; save the value back in the parms file
FW_UPDATE_LOOP_COUNT=$((${FW_UPDATE_LOOP_COUNT} + 1))
write_parms_to_file ${PARM_FILE}

log_msg ">>> read state:  $FW_UPDATE_STATE, read loops:  $FW_UPDATE_LOOP_COUNT, FW version:  $FW_UPDATE_VERS"


#
# Handle error case where updating firmware did not succeed after 5 attempts.
#
if [ ${FW_UPDATE_LOOP_COUNT} -gt 5 ]
then
	if [ ${FW_UPDATE_STATE} -lt 10 ]
	then
		#
		# In Silicom update state
		#

		log_msg ">>> Too many update attempts:  loops = $FW_UPDATE_LOOP_COUNT"

		if [ ${HAS_INTEL} -eq 0 ]
		then
			# Has Intel nics.
			log_msg ">>> Silicom firmware update failed!"
			# After reboot, start updating Intel NICs
			FW_UPDATE_STATE=10
			FW_UPDATE_LOOP_COUNT=0
			write_parms_to_file ${PARM_FILE}
			log_msg ">>> Rebooting... $(date)"
			sleep 1
			reboot
		else
			# Does not have Intel nics.
			log_msg ">>> Silicom firmware update failed!  Exiting..."
			# remove developer mode so we will reboot to NetScaler
			/bin/rm -f /nsconfig/.developer
			# remove rc.local to avoid further update attempts.
			rm ${NSCONFIG}/rc.local
			reboot_or_power_cycle_netscaler
		fi
	else
		#
		# In Intel update state
		#

		log_msg ">>> Intel firmware update failed!  Exiting..."
		# remove developer mode so we will reboot to NetScaler
		/bin/rm -f /nsconfig/.developer
		# remove rc.local to avoid further update attempts.
		rm ${NSCONFIG}/rc.local
		reboot_or_power_cycle_netscaler
	fi
fi

#
# Update Silicom firmware if state < 10, else update Intel firmware.
#
if [ ${FW_UPDATE_STATE} -lt 10 ]
then
	log_msg ">>> fortville_fw_update_state_machine:  Updating Silicom NICs!"

	sh fortville_fw_update_silicom_1 ${FIRMWARE_VERSION}
	UPDATE_RC=$?
	# 0:  Updates completed.  51:  More updates available (not an error).
	if [ ${UPDATE_RC} -ne 0 ] && [ ${UPDATE_RC} -ne 51 ]
	then
		log_msg ">>> Silicom update incomplete, returned ${UPDATE_RC}"
		log_msg ">>> Rebooting... $(date)"
		sleep 1
		reboot
	else
		log_msg ">>> Silicom update done, returned ${UPDATE_RC}"

		if [ ${HAS_INTEL} -eq 0 ]
		then
			#echo "has intel nics"
			# After reboot, start updating Intel NICs
			FW_UPDATE_STATE=10
			FW_UPDATE_LOOP_COUNT=0
			write_parms_to_file ${PARM_FILE}
			log_msg ">>> Rebooting... $(date)"
			sleep 1
			reboot
		else
			#echo "does not have intel nics"
			log_msg ">>> Firmware update done."
			# remove developer mode so we will reboot to NetScaler
			/bin/rm -f /nsconfig/.developer
			# remove rc.local to avoid further update attempts.
			rm ${NSCONFIG}/rc.local
			reboot_or_power_cycle_netscaler
		fi
	fi
else
	log_msg ">>> fortville_fw_update_state_machine:  Updating Intel NICs!"

	sh fortville_fw_update_intel_1 ${FIRMWARE_VERSION}
	UPDATE_RC=$?
	# 0:  Updates completed.  51:  More updates available (not an error).
	if [ ${UPDATE_RC} -ne 0 ] && [ ${UPDATE_RC} -ne 51 ]
	then
		log_msg ">>> Intel update incomplete, returned ${UPDATE_RC}"
		log_msg ">>> Rebooting... $(date)"
		sleep 1
		reboot
	else
		log_msg ">>> Intel update done, returned ${UPDATE_RC}"
		# remove developer mode so we will reboot to NetScaler
		/bin/rm -f /nsconfig/.developer
		# remove rc.local to avoid further update attempts.
		rm ${NSCONFIG}/rc.local
		reboot_or_power_cycle_netscaler
	fi
fi

log_msg ">>> fortville_fw_update_state_machine:  Unusual termination!"

exit 231

