#!/bin/sh

# luna firmware upgrade  script
# $1 image destination (0 or 1) 
# Kernel and root file system images are assumed to be located at the same directory named uImage and rootfs respectively
# ToDo: use arugements to refer to kernel/rootfs location.

########### G3 ##########################################################
### uImage : uImage
### rootfs : rootfs
#########################################################################
k_img="uImage"
r_img="rootfs"
img_ver="fwu_ver"
md5_cmp="md5.txt"
md5_cmd="/bin/md5sum"
#md5 run-time result
md5_tmp="md5_tmp"
md5_rt_result="md5_rt_result.txt"
new_fw_ver="new_fw_ver.txt"
cur_fw_ver="cur_fw_ver.txt"
env_sw_ver="env_sw_ver.txt"
hw_ver_file="hw_ver"
cdt_hw_ver_file="cdt_hw_ver"
skip_hwver_check="/tmp/skip_hwver_check"
custom_file="custom.cdtCfg"
config_file_place="/var/config"

# For YueMe framework
framework_img="framework.img"
framework_sh="framework.sh"
framework_upgraded=0

arg1="$1"
arg2="$2"

cdtcfg="/bin/cdtCfg"

update_framework() {

	if [ "`tar -tf $2 $framework_sh`" = "$framework_sh" ] && [ "`tar -tf $2 $framework_img`" = "$framework_img" ]; then
			echo "Updaing framework from $2"
			tar -xf $2 $framework_sh
			grep $framework_sh $md5_cmp > $md5_tmp
			$md5_cmd $framework_sh > $md5_rt_result
			diff $md5_rt_result $md5_tmp

			if [ $? != 0 ]; then 
					echo "$framework_sh md5_sum inconsistent, aborted image updating !"
					exit 1
			fi

			# Run firmware upgrade script extracted from image tar ball
			sh $framework_sh $2
			framework_upgraded=1
	fi

	if [ "`tar -tf $2 $k_img`" = '' ] && [ $framework_upgraded = 1 ]; then
			echo "No uImage for upgrading, skip"
			exit 2
	fi
}

do_hwver_check() {
	if [ -f $skip_hwver_check ]; then
			echo "Skip HW_VER check!!"
	else
		img_hw_ver=`tar -xf $2 $hw_ver_file -O`
		mib_hw_ver=`flash get HW_HWVER | sed s/HW_HWVER=//g`
		if [ "$img_hw_ver" = "skip" ]; then
			echo "skip HW_VER check!!"
		else
			echo "img_hw_ver=$img_hw_ver mib_hw_ver=$mib_hw_ver"
			if [ "$img_hw_ver" != "$mib_hw_ver" ]; then
				echo "HW_VER $img_hw_ver inconsistent, aborted image updating !"
				echo "4001">/tmp/check_status
				exit 1
			fi
		fi

		mib_hw_ver=`cdtCfg -a 1 | sed s/ONU_HW_type=//g`
		echo $mib_hw_ver | grep -n "VB"
		if [ $? = 0 ]; then
			img_hw_ver=`tar -xf $2 $cdt_hw_ver_file -O`
			echo $img_hw_ver | awk '{print $1}'| grep -n $mib_hw_ver
			if [ $? != 0 ]; then
				echo "img_hw_ver=$img_hw_ver"
				echo "HW_VER $img_hw_ver inconsistent,we need $mib_hw_ver, aborted image updating !"
				echo "4001">/tmp/check_status
				exit 1
			fi
		fi
	fi
}


do_extract_kel_md5() {
	tar_name=$arg2
	
	# Extract kernel image
	md5sum $tar_name -o $1 -l $2 | awk '{print $1}' > $md5_rt_result
	# Check integrity
	grep $k_img $md5_cmp | awk '{print $1}' > $md5_tmp
	cat $md5_rt_result
	cat $md5_tmp
	diff $md5_rt_result $md5_tmp

	if [ $? != 0 ]; then
			echo "$k_img" "md5_sum inconsistent, aborted image updating !"
			echo "5001">/tmp/check_status
			exit 1
	fi
	echo "Integrity of $k_img is okay."
}

do_extract_fs_md5() {
	tar_name=$arg2
	
	# Extract kernel image
	md5sum $tar_name -o $1 -l $2 | awk '{print $1}' > $md5_rt_result
	# Check integrity
	grep $r_img $md5_cmp | awk '{print $1}' > $md5_tmp
	cat $md5_rt_result
	cat $md5_tmp
	diff $md5_rt_result $md5_tmp

	if [ $? != 0 ]; then
			echo "$r_img" "md5_sum inconsistent, aborted image updating !"
			echo "5002">/tmp/check_status
			exit 1
	fi

	echo "Integrity of $r_img is okay."
}

do_firware_ver_chk() {
	# Check upgrade firmware's version with current firmware version
	tar -xf $2 $img_ver
	if [ $? != 0 ]; then
		echo "1" > /var/firmware_upgrade_status
		echo "Firmware version incorrect: no fwu_ver in img.tar !"
		echo "6001">/tmp/check_status
		exit 1
	fi

	cat $img_ver > $new_fw_ver
	cat /etc/version > $cur_fw_ver

	cat $new_fw_ver | grep -n '^V[0-9]*.[0-9]*.[0-9]*-[0-9][0-9]*'
	if [ $? != 0 ]; then
		echo "1" > /var/firmware_upgrade_status
		echo "Firmware version incorrect: `cat $new_fw_ver` !"
		echo "6002">/tmp/check_status
		exit 1
	fi

	#Because we don't have full fw version in fwu_ver, so we cut full version from
	#"V4.0.0-191014 -- Mon Oct 14 15:10:15 CST 2019" to be "V4.0.0-191014"

	short_cur_fw_ver=`cat $cur_fw_ver | awk -F ' ' '{print $1}'`
	echo "Try to upgrade firmware version from `cat $cur_fw_ver` short version is $short_cur_fw_ver"
	echo "                                  to `cat $new_fw_ver`"

	#if [ "`cat $new_fw_ver`" == "`cat $cur_fw_ver`" ]; then
	if [ "`cat $new_fw_ver`" == "$short_cur_fw_ver" ]; then
		echo "4" > /var/firmware_upgrade_status
			echo "Current firmware version already is `cat $cur_fw_ver` !"
			echo "6003">/tmp/check_status
			exit 1
	fi

	echo "Firware version check okay."
}

