#!/bin/bash
#-----------------------------------------------------------------------------
#
#   \brief   EnterUBoot()
#
#   Function enters the UBoot of the TC3G.
#
#   \param[in]     "hard_reset"
#                  "soft_reset"
#   \param[out]    none
#   \param[in,out] none
#
#   \return
#   possible return value(s) and description
#   return 0 -> C_NO_ERROR
#   return 1 -> C_UNKOWN_ERROR
#
#   \created     29.08.2013  STW/A.Appelt
#
#-----------------------------------------------------------------------------

function EnterUBoot()
{
   local RetVal=
   # connect to TC1

   # configure stty
   stty -F $serial_port cs8 -cstopb -hupcl -iexten -echo -ixon -crtscts -parenb raw 115200 igncr

   if [ "$1" == "hard_reset" ]; then
      echo -e "\033[32m\nPlease start or restart the $VarTargetName...\033[37m"

      # wait for UBoot version
      if (! searchUBootVersion "hard_reset" ); then
         echo -e "\nWrong Uboot version!"
         return 1
      fi
   elif [ "$1" == "soft_reset" ]; then
      echo -e "$VarTargetName is restarting...\n"

      # wait for UBoot version
      if (! searchUBootVersion "soft_reset" ); then
         echo -e "\nWrong Uboot version!"
         return 1
      fi

   else
      return 1
   fi

   # start buffering RS232 traffic
   OUTPUT=`cat $serial_port > "$script_dir/$VarTmpFile" &`

   # send some ESC siganls to enter UBoot
   echo $'\33'$'\33'$'\33'$'\33'$'\33'$'\33'$'\33'$'\33' > $serial_port

   enterUboot
   RetVal=$?
   if [ "$RetVal" == "0" ]; then
      VarUBootPwdSet=false
   elif [ "$RetVal" == "9" ]; then
      VarUBootPwdSet=true
   else
      echo -e "\nError: Timeout!"
      echo -e "Unable to find UBoot promt. Please start repeat update procedure.\n"
      return 1
   fi


   if [ "$VarUBootPwdSet" == "true" ]; then
      if [ "$VarUpdateNow" == "true" ]; then
         # Read Password without GUI
         echo -n "Enter current UBoot password:"
         read -s VarUBootPassword
      else
         # get passwd via GUI
         VarUBootPassword=$(zenity --entry --hide-text \
            --cancel-label="Exit updater" \
            --ok-label="Continue" \
            --text "Enter current UBoot password:" \
            --title "$VarTargetName Updater")
      fi

      # Check for null entry or cancellation.
      if [[ ${?} != 0 || -z ${PASSW} ]]; then
         exit 1
      fi

      # start buffering RS232 traffic
      OUTPUT=`cat $serial_port > "$script_dir/$VarTmpFile" &`
      sleep 0.1
      # send CR
      echo -e "\r" > $serial_port
      sleep 0.1

      # wait for Enter password prompt
      if (! waitForPromt "Enter"); then
         echo -e "\nError: Timeout!"
         echo -e "Unable to find 'Enter password' promt.\n"
         return 1
      fi

      # start buffering RS232 traffic
      OUTPUT=`cat $serial_port > "$script_dir/$VarTmpFile" &`
      sleep 0.1
      # enter password
      echo "$VarUBootPassword" > $serial_port
      sleep 0.1
      # wait for Enter password prompt
      if (! waitForPromt "=>"); then
         echo -e "\nError: Timeout!"
         echo -e "Unable to find UBoot promt. Check UBoot password."
         return 1
      fi
   fi

   echo -e "\nYou have now entered the UBoot.\n"

return 0
}

# function to search for UBoot version
function searchUBootVersion()
{
   while read -t $VarTimeoutUBootVersion line; do
      if test "${line#*"2008.10"}" != "$line"; then
         echo "$line"
         return 1
      elif test "${line#*"2012.10"}" != "$line"; then
         echo "$line"
         # check UBoot Version
         checkUBootVersion "$line"
         ret_val=$?
         if [ "$ret_val" != 0 ]; then
            echo -e "\033[33mWarning: UBoot Version is STW-V2.01r0 or older. Update via TFTP could cause errors.\033[37m"
         fi

         return 0
      else
         if [ "$1" == "hard_reset" ]; then
            echo "Waiting for restart..."
         fi
      fi
   done < $serial_port
}

# function to search for a Promt
function waitForPromt()
{
   param=$1
   length=${#param}
   StartTime=$(date +%s)
   timeout 10 tail -f "$script_dir/$VarTmpFile" |
   while read -n $length line; do
      CurrTime=$(date +%s)
      TimeDiff=$(( $CurrTime - $StartTime ))
      if [ $TimeDiff -ge 9 ]; then
         killall tail  2>/dev/null
         return 1
      elif test "${line#*"$1"}" != "$line"; then
         killall tail  2>/dev/null
         return 0
      fi
   done
   OUT=$?
   CurrTime=$(date +%s)
   TimeDiff=$(( $CurrTime - $StartTime ))
   if [ "$OUT" == 0 -a $TimeDiff -le 9 ]; then
      killall cat & > /dev/null &
      cat "$script_dir/$VarTmpFile"
      echo -e "\n"
      sleep 1
      return 0
   fi
killall cat & > /dev/null &
return 1
}

function enterUboot()
{
   param="Autoboot"
   length=${#param}
   StartTime=$(date +%s)
   timeout 10 tail -f "$script_dir/$VarTmpFile" |
   while read -n $length line; do
      CurrTime=$(date +%s)
      TimeDiff=$(( $CurrTime - $StartTime ))
      if [ $TimeDiff -ge 9 ]; then
         killall tail  2>/dev/null
         return 1
      elif test "${line#*"=>"}" != "$line"; then
         killall tail  2>/dev/null
         return 0
      elif test "${line#*"Autoboot"}" != "$line"; then
         killall tail  2>/dev/null
         return 9
      fi
   done
   OUT=$?
   CurrTime=$(date +%s)
   TimeDiff=$(( $CurrTime - $StartTime ))
   if [ "$OUT" == 0 -a $TimeDiff -le 9 ]; then
      killall cat & > /dev/null &
      cat "$script_dir/$VarTmpFile"
      echo -e "\n"
      sleep 1
      return 0
   elif [ "$OUT" == 9 -a $TimeDiff -le 9 ]; then
      killall cat & > /dev/null &
      cat "$script_dir/$VarTmpFile"
      echo -e "\n"
      sleep 1
      return 9
   fi
killall cat & > /dev/null &
return 1
}

# function to check the UBoot Version
function checkUBootVersion()
{

   # find index of 'STW-V'
   index=$(grep -o -b "STW-V" <<< "$1" | cut -c1-2 )
   index=$(($index + 6))

   # get UBoot Version Number
   UBootVersion=$(expr substr "$1" "$index" 6)
   UBootVersion=${UBootVersion//[.r]/}

   # check if UBoot Version is compatible with update via TFTP
   if [ "$UBootVersion" -le "$VarUBootVersionForTftp" ]; then
      return 1
   fi

return 0
}

