#!/bin/sh
#
# setenv.sh - U-Boot env configuration script
#
# Written by Vincent Chen <VincentChen@wondermedia.com.tw>

# saveenv
# @uboot_env	U-boot script in raw strings format
# @mtd		MTD device used by U-Boot env.
# @flag		active flag
#
# Save uboot environment variables from u-boot raw strings
#
# Usage:
#     saveenv /mnt/mmcblk0p1/env/uboot_env_sf /dev/mtd3 1
saveenv ()
{
	local uboot_env=$1
	local mtd=$2
	local flag=$3

	local crc32=`which crc32`
	local infile=${uboot_env}
	local outfile=/tmp/uboot_env.raw
	local tmpfile=/tmp/uboot_env.tmp

	#echo "infile=$infile"
	#echo "outfile=$outfile"
	#echo "tmpfile=$tmpfile"

	dd if=/dev/zero of=${outfile} bs=1k count=64

	cat ${infile} | tr "\n" "\0" > ${tmpfile}

	dd if=${tmpfile} of=${outfile} bs=1 seek=5 count=65531 conv=notrunc

	# $crc32 -s 5 -x 1 ${outfile}
	$crc32 -s 5 -r ${outfile} > ${tmpfile}
	printf "\x${flag}" >> ${tmpfile}
	dd if=${tmpfile} of=${outfile} bs=1 seek=0 count=5 conv=notrunc

	flash_eraseall $mtd
	cat ${outfile} > $mtd

	rm ${tmpfile} ${outfile}
}

# saveenv_nand
# @uboot_env	U-boot script in raw strings format
# @mtd		MTD device used by U-Boot env.
#
# Save uboot environment variables from u-boot raw strings
#
# Usage:
#     saveenv_nand /mnt/mmcblk0p1/env/uboot_env_sf /dev/mtd3
saveenv_nand ()
{
	local uboot_env=$1
	local mtd=$2

	local crc32=`which crc32`
	local infile=${uboot_env}
	local outfile=/tmp/uboot_env.raw
	local tmpfile=/tmp/uboot_env.tmp

	#echo "infile=$infile"
	#echo "outfile=$outfile"
	#echo "tmpfile=$tmpfile"

	dd if=/dev/zero of=${outfile} bs=1k count=64

	cat ${infile} | tr "\n" "\0" > ${tmpfile}

	dd if=${tmpfile} of=${outfile} bs=1 seek=4 count=65532 conv=notrunc

	# $crc32 -s 4 -x 1 ${outfile}
	$crc32 -s 4 -r ${outfile} > ${tmpfile}
	dd if=${tmpfile} of=${outfile} bs=1 seek=0 count=4 conv=notrunc

	flash_eraseall $mtd
	nandwrite -p -s 0 $mtd ${outfile}

	rm ${tmpfile} ${outfile}
}

get_mtd ()
{
	echo /dev/`cat /proc/mtd | grep "$1" | cut -d: -f1`
}

edit_config ()
{
	if [ $# -lt 2 ]; then
		echo "Usage: edit_config config name [value]"
		return
	fi

	local config=$1
	local name=$2
	local value=$3
	local old_value=

	if [ -e "$config" ]; then
		old_value=`cat $config | grep ^$name= | cut -d= -f2`
	fi

	if [ -z "$old_value" ]; then
		if [ ! -z "$value" ]; then
			# add
			echo "$name=$value" >> $config
			return
		fi
	else
		if [ ! -z "$value" ]; then
			# modify
			sed "s/$name=$old_value/$name=$value/g" -i $config
		else
			# delete
			sed "s/$name=$old_value//g" -i $config
		fi
	fi
	sed "/^$/d" -i $config
}

if [ $# -lt 1 ]; then
	echo "Usage: setenv.sh ${var} ${value}"
	exit 0
fi

#
# Get variable and value
#
var=
value=
for i in $@; do
	if [ -z $var ]; then
		var=$i
	elif [ -z $value ]; then
		value=$i
	else
		value="${value} $i"
	fi
done
#echo "var = $var"
#echo "value = $value"

uboot_mtd_sf=
uboot_mtd_nand=
uboot_mtd=

# Get activated U-Boot configuration from SF
for mtd in `cat /proc/mtd | grep cfg | grep SF | cut -d: -f1`; do
	# check active flag
	f=`hexdump -v -e '1/1 "%d"' -s 4 -n 1 /dev/$mtd`
	if [ "$f" == "1" ]; then
		uboot_mtd_sf=/dev/$mtd
		break
	fi
done

if [ ! -z "$uboot_mtd_sf" ]; then
	uboot_mtd_sf=`get_mtd "u-boot env. cfg. 1-SF"`
fi

# Get activated U-Boot configuration from NAND
uboot_mtd_nand=`get_mtd "u-boot env. cfg. 1-NAND"`

if [ ! -z "$uboot_mtd_sf" ]; then
	uboot_mtd="$uboot_mtd_sf"
elif [ ! -z "$uboot_mtd_nand" ]; then
	uboot_mtd="$uboot_mtd_nand"
fi

oldstyle=0

if [ ! -z "$uboot_mtd" ]; then
	# Generate new uboot env.
	envfile=/tmp/envfile.txt
	if [ $oldstyle -eq 1 ]; then
		strings $uboot_mtd | grep -e "^$var" -v > $envfile
		if [ ! -z $value ]; then
			echo "$var=$value" >> $envfile
		fi
	else
		strings $uboot_mtd > $envfile
		edit_config $envfile "$var" "$value"
	fi

	if [ ! -z "$uboot_mtd_sf" ]; then
		# Save env. to mtd
		saveenv $envfile $uboot_mtd_sf 1
	fi

	if [ ! -z "$uboot_mtd_nand" ]; then
		# Save env. to mtd
		saveenv_nand $envfile $uboot_mtd_nand
	fi
	rm $envfile
fi

