#!/bin/sh
###############################################################################
###
# \file install.sh
# \brief
# Firmware package install script
#
# copyright: (c) Berghof Automation GmbH, all rights reserved.
#
# 1. Parameter: tgz-file with absolute path
# 2. Parameter: web or usb, source of the packet
# 3. Parameter: output logfile (opt)
### 
###############################################################################

if [ $3 ]; then
	logfile=$3
else
	logfile=/tmp/pkginstall.log
fi

# Logausgaben in Logdatei (Konsole) und in Systemlog
printlog()
{
	echo "INSTALL: $*"
	echo "INSTALL: $*" >> $logfile
}

# Devicetree Update durchführen
# $1 = FDT File
update_fdt_mtd()
{
	devicetree_file=$1
	ftd_mtd=$(cat /proc/mtd | grep FDT | awk -F':' '{print $1}')
	ARCH=$(cat /proc/device-tree/fdt-architecture)
	if [ $ftd_mtd ]; then
		printlog "erasing $ftd_mtd device"
		/sbin/flash_erase /dev/$ftd_mtd 0 0
		printlog "programming $ftd_mtd device"
		if test "$ARCH" = "ecmx6sx"; then
			/sbin/nandwrite /dev/$ftd_mtd $devicetree_file -p
		elif test "$ARCH" = "kemx6sx"; then
			/sbin/nandwrite /dev/$ftd_mtd $devicetree_file -p
		elif test "$ARCH" = "kex06"; then
			/sbin/nandwrite /dev/$ftd_mtd $devicetree_file -p
		else
			dd if=$devicetree_file of=/dev/$ftd_mtd
		fi
		printlog "devicetree update done."
	else
		printlog "mtd device not found."
	fi
}

case $2 in
web|usb)
	# ist ok
	;;
*)
	printlog "install called with wrong parameter $2"
	exit 1;
	;;
esac

# increase /tmp if it is to low
SPACETOTAL=$(df -m . | sed -n 2p | awk '{print $2}')
if test "${SPACETOTAL}" -le "180"; then
	printlog "/tmp filesystem increased to 180M"
	mount /tmp -oremount,size=180M
fi

# check if /tmp has enough space left
SPACETOTAL=$(df -m . | sed -n 2p | awk '{print $2}')
SPACENEEDED=$(ls -l $1 | awk '{print $5}')
SPACENEEDED=$(( ${SPACENEEDED} / ( 1024 * 1024 ) ))
SPACEFREE=$(df -m . | sed -n 2p | awk '{print $4}')
printlog "SPACE total ${SPACETOTAL}MB" 
printlog "SPACE needed ${SPACENEEDED}MB"
printlog "SPACE free ${SPACEFREE}MB"
if test "${SPACEFREE}" -le "${SPACENEEDED}"; then
	printlog "Too low on memory, need ${SPACENEEDED}MB but only ${SPACEFREE}MB available"
	exit 1
fi

fwSecureUpdate=$(inigetkey /usr/local/etc/syscfg.ini firmware secureupdate)

# Firmware Verification wird nur bei einer Installation über web ausgeführt
if [ "$fwSecureUpdate" = "1" ]; then
	if [ "$2" = "web" ]; then
	
		if [ ! -f "/etc/fw.pem" ]; then
			printlog "firmware security key missing - update not possible"
			exit 1
		fi 
		
		printlog "verify firmware"
		tar xzf "${1}" root.sign -C ./
		status=$?
		if [ ! $status -eq 0 ]; then
			printlog "ERROR extracting root signature from package !"
			exit 1 
		fi

		openssl base64 -d -in root.sign -out root64.sign
		VERIFY=$(tar -xzOf "${1}" root.tgz | openssl dgst -sha256 -verify /etc/fw.pem -signature root64.sign)

		if test "$VERIFY" == "Verified OK"; then
			printlog "verification root.tgz: ${VERIFY}"
		else
			printlog "verification root.tgz: Failed ! (${VERIFY})"
			exit 1
		fi

		tar xzf "${1}" fdt.sign -C /tmp/
		status=$?
		if [ ! $status -eq 0 ]; then
			printlog "ERROR extracting fdt signature from package !"
			exit 1 
		fi

		openssl base64 -d -in fdt.sign -out fdt64.sign
		VERIFY=$(tar -xzOf "${1}" fdt.tgz | openssl dgst -sha256 -verify /etc/fw.pem -signature fdt64.sign)

		if test "$VERIFY" == "Verified OK"; then
			printlog "verification fdt.tgz: ${VERIFY}"
		else
			printlog "verification fdt.tgz: Failed ! (${VERIFY})"
			exit 1
		fi
	fi
