#!/bin/sh

#########################################################################################
# Tools used by all script invoked in update process
# Version should be the same as those used in update_survey script
#
# Versions
#
# 1.0.7
#
# Add some functions
#	- IsProcessRunning
#	- KillRunningProcess
#
# Add log levels for LogUpdate function
# 	- NORMAL / WARNING / SEVERE
#	- If no parameter given, then used a NORMAL level
#
# 1.0.8 
#
# Modify SetLed function to support more modes and colors
# Imply to modify also the calls from other files
#
# 1.0.9
# The script gets its own version and don't share the SCRIPT_VERSION variable anymore
#
# 1.1.0
# Add a verification to each directory creation in order to suppress a potential existing file
# with the same name which will avoid the directory creation
#
# 1.1.1
# Add definition of FAST_BLINK, NORMAL_BLINK and SLOW_BLINK for led blinking
#
# 1.1.2
# Adjust content of BACKUP_ENV_DIR variable to match the name used in update_survey script
#
# 1.2.0
# Add a specific part of logged msg so that a reader can clearly identify the emitter
# Integration EMSS hardware specificities
#
# 1.2.3
# Suppress the UC_Writelog function as it was not only unnecessary because it just did a 
# call to the LogUpdate function with all arguments received but also a source of problems 
# as the LogUpdate function called was placed below the UC_WriteLog function calling.
#
# 1.2.4
# Optimisation of LogUpdate function with the awk script output_filtered_log
# Gain : about 5x faster than the previous implementation
#
# 1.2.5
# Elcom board detection and processing introduced
#
# 1.2.6
# UPDATE_DIR changed to location in FLASH
# GetUpdateStatus / SetUpdateStatus handling improved
#
# 1.2.7
# Functions from BSPUpdateTools added
# Is_Higher_Version function added
# Stop_Critical_Processes function added
# Get_Script_Version function added
#
# 1.2.8
# Get_Apps_Allowed function added - returns appnames that are allowed to run on specific boards 
#
# 1.2.9
# Get_App_Installed function added - returns the name of the app that is currently installed
# Get_App_Installed_Version function added - returns the version string of the app that is currently installed
#
# 1.3.0
# EMSS replaced with HBS
#
# 1.3.1
# GetLed function added - returns color and mode for given Led according to SetLed
# SetLed fixed transition from red, green fixed to orange blinking
#
# 1.3.2
# Avoid error when LogUpdate is called from background process
#########################################################################################

UPDATE_COMMON_SCRIPT_VERSION="1.3.2"
UPDATE_COMMON_SCRIPT_INITIALS="[UC-]"

#########################################################################################
# Variables used by all scripts that "source" update_common - be careful!
#########################################################################################

CONSOLE=/dev/console

ROOT_DIR=/root

APP_DIR=$ROOT_DIR/app

BACKUP_APP_DIR=$ROOT_DIR/oldapp
BACKUP_ENV_DIR=$ROOT_DIR/backenv

MBSA_DIRECTORY=mbsa
OSGI_DIRECTORY=osgi

USR_LOCAL_BIN="/usr/local/bin"
HAGER_APP_STARTING_SCRIPT="application"

HAGER_APPLICATION="/usr/local/bin/application"
APP_BACKUP_FILE="txa100.backup.bak"

HAGER_APP_NAMES="knxng ems doorphone"

# -----------------	Update directories defines

UNZIP_DIR_OLD="/data/tmp/unzip"
UNZIP_DIR_NEW="/root/unzip"
UNZIP_DIR=$UNZIP_DIR_NEW

UPDATE_DIR="/data/tmp/update"
UPDATE_INSTALL_DIR=$UPDATE_DIR/install
UPDATE_STATE_DIR=$UPDATE_DIR/platformstate

UPDATE_EXTENSION=zip
UPDATE_STATUS_FILE=$UPDATE_DIR/status


#------------------ Environment script parameter

MODENV_DIR=modify_environment
MODENV_SCRIPT=modify_environment.sh

FUNC_INSTALL="Install"
FUNC_RESTORE="Restore"
FUNC_CLEAN="Clean"

#------------------ Specific hardware defines

BOARDTYPE_FILE=/proc/HBox-BoardType
BSP_VERSION_FILE=/proc/HBox-Firmware-version

KNX_BOARD="KNX"
HBS_BOARD="HBS"
ELCOM_BOARD="ELCOM"