do_firmware_space_check() {
	kel_size=$1
	fs_size=$2
	img_dst=$arg1
	# Find out kernel/rootfs mtd partition according to image destination
	k_mtd="/dev/"`cat /proc/mtd | grep \"ubi_k"$img_dst"\" | sed 's/:.*$//g'`
	r_mtd="/dev/"`cat /proc/mtd | grep \"ubi_r"$img_dst"\" | sed 's/:.*$//g'`
	k_mtd_size=`cat /proc/mtd | grep \"ubi_k"$img_dst"\" | sed 's/^.*: //g' | sed 's/ .*$//g'`
	r_mtd_size=`cat /proc/mtd | grep \"ubi_r"$img_dst"\" | sed 's/^.*: //g' | sed 's/ .*$//g'`
	echo "kernel image is located at $k_mtd"
	echo "rootfs image is located at $r_mtd"

	mtd_size_dec="`printf %d 0x$k_mtd_size`"
	img_size_dec="$kel_size"
	expr "$img_size_dec" \< "$mtd_size_dec" > /dev/null
	if [ $? != 0 ]; then
		echo "uImage size too big($img_size_dec) !"
		echo "3" > /var/firmware_upgrade_status
		echo "7001">/tmp/check_status
		exit 1
	fi

	mtd_size_dec="`printf %d 0x$r_mtd_size`"
	img_size_dec="$fs_size"
	expr "$img_size_dec" \< "$mtd_size_dec" > /dev/null
	if [ $? != 0 ]; then
		echo "rootfs size too big($img_size_dec) !"
		echo "3" > /var/firmware_upgrade_status
		echo "7002">/tmp/check_status
		exit 1
	fi

	echo "Both uImage and rootfs size check okay, start updating ..."
}

get_vol_num_from_vol_name() {
	dev_num="$1"
	vol_name="$2"
	info=$(ubinfo -d "${dev_num}" -N "${vol_name}")
	set $info
	echo "/dev/ubi${dev_num}_$3"
}

do_extract_and_update_kel() {
	echo "1">/tmp/upgrade_status
	FILE=/tmp/uSleepFlag1
	i=0
	while [ $i -lt 5 ]; do
		if [ -f "$FILE" ]; then
			break
		fi		
		let i++
		echo "i=$i,usleepflag1 doesn't exist,sleep 1"
		sleep 1
	done

	img_num=$arg1
	tar_name=$arg2

	vkimg=$(get_vol_num_from_vol_name "0" "ubi_k${img_num}")
	echo "ubiupdatevol $vkimg --skip=$1 --size=$2 $tar_name"
	ubiupdatevol "$vkimg" --skip=$1 --size=$2 "$tar_name"
	if [ $? != 0 ]; then
		echo "8001">/tmp/check_status
		exit 1
	fi
}

do_extract_and_update_fs() {
	img_num=$arg1
	tar_name=$arg2

	vrimg=$(get_vol_num_from_vol_name "0" "ubi_r${img_num}")

	echo "ubiupdatevol $vrimg --skip=$1 --size=$2 $tar_name"
	ubiupdatevol "$vrimg" --skip=$1 --size=$2 "$tar_name"
	if [ $? != 0 ]; then
		echo "8002">/tmp/check_status
		exit 1
	fi
	echo "2">/tmp/upgrade_status
}

write_ver_record_and_clean() {
	cat $new_fw_ver | grep CST
	if [ $? = 0 ]; then
		echo `cat $new_fw_ver` | sed 's/ *--.*$//g' > $env_sw_ver
	else
		cat $new_fw_ver > $env_sw_ver
	fi
	# Write image version information 
	nv setenv sw_version"$1" "`cat $env_sw_ver`"

	# Clean up temporary files
	rm -f $md5_cmp $md5_tmp $md5_rt_result $img_ver $new_fw_ver $cur_fw_ver $env_sw_ver $2

	# Post processing (for future extension consideration)

	echo "Successfully updated image $1!!"
}

main() {
	k_info=`$cdtcfg -g $k_img $arg2`
	k_off=`echo $k_info | awk -F ',' '{print $1}'`
	k_len=`echo $k_info | awk -F ',' '{print $2}'`
	
	r_info=`$cdtcfg -g $r_img $arg2`
	r_off=`echo $r_info | awk -F ',' '{print $1}'`
	r_len=`echo $r_info | awk -F ',' '{print $2}'`

	update_framework "$arg1" "$arg2"
	do_hwver_check "$arg1" "$arg2"
	do_extract_kel_md5 "$k_off" "$k_len"
	do_extract_fs_md5 "$r_off" "$r_len"
	do_firware_ver_chk "$arg1" "$arg2"
	do_firmware_space_check "$k_len" "$r_len"
	do_extract_and_update_kel "$k_off" "$k_len"
	do_extract_and_update_fs "$r_off" "$r_len"
	if [ "`tar -tf $arg2 $custom_file`" = "$custom_file" ]; then
		tar -xf $arg2 $custom_file
		mv $custom_file $config_file_place
	fi
	write_ver_record_and_clean "$arg1" "$arg2"
}

main

# Stop this script upon any error
# set -e