fi

# root.tgz entpacken
printlog "extracting ROOTFS from package"
tar xzf "$1" root.tgz -C ./
if test "$?" != "0"; then
	rm -f root.tgz
	printlog "unpacking package Failed"
	exit 1
fi

# fwinfo.ini entpacken
printlog "extracting Firmware Infofile from package"
tar xzf "$1" fwinfo.ini -C ./
if test "$?" != "0"; then
	rm -f fwinfo.ini
	printlog "unpacking package Failed"
	exit 1
fi

# check for devicetree update
tar xzf "$1" fdt.tgz -C ./
if test "$?" != "0"; then
	printlog "No FDT archive found..."
fi

# remove source package if web package
if [ "$2" = "web" ]; then
	printlog "remove package file due to web-package"
	rm $1	
fi

# check min Firmware
fwVerMaj=$(inigetkey fwinfo.ini firmware version | awk -F'.' '{print $1}')
fwVerMin=$(inigetkey fwinfo.ini firmware version | awk -F'.' '{print $2}')
fwVerBug=$(inigetkey fwinfo.ini firmware version | awk -F'.' '{print $3}')

reqVerMaj=$(cat /proc/device-tree/min-firmware | awk -F'.' '{print $1}')
reqVerMin=$(cat /proc/device-tree/min-firmware | awk -F'.' '{print $2}')
reqVerBug=$(cat /proc/device-tree/min-firmware | awk -F'.' '{print $3}')

if [ $fwVerMaj -gt $reqVerMaj ]; then
	#ok
	printlog "Device min FW requirement OK"
else
	if [ $fwVerMaj -eq $reqVerMaj ]; then
		if [ $fwVerMin -gt $reqVerMin ]; then
			#ok
			printlog "Device min FW requirement OK"
		else
			if [ $fwVerMin -eq $reqVerMin ]; then
				if [ $fwVerBug -ge $reqVerBug ]; then
					#ok
					printlog "Device min FW requirement OK"
				else
					#nicht ok
					printlog "ERROR: Device requires min Firmware $reqVerMaj.$reqVerMin.$reqVerBug but $fwVerMaj.$fwVerMin.$fwVerBug is given"
					exit 1
				fi
			else
				#nicht ok
				printlog "ERROR: Device requires min Firmware $reqVerMaj.$reqVerMin.$reqVerBug but $fwVerMaj.$fwVerMin.$fwVerBug is given"
				exit 1
			fi
		fi
	else
		#nicht ok
		printlog "ERROR: Device requires min Firmware $reqVerMaj.$reqVerMin.$reqVerBug but $fwVerMaj.$fwVerMin.$fwVerBug is given"
		exit 1
	fi
fi

# Search for FDT Update
if [ -f "fdt.tgz" ]; then
	ARTNUM=$(cat /proc/device-tree/fdt-artnum)
	HWVERS=$(cat /proc/device-tree/fdt-hwvers)
	FDTVERS=$(cat /proc/device-tree/fdt-version)
	
	printlog "searching new devicetree for $ARTNUM-$HWVERS ..."	

	for file in `tar -tzf fdt.tgz`
	do
			echo $file
			avail_fdt_vers=$(echo $file | grep $ARTNUM-$HWVERS | awk -F'-' '{print $3}' | awk -F'.' '{print $1}' | sed 's/[^0-9]*//g')
			cur_fdt_vers=$(echo $FDTVERS | sed 's/[^0-9]*//g')

			if [ ! $avail_fdt_vers ]; then
					continue
			fi

			if [ $avail_fdt_vers -gt $cur_fdt_vers ]; then
					printlog "new devicetree available"	
					printlog "installing devicetree $file..."	
					tar xzf fdt.tgz $file -C ./
					if test "$?" != "0"; then
						printlog "error extracting devicetree..."
					else
						update_fdt_mtd $(/bin/realpath ./$file)
					fi
					break
			fi
	done
fi

# Start update -> give it to the firmware!
printlog "calling SYSUPDATE"
/sbin/sysupdate ./root.tgz $2 $logfile

RET=$?
if [ "${RET}" = "0" ]; then
	if [ "$2" = "usb" ]; then
		printlog "SUCCESSFUL ! initating reboot..."
		reboot
	fi
fi

printlog "SYSUPDATE returned with error, FAILED !"
exit ${RET}