#list of allowed apps for specific boards, define like "app1 app2 app3"
KNX_BOARD_APPS_ALLOWED="knxng"
HBS_BOARD_APPS_ALLOWED="ems"
ELCOM_BOARD_APPS_ALLOWED="doorphone"

KNX_LED_POWER=1
KNX_LED_KNX=2
KNX_LED_ETH0=3
KNX_LED_ETH1=4
KNX_LED_PORTAL=5

HBS_LED_STATUS=1
HBS_LED_PORTAL=2
HBS_LED_ETH0=3
HBS_LED_ETH1=4
HBS_LED_POWER=5

#------------------ LogFiles defines

OUTPUT_FILTERED_LOG=/usr/local/bin/output_filtered_log
DATA_VAR_DIR=/data/var
DATA_VAR_LOG_DIR=$DATA_VAR_DIR/log
APP_LOGFILE=$DATA_VAR_LOG_DIR/update

LOG_DEBUG=1
LOG_WARNING=2
LOG_NORMAL=3

HBOX_LOG_LEVEL_STR="HBoxLogLevel"
LOGFILE_AND_CONSOLE="Console"

#------------------ Signal defines

SIGKILL=9
SIGTERM=15

#------------------ Leds defines

GREEN=green
RED=red
ORANGE=orange

LED_POWER=1
LED_KNX=2
LED_ETH1=4
LED_ETH0=3
LED_PORTAL=5

FAST_BLINK=100
NORMAL_BLINK=500
SLOW_BLINK=1000

#------------------ Status defines

STATUS_UPDATE_OK=0
STATUS_SURVEY=1
STATUS_UPDATE_ABORT=2
STATUS_UPDATE_FILE_ERROR=3
STATUS_WAIT_APP=4
STATUS_APP_STARTED=5
STATUS_UPDATE_FILE_OK=6
STATUS_WAIT_REBOOT=7


#########################################################################################
# Functions
#########################################################################################

#########################################################################################
# Function that create a directory with a given name. Verify first that a file with the 
# same name doesn't exist at the designed location because it will prevent directory 
# creation. 
#
# Input - $1 Directory name

CreateDirectory() {
	
	if [ ! -z $1 ]; then 																											# The directory name must be given at the least 

		if [ ! -e "$1" ]; then																										# If directory already exists, just do nothing

			if [ -f "$1" ]; then 																									# Verify if a file with the same name already exists at current location
				rm "$1"																												# If so, it must be deleted, otherwise it will prevent the directory to be created
			fi

			mkdir -p "$1"
		fi
	fi
}

#########################################################################################
# Function that verify prensence of log directories and create them if needed

ManageLogDirectories() {

	if [ ! -e "$DATA_VAR_DIR" ]; then																								# Create log directories
		CreateDirectory $DATA_VAR_DIR																											# In case we must write log entries
	fi

	if [ ! -e "$DATA_VAR_LOG_DIR" ]; then																							# Without the help of UPDATE_COMMON_FILE
		CreateDirectory $DATA_VAR_LOG_DIR																										# As it is not present
	fi

}

#########################################################################################
# Function that log a message in logfile
#
# Input - $1 Message
# 		  $2 Severity level of the message : NORMAL - WARNING
# 		  $3 Destination : LOGFILE - LOGFILE + CONSOLE

LogUpdate() {

	# Create the log file and directories if needed
	ManageLogDirectories
	
	caller=`cat /proc/$$/cmdline 2> /dev/null | tr '\000' '#'`
	$OUTPUT_FILTERED_LOG -v caller=$caller -v comment="$1" -v logLevel=$2 >> $APP_LOGFILE

	# The third parameter (optional) allows the message to be displayed on the console

	if [ ! -z $3 ] && [ "$3" == "$LOGFILE_AND_CONSOLE" ]; then
		TimeElapsed=`awk '{printf("[%11f]", $1)}' /proc/uptime)`
		echo "$TimeElapsed $ScriptInitials $1" >> $CONSOLE
	fi
}

#########################################################################################
# Function that verify presence of some update directories and create them if needed

