#!/bin/sh
#
# Pirelli-STB Flash script
#
# History of changes:
#
#       20061103
#               Absolute paths (linux hardening)
#       20060605
#               check that file size does not exceed flash size
#       20060518
#               RAPPO: deleted unconsistent print
#       20060516
#               RAPPO: added flash sectors protection
#	20060512
#		handled error exit code
#		fixed timeout (expressed correctly in microseconds)
#	20060510
#		reduced erase wait times (relying on a better mtd layer in the kernel)
#	20060414
#		added offset as [optional] 3rd parameter
#		added usage
#	20060413
#		first CVS commit
#	20060412
#		major revision
#	20060404
#		first version
#
# Pirelli Broadband Solutions 2006
# <massimiliano.galanti.sj@pirelli.com>, <paolo.diotti.sj@pirelli.com>, <pierpaolo.glave@pirelli.com>

usage()
{
  /bin/echo -e "\nUsage: $(basename $0) flash_partition_number filename [offset_in_bytes [noerase]]\n"
}

# Parse arguments
if [ $# -lt 2 ]
then
  /bin/echo "Error: too few arguments"
  usage
  exit 2
fi

DO_ERASE=1

/bin/echo "Flash upgrading procedure:"
# input parameters
CHARDEVICE=/dev/mtd/$1
BLOCKDEVICE=/dev/mtdblock/$1
FILENAME=$2
if [ -z "$3" ] ; then
	START_OFFSET=0
else
	START_OFFSET=$3
	if [ -n "$4" ] ; then
		if [ "$4" = "noerase" ] ; then
			DO_ERASE=0
		fi
	fi
fi

# banner
/bin/echo "$0 ver.20061103"
/bin/echo

# get sizes
FLASHSIZE=`/usr/sbin/mtd_debug info $CHARDEVICE | /bin/grep mtd.size | /bin/sed "s/mtd.size = \([0-9]*\) .*/\1/"`
ERASESIZE=`/usr/sbin/mtd_debug info $CHARDEVICE | /bin/grep mtd.erasesize | /bin/sed "s/mtd.erasesize = \([0-9]*\) .*/\1/"`
FILESIZE=`/bin/ls -l $FILENAME | /bin/sed "s/[ ]*/ /g" | /usr/bin/cut -d ' ' -f 6`

# FRATTOLIN: Check that file size does not exceed flash size
if [ "$FILESIZE" -gt "$FLASHSIZE" ]
then
    /bin/echo "Error: file size exceeds flash size"
    exit 1
fi

# block erase time in microseconds (typical)
ERASETIME=0
# time increase step in case of errors, in microseconds
TIMESTEP=500000
# block erase max time in microseconds
MAXTIME=5000000


REPROTECT=0
ZERO=0

# RAPPO: cancella l' eventuale file esistente perche' si va in append. 
if [ -e /tmp/rappo_prot ] ; then
	rm /tmp/rappo_prot
fi

# calculate block number
# RAPPO: ORIG_PIER let BLOCKNUM=$FLASHSIZE/$ERASESIZE


# GLAVE : let SECTNUM=$FILESIZE/$ERASESIZE
let SECTNUM=$FILESIZE-1
let SECTNUM=$SECTNUM/$ERASESIZE
let SECTNUM=$SECTNUM+1
let FLASHBLOCKNUM=$FLASHSIZE/$ERASESIZE

let START_BLOCK=$START_OFFSET/$ERASESIZE

let ENDBLOCK=$SECTNUM+$START_BLOCK

# start looping!
THISBLOCK=$START_BLOCK
THISTIME=$ERASETIME

if [ "$DO_ERASE" = 1 ] ; then
	while [ "$THISBLOCK" -lt "$ENDBLOCK" ]
	do
		/bin/echo
		/bin/echo
		let HUMAN_THISBLOCK=$THISBLOCK+1
	
		let OFFSET=$THISBLOCK*$ERASESIZE
		
	# RAPPO
		if /usr/sbin/mtd_debug check_protection $CHARDEVICE $OFFSET ; then
	# la print e' nel driver!   
			/bin/echo -n "."
		else
	# la print e' nel driver!   /bin/echo -n -e "Sector $OFFSET is PROTECTED\r"
	#		RAPPO: inserisci nel file /tmp/rappo_prot i settori protetti 
	# 		da riproteggere alla fine.
			/bin/echo $OFFSET >>/tmp/rappo_prot
			/usr/sbin/mtd_debug unprotect $CHARDEVICE $OFFSET 2>/dev/null  >/dev/null
			REPROTECT=1
	#		/bin/echo -n -e "Now is Unprotected !\r"
			/bin/echo "Now is Unprotected !"
	
		fi
	
	
		/bin/echo -n "Erasing $CHARDEVICE ($HUMAN_THISBLOCK/$FLASHBLOCKNUM): "
		/usr/sbin/mtd_debug erase $CHARDEVICE $OFFSET $ERASESIZE 2>/dev/null
		
		/bin/usleep $THISTIME
		
		if /bin/dd if=$BLOCKDEVICE bs=1 count=2 skip=$OFFSET 2>/dev/null | /usr/bin/hexdump | /bin/grep "^0000000 ffff" >/dev/null
		then
			/bin/echo -n -e "OK\r"
			let THISBLOCK=$THISBLOCK+1
			let THISTIME=$ERASETIME
		else
			/bin/echo "ERROR"
			let THISTIME=$THISTIME+$TIMESTEP
			if [ "$THISTIME" -gt "$MAXTIME" ]
			then
				/bin/echo "Erase timeout exceeded."
				exit 1
			fi
		fi
	done
fi
	
# issue WRITE Command
/bin/echo
/bin/echo -n "Writing file $FILENAME ($FILESIZE) to $CHARDEVICE: "
if /usr/sbin/mtd_debug write $CHARDEVICE $START_OFFSET $FILESIZE $FILENAME 2>/dev/null >/dev/null
then
	/bin/echo "OK"
else
	/bin/echo "ERROR"
	exit 1
fi


# RAPPO: reprotect all flash sectors if someone was protected

# /bin/echo "--------- REPROTECT=$REPROTECT -----------"
if [ "$REPROTECT" -ne "$ZERO" ] ; then
# read protected sectors from file and reprotect the temporary unprotected sectors
	exec </tmp/rappo_prot
	while read offset
	do
#	if [ "$offset" -ne "" ] ; then
# per riscriverci sopra....	/bin/echo -n -e "... reprotect the sector $offset again\r"
		/bin/echo "... reprotect the sector $offset again"
		/usr/sbin/mtd_debug protect $CHARDEVICE $offset 2>/dev/null  >/dev/null
#	fi
	done
fi

/bin/echo

if [ -e /tmp/rappo_prot ] ; then
#	cp /tmp/rappo_prot /tmp/save_prot  Salvataggio per debugging
	rm /tmp/rappo_prot
fi


exit 0