ManageUpdateDirectories() {

	if [ ! -d "$UPDATE_DIR" ] ; then																								# Check presence of UPDATE_DIR
		LogUpdate "Creating $UPDATE_DIR directory"																					# As it could be accidentally destroyed
		CreateDirectory $UPDATE_DIR																									# And then must be restored
	fi

	if [ ! -d "$UPDATE_INSTALL_DIR" ]; then																							# Do the same for UPDATE_INSTALL_DIR
		LogUpdate "Creating $UPDATE_INSTALL_DIR directory"																			# Which is the place where update file will be placed
		CreateDirectory $UPDATE_INSTALL_DIR
	fi
	
	if [ ! -d "$UPDATE_STATE_DIR" ]; then																							# And for UPDATE_STATE_DIR
		LogUpdate "Creating $UPDATE_STATE_DIR directory"																			# Which is the place to exchange files with the application
		CreateDirectory $UPDATE_STATE_DIR
	fi

	# finally, link UPDATE_DIR to /tmp/update that might be hardcoded in old app versions
	if [ ! -d "/tmp/update" ] ; then																								
		ln -sf $UPDATE_DIR /tmp/update
	fi
}

#########################################################################################
# Function that retrieve the HBox type 

Get_BoardType() {

 	boardtype=$(cat $BOARDTYPE_FILE)
 	echo $boardtype
}

#########################################################################################
Get_BSP_Version() {

	local bspversion=`cat "$BSP_VERSION_FILE"`
	echo $bspversion
}

# Get_Apps_Allowed returns all application names those installation is allowed for the specific board type
Get_Apps_Allowed() {

	local boardtype=$(cat $BOARDTYPE_FILE)

 	case "$boardtype" in

 		$KNX_BOARD)
			echo $KNX_BOARD_APPS_ALLOWED
			;;
		$HBS_BOARD)
			echo $HBS_BOARD_APPS_ALLOWED
			;;
		$ELCOM_BOARD)
			echo $ELCOM_BOARD_APPS_ALLOWED
			;;
		*)
			echo ""
			;;
	esac
}

#########################################################################################
# Function that returns the name of the installed app
Get_App_Installed() {

	local appname=unknown

	for file in $APP_DIR/$OSGI_DIRECTORY/bin/vms/*
		do
    		file=${file%*/}
			filename=${file##*/}

			set -- $HAGER_APP_NAMES
			while [ -n "$1" ]; do
				if [ "$filename" == "$1" ]; then
					appname=$1
				fi
				shift
			done
		done

	echo $appname
}

#########################################################################################
# Function that returns the version of the installed app
#
# input : appname e.g. from Get_App_Installed
Get_App_Installed_Version() {

	local prsfile=$APP_DIR/$OSGI_DIRECTORY/bin/vms/$1.prs

	if [ -f "$prsfile" ]; then
		appversion=`cat $prsfile | grep 'com.hager.application.version' | awk -F= '{print $2}'`
	fi

	echo $appversion
}

#########################################################################################
# Function that returns the version of a script requested in arg in the form of : X.Y.Z
#
# input : filename of script
Get_Script_Version() {
	
	if [ -f $1 ]; then
		local scriptversion=`cat $1 | grep _SCRIPT_VERSION= | awk -F= '{print $2}' | tr -d '"'`
		echo $scriptversion
	fi
}

#########################################################################################
# Function that compare 2 numbers given in entry in the form of : X.Y.Z
#
# Return
# 	- 0 : $2 > $1
#	- 1 : All other cases

Is_Higher_Version() {

	if [ -z "$1" ] || [ -z "$2" ]; then
		echo 1
		return 1
	fi

	# Build numeric version numbers

	Current=$(echo "$1" | awk -F. '{ printf("%d%03d%03d\n", $1,$2,$3); }')
	New=$(echo "$2" | awk -F. '{ printf("%d%03d%03d\n", $1,$2,$3); }')

	# And compare them

	if [ $New -gt $Current ]; then
		echo 0
		return 0
	else
		echo 1
		return 1
	fi
}

#########################################################################################
# Function that set correct defines according to the current board type

UC_InitSpecific() {
 	
 	boardtype=$(Get_BoardType)

 	case "$boardtype" in

 		$KNX_BOARD)
			LED_POWER=$KNX_LED_POWER
			LED_KNX=$KNX_LED_KNX
			LED_ETH1=$KNX_LED_ETH1
			LED_ETH0=$KNX_LED_ETH0
			LED_PORTAL=$KNX_LED_PORTAL
			;;

		$HBS_BOARD)
			LED_POWER=$HBS_LED_POWER
			LED_STATUS=$HBS_LED_STATUS
			LED_ETH1=$HBS_LED_ETH1
			LED_ETH0=$HBS_LED_ETH0
			LED_PORTAL=$HBS_LED_PORTAL
			;;

		$ELCOM_BOARD)
			LED_POWER=$KNX_LED_POWER
			LED_KNX=$KNX_LED_KNX
			LED_ETH1=$KNX_LED_ETH1
			LED_ETH0=$KNX_LED_ETH0
			LED_PORTAL=$KNX_LED_PORTAL
			;;
		
		*)
			;;

	esac
 }

#########################################################################################
# Function that manage designed led using given modes and colors 
#
# Input - $1 : led : POWER - KNX - ETH0 - ETH1 - PORTAL
# 		  $2 : color : GREEN - RED - ORANGE - LEDOFF
# 		  $3 : mode : FIXED - NORMAL_BLINK - FAST_BLINK - SLOW_BLINK - HEARTBEAT

SetLed() {
	
	LogUpdate "Set Led $1 $2 $3"
	
	Led=""

	case "$1" in
		
		POWER)
			Led=$LED_POWER
			;;

		KNX | STATUS)
			if [ $boardtype == "$KNX_BOARD" ] || [ $boardtype == "$ELCOM_BOARD" ]; then
				Led=$LED_KNX
			else
				Led=$LED_STATUS
			fi
			;;

		ETH0)
			Led=$LED_ETH0
			;;

		ETH1)
			Led=$LED_ETH1
			;;

		PORTAL)
			Led=$LED_PORTAL
			;;

		*)
			LogUpdate "SetLed - Unsupported led : $1. Supported leds are : POWER - KNX - ETH0 - ETH1 - PORTAL"
			return 1
			;;

	esac

	GreenBrightness=0
	RedBrightness=0

	if [ $boardtype == "$HBS_BOARD" ]; then
		OrangeBrightness=0
	fi

	case "$2" in 
	
		GREEN)
			GreenBrightness=1
			;;
		
		RED)
			RedBrightness=1
			;;
		
		ORANGE)
			
			if [ $boardtype == "$KNX_BOARD" ] || [ $boardtype == "$ELCOM_BOARD" ]; then
				GreenBrightness=1
				RedBrightness=1
			else
				OrangeBrightness=1
			fi

			;;

		LEDOFF)
			;;

		*)
			LogUpdate "SetLed - Unsupported color : $2. Supported colors are : RED - GREEN - ORANGE"
			return 1
			;;
	
	esac

	GreenMode=none
	RedMode=none

	if [ $boardtype == "$HBS_BOARD" ]; then
		OrangeMode=none
	fi

	SpeedBlink=""

	case "$3" in
		
		FIXED)
			;;
			
		NORMAL_BLINK | FAST_BLINK | SLOW_BLINK)

			if [ $GreenBrightness -eq 1 ]; then
				GreenMode=timer
			fi

			if [ $RedBrightness -eq 1 ]; then
				RedMode=timer
			fi

			if [ $boardtype == "$HBS_BOARD" ]; then
				
				if [ $OrangeBrightness -eq 1 ]; then
					OrangeMode=timer
				fi
			fi

			if [ $3 == NORMAL_BLINK ]; then
				SpeedBlink=$NORMAL_BLINK
			elif [ $3 == FAST_BLINK ]; then
				SpeedBlink=$FAST_BLINK
			else
				SpeedBlink=$SLOW_BLINK
			fi

			;;
		
		HEARTBEAT)

			if [ $GreenBrightness -eq 1 ]; then
				GreenMode=heartbeat
			fi

			if [ $RedBrightness -eq 1 ]; then
				RedMode=heartbeat
			fi

			if [ $boardtype == "$HBS_BOARD" ]; then

				if [ $OrangeBrightness -eq 1 ]; then
					OrangeMode=heartbeat
				fi
			fi

			;;

		*)
			LogUpdate "SetLed - Unsupported mode : $3. Supported mode are : FIXED - NORMAL_BLINK - FAST_BLINK - SLOW_BLINK - HEARTBEAT"
			return 1
			;;
	
	esac


	# set brightness 0 first for proper sync
	echo 0 > /sys/class/leds/led-green-"$Led"/brightness
	echo 0 > /sys/class/leds/led-red-"$Led"/brightness

	# Set green led

	echo $GreenMode > /sys/class/leds/led-green-"$Led"/trigger
	echo $GreenBrightness > /sys/class/leds/led-green-"$Led"/brightness
			
	if [ $GreenMode == timer ]; then
		echo $SpeedBlink > /sys/class/leds/led-green-"$Led"/delay_on
		echo $SpeedBlink > /sys/class/leds/led-green-"$Led"/delay_off
	fi

	# Set red led

	echo $RedMode > /sys/class/leds/led-red-"$Led"/trigger
	echo $RedBrightness > /sys/class/leds/led-red-"$Led"/brightness	

	if [ $RedMode == timer ]; then
		echo $SpeedBlink > /sys/class/leds/led-red-"$Led"/delay_on
		echo $SpeedBlink > /sys/class/leds/led-red-"$Led"/delay_off
	fi


	if [ $boardtype == "$HBS_BOARD" ]; then

		# Set orange led

		echo $OrangeMode > /sys/class/leds/led-orange-"$Led"0/trigger
		echo $OrangeBrightness > /sys/class/leds/led-orange-"$Led"0/brightness	

		if [ $OrangeMode == timer ]; then
			echo $SpeedBlink > /sys/class/leds/led-orange-"$Led"0/delay_on
			echo $SpeedBlink > /sys/class/leds/led-orange-"$Led"0/delay_off
		fi
	fi

}

#########################################################################################
# Function that returns color and mode for the led given in $1
#
# Input - $1 : led : POWER - KNX - ETH0 - ETH1 - PORTAL
# Output - color : GREEN - RED - ORANGE - LEDOFF
#          mode : FIXED - NORMAL_BLINK - FAST_BLINK - SLOW_BLINK - HEARTBEAT

GetLed() {

	Led=""

	case "$1" in
		POWER)
			Led=$LED_POWER
			;;

		KNX | STATUS)
			if [ $boardtype == "$KNX_BOARD" ] || [ $boardtype == "$ELCOM_BOARD" ]; then
				Led=$LED_KNX
			else
				Led=$LED_STATUS
			fi
			;;

		ETH0)
			Led=$LED_ETH0
			;;

		ETH1)
			Led=$LED_ETH1
			;;

		PORTAL)
			Led=$LED_PORTAL
			;;

		*)
			return 1
			;;

	esac

	red_mode=$(cat /sys/class/leds/led-red-"$Led"/trigger | awk -F'[][]' '{print $2}')
	red_brightness=$(cat /sys/class/leds/led-red-"$Led"/brightness)
	red_blinkspeed=$([ -f /sys/class/leds/led-red-"$Led"/delay_on ] && cat /sys/class/leds/led-red-"$Led"/delay_on || echo 0)
	green_mode=$(cat /sys/class/leds/led-green-"$Led"/trigger | awk -F'[][]' '{print $2}')
	green_brightness=$(cat /sys/class/leds/led-green-"$Led"/brightness)
	green_blinkspeed=$([ -f /sys/class/leds/led-green-"$Led"/delay_on ] && cat /sys/class/leds/led-green-"$Led"/delay_on || echo 0)
	orange_mode=$([ -f /sys/class/leds/led-orange-"$Led"/trigger ] && cat /sys/class/leds/led-orange-"$Led"/trigger | awk -F'[][]' '{print $2}' || echo none)
	orange_brightness=$([ -f /sys/class/leds/led-orange-"$Led"/brightness ] && cat /sys/class/leds/led-orange-"$Led"/brightness || echo 0)
	orange_blinkspeed=$([ -f /sys/class/leds/led-orange-"$Led"/delay_on ] && cat /sys/class/leds/led-orange-"$Led"/delay_on || echo 0) 

	case "$red_mode$green_mode$orange_mode" in
		heartbeatheartbeatnone|nonenoneheartbeat)
			echo "ORANGE HEARTBEAT"
			;;
		heartbeatnonenone)
			echo "RED HEARTBEAT"
			;;
		noneheartbeatnone)
			echo "GREEN HEARTBEAT"
			;;
		timertimernone)
			case "$red_blinkspeed" in
				$SLOW_BLINK)
					echo "ORANGE SLOW_BLINK"
					;;
				$FAST_BLINK)
					echo "ORANGE FAST_BLINK"
					;;
				$NORMAL_BLINK)
					echo "ORANGE NORMAL_BLINK"
					;;
			esac
			;;
		nonenonetimer)
			case "$orange_blinkspeed" in
				$SLOW_BLINK)
					echo "ORANGE SLOW_BLINK"
					;;
				$FAST_BLINK)
					echo "ORANGE FAST_BLINK"
					;;
				$NORMAL_BLINK)
					echo "ORANGE NORMAL_BLINK"
					;;
			esac
			;;
		timernonenone)
			case "$red_blinkspeed" in
				$SLOW_BLINK)
					echo "RED SLOW_BLINK"
					;;
				$FAST_BLINK)
					echo "RED FAST_BLINK"
					;;
				$NORMAL_BLINK)
					echo "RED NORMAL_BLINK"
					;;
			esac
			;;
		nonetimernone)
			case "$green_blinkspeed" in
				$SLOW_BLINK)
					echo "GREEN SLOW_BLINK"
					;;
				$FAST_BLINK)
					echo "GREEN FAST_BLINK"
					;;
				$NORMAL_BLINK)
					echo "GREEN NORMAL_BLINK"
					;;
			esac
			;;
		nonenonenone)
			case "$red_brightness$green_brightness$orange_brightness" in
				110|001)
					echo "ORANGE FIXED"
					;;
				100)
					echo "RED FIXED"
					;;
				010)
					echo "GREEN FIXED"
					;;
				000)
					echo "LEDOFF FIXED"
					;;
			esac
			;;
		*)
			echo "UNDEFINED"
			;;
	esac

}

#########################################################################################
# Signal update is progressing. Function replaces same definition in BSPUpdateTools
update_in_progress() {
	SetLed POWER GREEN HEARTBEAT
}

#########################################################################################
# Signal update error. Function replaces same definition in BSPUpdateTools
update_error() {
	SetLed POWER ORANGE NORMAL_BLINK
}

#########################################################################################
# Signal update success. Function replaces same definition in BSPUpdateTools
update_ok() {
	SetLed POWER ORANGE FIXED
}

#########################################################################################
# Function that cleans directories totally or not depending on parameters
# 
# Order of parameters
# $1 = directory to clean

CleanDirectory() {

	if [ -d "$1" ] ; then																											# Check presence of given directory
		LogUpdate "Cleaning $1 directory"
		rm -Rf $1 2>&1 >> $APP_LOGFILE
	fi
}

#########################################################################################
# Input : $1 process name or process pid
# Output : String with pid if some

GetPidOfRunninProcess() {

	pids=$(ps | grep -v -e $0 -e grep | grep "$1" | head -n 1 | awk '{printf $1}')
	echo $pids
}


#########################################################################################
# Function that return a list of the PIDs of all processes whose name is given on entry
# It use grep instead of pidof as it can find some processes that pidof will not
#
# Input  : $1 Process name
# Output : String

GetRunningIds() {
	psfound=$(ps | grep -v -e $0 -e grep | grep -i "$1" | awk '{print $1}')
	echo $psfound
}

#########################################################################################
# Function that return the PPid of a process if this one exists
#
# Input : $1 - Process's id about which we will return the parent id
# Output : Parent Id

GetProcessParentId() {

	if [ -z "$1" ]; then
		LogUpdate "ERROR ----- GetProcessParentId need an id as parameter. Abort"
		return 1
	fi

	if [ ! -f "/proc/$1/status" ]; then
		LogUpdate "ERROR ----- Can't find a /proc/$1/status file for given pid : $1. Abort"
		return 1
	fi

	val=$(cat /proc/$1/status | grep -i "ppid" | awk '{print $2}')

	echo $val
	return 0
}

#########################################################################################
# Function that check during time-out if given pid is not running anymore
# Input : $1 - Process pid to check

DidProcessDied() {

	bContinue=true
	Count=1
	MAX_TRIES=101

	while [ $Count -lt $MAX_TRIES ] && [ $bContinue == true ]; do
		
		mypid=$(GetPidOfRunninProcess "$1")
		
		if [ -z $mypid ]; then
			LogUpdate "Process pid : $1 is not running anymore" $LOG_DEBUG
			bContinue=false
			break
		fi

		usleep 1000													# 1 millisecond
		Count=`expr $Count + 1`

	done

	if [ $bContinue == true ]; then
		return 1
	fi

	LogUpdate "Took less than $Count milliseconds to kill $1 process" $LOG_DEBUG
	return 0
}

#########################################################################################
# Function that try to detect a running process whose name is given on entry using ps 
# and grep tools
# 
# Input  - $1 Process name
# Output - 0 : Process found / 1 : Process not found

IsProcessRunning() {

	psfound=$(GetPidOfRunninProcess "$1")

	if [ -z $psfound ]; then
		return 1
	else
		return 0
	fi
}

#########################################################################################
GentlyKillProcess() {
	LogUpdate "Kill process $1 using SIGTERM ($SIGTERM) signal" $LOG_DEBUG
	kill -$SIGTERM $1 2>&1 >> $APP_LOGFILE
}

#########################################################################################
HardlyKillprocess() {
	LogUpdate "Kill process $1 using SIGKILL ($SIGKILL) signal" $LOG_DEBUG
	kill -$SIGKILL $1 2>&1 >> $APP_LOGFILE
}

#########################################################################################
# Function that kill a process whose pid is given in entry
#
# Input : $1 process pid
# Output : 0 - OK / 1 - Not OK

KillRunningPid() {

	if [ ! -z $1 ]; then

		pid=$1

		GentlyKillProcess $pid

		if ! DidProcessDied $pid; then

			LogUpdate "Process pid:$pid can't be gently killed. Hard way now !" $LOG_WARNING
			HardlyKillprocess $pid

			if ! DidProcessDied $pid; then
				LogUpdate "ERROR ----- Process pid:$pid id can't be killed. Abort"
				return 1
			fi
		fi

		LogUpdate "Process pid:$pid has been killed"

	else
		LogUpdate "KillRunningPid : Missing argument. Process pid expected"
		return 1
	fi

	return 0
}

#########################################################################################
# Function that kill the first running processes that have the name given on entry
#
# Input : $1 Process name
# Output : 0 - OK / 1 - Not OK

KillRunningProcess() {

	if [ -z $1 ]; then
		LogUpdate "KillRunningProcess : Missing argument. Process name expected"
		return 1
	fi

	psfound=$(GetPidOfRunninProcess "$1")

	if [ ! -z $psfound ]; then
		if ! KillRunningPid $psfound; then
			return 1
		fi
	fi

	return 0
}

#########################################################################################
# Functions that use either pidof or ps to retrieve a process whose name is given in 
# entry in order to kill it
#
# Input  : $1 -> Process name
# Output : none

KillProcessByPidof() {
	
	if [ ! -z "$1" ]; then

		LogUpdate "Look at $1 process using pidof identification" $LOG_WARNING
		pidfound=$(pidof "$1") 2>&1 >> $APP_LOGFILE

		if [ ! -z $pidfound ]; then
			LogUpdate "Killing $1 process" $LOG_WARNING
			kill -9 $pidfound
			LogUpdate "Killing done" $LOG_WARNING
		else
			LogUpdate "No process to kill" $LOG_WARNING
		fi

	else
		LogUpdate "KillProcessByPidof - Missing argument : process name"
	fi
}

#########################################################################################

KillProcessByPS() {

	if [ ! -z "$1" ]; then

		LogUpdate "Look at $1 process using ps identification" $LOG_WARNING
		psfound=$(ps | grep -v -e $0 -e grep | grep "$1" | awk '{print $1}')

		if [ ! -z $psfound ]; then
			LogUpdate "Killing $1 process" $LOG_WARNING
			kill -9 $psfound
			LogUpdate "Killing done" $LOG_WARNING
		else
			LogUpdate "No process to kill" $LOG_WARNING
		fi

	else
		LogUpdate "KillProcessByPS - Missing argument : process name"
	fi
}

#########################################################################################
# Stop processes that are known to get disturbed by update activity, or using a lot of
# resources, e.g. videoengine or asterisk. We do this by just calling the init scripts
Stop_Critical_Processes() {
 	boardtype=$(Get_BoardType)

 	case "$boardtype" in

 		$KNX_BOARD)
			;;

		$HBS_BOARD)
			;;

		$ELCOM_BOARD)
			# stop videoengine
			LogUpdate "stopping videoengine..."
			/etc/init.d/S70videoengine stop

			# stop baresip
			LogUpdate "stopping baresip..."
			/etc/init.d/S65baresip stop	

			# stop asterisk
			LogUpdate "stopping asterisk..."
			/etc/init.d/S60asterisk stop	
			;;
		
		*)
			;;

	esac
}


#########################################################################################
# Function for setting internal status that will be used by all update sequence logic
#
# Order of parameters
# $1 Status to set 

SetUpdateStatus() {
	if [ ! -z "$1" ]; then
		if [ ! -f $UPDATE_STATUS_FILE ]; then
			ManageUpdateDirectories
		fi

		echo "$1" > $UPDATE_STATUS_FILE
	fi
}

#########################################################################################
# Function to get internal status that will be used by all update sequence logic

GetUpdateStatus() {
	local updateStatus=$(cat $UPDATE_STATUS_FILE 2>/dev/null)

	if [ "$updateStatus" == "" ]; then
		SetUpdateSatus $STATUS_SURVEY
		updateStatus=$STATUS_SURVEY
	fi

	echo $updateStatus
}

#########################################################################################
CollectScriptVersion() {

	patterntofind="version="
	currentVersion="No version"

	# Check argument presence
	if [ -z "$1" ]; then
		LogUpdate "CollectScriptVersion : Missing argument : FilePathName"

	else

		# Check file existence
		if [ ! -e "$1" ]; then
			LogUpdate "CollectScriptVersion : $1 doesn't exists"
		else

			# OK, file exists, check version
			currentFile="$1"

			# Collect from file all lines with "version=" pattern
			extractStr=$(grep -i "$patterntofind" "$currentFile")

			# But just keep the first one which is those we are looking for
			extract=$(echo $extractStr | cut -d" " -f1)

			if [ ! -z $extract ]; then
				currentVersion=$(echo "$extract" | cut -d "=" -f2)
			fi

		fi
	fi

	# Delete potential quotation marks at the ends of the string
	lenVersion=${#currentVersion}

	if [ $(echo $currentVersion | tail -c 2) == '"' ]; then
		let lenVersion--
	fi
	
	if [ $(echo $currentVersion | head -c 1) == '"' ]; then
		let lenVersion--
		currentVersion=${currentVersion:1:$lenVersion}
	else
		currentVersion=${currentVersion:0:$lenVersion}
	fi
	

	# return string
	echo "$currentVersion"
}

#########################################################################################
# lock partition. Function replaces same definition in BSPUpdateTools
set_partition_as_lock() {
	if [[ $1 -ne 1 && $1 -ne 2 ]] ; then
		echo "$EXEC_NAME: Unknown partition (\"system_$1\")" > /dev/console
		return 1
	fi
	# Set flag of partition
	fw_setenv "part_sys"$1"_flag" LOCK
	if [ $? -ne 0 ] ; then
		echo "$EXEC_NAME: unable to set partition (\"system_$1\") as \"LOCK\"" > /dev/console
		return 1
	fi
	return 0
}

#########################################################################################
# set partition as update partition. Function replaces same definition in BSPUpdateTools
set_partition_as_update() {
	if [[ $1 -ne 1 && $1 -ne 2 ]] ; then
		echo "$EXEC_NAME: Unknown partition (\"system_$1\")" > /dev/console
		return 1
	fi
	# Set flag partition
	fw_setenv "part_sys"$1"_flag" UPDATE
	if [ $? -ne 0 ] ; then
		echo "$EXEC_NAME: unable to set partition (\"system_$1\") as \"UPDATE\"" > /dev/console
		return 1
	fi
	# Reset partition counter
	fw_setenv "part_sys"$1"_count" 0
	if [ $? -ne 0 ] ; then
		echo "$EXEC_NAME: unable to set partition (\"system_$PartNum\") counter to '0'" > /dev/console
		return 1
	fi
	return 0
}

#########################################################################################
# set partition as backup partition. Function replaces same definition in BSPUpdateTools
set_partition_as_backup() {
	if [[ $1 -ne 1 && $1 -ne 2 ]] ; then
		echo "$EXEC_NAME: Unknown partition (\"system_$1\")" > /dev/console
		return 1
	fi
	# Set flag of partition
	fw_setenv "part_sys"$1"_flag" BACKUP
	if [ $? -ne 0 ] ; then
		echo "$EXEC_NAME: unable to set partition (\"system_$1\") as \"BACKUP\"" > /dev/console
		return 1
	fi
	return 0
}

#########################################################################################
#########################################################################################
# Script entry
#########################################################################################
#########################################################################################

UC_InitSpecific
