#! /bin/sh
##################################################################################
##################################################################################
# install results:
##################################################################################
export INSTALL_SUCCESS_NO_REBOOT=0
export INSTALL_SUCCESS_REBOOT=1
export INSTALL_WRONG_HARDWARE=2
export INSTALL_KERNEL_CHECKSUM=3
export INSTALL_FILESYSTEM_CHECKSUM=4
export INSTALL_URLADER_CHECKSUM=5
export INSTALL_OTHER_ERROR=6
export INSTALL_FIRMWARE_VERSION=7
export INSTALL_DOWNGRADE_NEEDED=8
force_update=n
force_down=n
for i in "$@" ; do
    case $i in
        -f)
            force_update=y
        ;;
        -d)
            force_down=y
        ;;
    esac
done
##################################################################################
# get Kernelversion for further handling (deny update <= 3.x)
##################################################################################
currKver="$(uname -r)"
kversion=""
case ${currKver} in
    [3-9].* )
        kversion="${currKver%%-*}"; kversion="${kversion%.*}";
        echo "install: have Kernel ${currKver} - set kversion '${kversion}'";
        ;;
    *)
        echo "install: updating Kernel '${currKver}' is not supported";
        exit "${INSTALL_FIRMWARE_VERSION}"
        ;;
esac
##################################################################################
echo "install: check and install new firmware ..."
##################################################################################
need_reboot="${INSTALL_SUCCESS_NO_REBOOT}"
##################################################################################
# Power LED blinken lassen
##################################################################################
/bin/update_led_on
# AVM watchdog compatibility blurb
if [ -x /sbin/avm_watchdog ]; then
    have_avm_watchdog() { /sbin/avm_watchdog --detect >/dev/null; }
    avm_watchdog() { /sbin/avm_watchdog "$@"; }
    echo_avm_watchdog_cmd() { echo "/sbin/avm_watchdog $*"; }
else
    # Old libwdt, /dev/watchdog is AVM device
    have_avm_watchdog() { test -c /dev/watchdog; }
    avm_watchdog() { echo "$*" > /dev/watchdog; }
    echo_avm_watchdog_cmd() { echo "echo $* > /dev/watchdog"; }
fi
##################################################################################
# install support functions
##################################################################################
abort_update() {
    local code="$1" reason="${2-}"
    echo "${reason:+$reason: }abort update -- set INFO led to off (modul=7, state=1)"
    /bin/update_led_off
    exit "${code}"
}
################################
# accepted list of OEMs:
################################
echo OEM="${OEM}"
# Fritz_Box_HW241
echo testing acceptance for device Fritz_Box_HW241 ...
    if [ ! -z "${OEM}" ] ; then
        oem_found=0
        for i in  avm avme ; do
            if [ "$i" = "${OEM}" ] ; then
                echo "OK - OEM ${OEM} is supported"
                oem_found=1
                break
            fi
        done
        if [ "$oem_found" = "0" ] ; then 
            abort_update "${INSTALL_WRONG_HARDWARE}" "OEM ${OEM} not supported"
        fi
    fi
echo "testing acceptance for device Fritz_Box_HW241 done"
kernel_start=0x00090000
kernel_size=32964608
filesystem_start=0x00000000
filesystem_size=0
newFWver=08.25
# Versioninfo:	169.08.25
# Buildnummer:	r132922
# Checkpoint:	312427aa925a7a3c7002bc8bc7241dfd40a5a9a9
# Boxinfo:	HWID=241;OEM=avm,avme;
#! /bin/sh
##################################################################################
#
# FW Version Pattern: major.middle.minor -- compare middle and minor
#
##################################################################################
versioncmp() {
  local a="$1.0" cmp=$2 b="$3.0";
  while test "${a%%.*}" -eq "${b%%.*}" -a "${a}" != 0 -a "${b}" != 0; do
    a="${a#*.}" b="${b#*.}";
  done
  test "${a%%.*}" "$cmp" "${b%%.*}"
}
##################################################################################
# ascertain update requirements
##################################################################################
currFWver=$(/etc/version -v)
case "$currFWver" in
    [0-9][0-9][0-9].[0-9][0-9].[0-9][0-9]) ;;
    [0-9][0-9][0-9].[0-9][0-9].[0-9][0-9][0-9]) ;;
    *)
    abort_update "${INSTALL_FIRMWARE_VERSION}" "error parsing firmware version"
    ;;
esac
currFWver="${currFWver#*.}" # strip major-part (xx.)
echo "curr: xx.${currFWver}  new: xx.${newFWver}"
##################################################################################
# Downgrade with or w/o factorysettings or normal update ?
##################################################################################
if [ "${force_update}" = "y" ] ; then
    echo "Force: Accept Firmware Version: xx.${newFWver} "
    echo "Force: Downgrade with factorysettings ..."
    /bin/setfactorydefaults
    echo "Force: factorysettings done."
else
    ##################################################################################
    #    (newFW) -lt (currFW) :   trigger update interaction
    ##################################################################################
    if versioncmp "${newFWver}" -lt "${currFWver}" ; then
        echo "warning: Firmware downgrade detected"
        # behaviour for devices which basically are downgradable
        if [ "${force_down}" = "y" ] ; then
            echo "Force: Downgrade w/o factorysettings ..."
            # proceed (ignore downgrade, do not trigger interaction) 
        else
            abort_update "${INSTALL_DOWNGRADE_NEEDED}"
        fi
    fi
    echo "Accept Firmware Version: xx.${newFWver}"
fi
# next: prepare_update
#! /bin/sh
##################################################################################
# prepare install
##################################################################################
# do no longer overwrite/remove /var/post_install
if [ ! -f /var/post_install ] ; then
# create, if not present
  echo "#! /bin/sh" >/var/post_install
fi
# append sequence to /var/post_install
# stop Deamons:
#   - LED- and Operating hours counter
#   - telefon, telnetd
{
echo 'echo $0: start'
echo "sleep 1"
echo "killall run_clock"
echo "if pidof telefon &>/dev/null ; then killall telefon ; fi"
echo "if pidof telnetd &>/dev/null ; then killall telnetd ; fi"
echo "echo MODE=update > /dev/avm_power"
} >>/var/post_install
# disable Watchdog immediately before flashing
if have_avm_watchdog; then
  echo_avm_watchdog_cmd disable >> /var/post_install
fi
# still running ?
{
echo "echo still running:"
echo "ps"
echo "lsmod"
echo "sleep 1"
} >>/var/post_install
# next: prepare_update_flash
#! /bin/sh
##################################################################################
# setting files to install (non-mirror, spi-nor, active system running from ram-mtd)
##################################################################################
###########################################
echo "install: ${kversion} getting mtds to install..."
echo install: --mtd------------------------------------------------
var_kernel_mtdnr=$(sed -nr 's/^mtd([[:digit:]]+)[:].*\"reserved-kernel\"$/\1/p' "/proc/mtd")
var_non_res_kernel_mtdnr=$(sed -nr 's/^mtd([[:digit:]]+)[:].*\"kernel\"$/\1/p' "/proc/mtd")
# get linux_fs_start
linux_fs_start=$(sed -nr 's/^linux_fs_start[[:space:]]([01])$/\1/p' "${CONFIG_ENVIRONMENT_PATH}/environment")
# check
if test -z "$var_kernel_mtdnr" || test -z "$var_non_res_kernel_mtdnr" ; then
    abort_update "${INSTALL_KERNEL_CHECKSUM}" "Kernel mtdblock not found."
fi
echo install: --assert---------------------------------------------
if ! test -f "/var/tmp/kernel.image" ; then
    abort_update "${INSTALL_KERNEL_CHECKSUM}" "File 'kernel.image' doesn't exist."
fi
if ! test -x "/sbin/update_image" ; then
    abort_update "${INSTALL_OTHER_ERROR}" "Missing Flash Update Tool (/sbin/update_image)."
fi
echo install: --addr+size------------------------------------------
    kernel_image_size="$(stat -c %s /var/tmp/kernel.image)"
    echo "install: kernel_start=${kernel_start}"
    echo "install: kernel_size=${kernel_size}"
    echo "install: kernel_image_size=${kernel_image_size}"
    if [ -z "${kernel_image_size}" ] || [ "${kernel_image_size}" = "0" ]  ; then
        abort_update "${INSTALL_KERNEL_CHECKSUM}" "Kernel Adress or Size error!"
    fi
###########################################
need_reboot="${INSTALL_SUCCESS_REBOOT}"
###########################################
echo "install: ${kversion} writing commands to install..."
#### DEBUG-EXIT ####
# echo "#### DEBUG-EXIT ####" >>/var/post_install
# echo "exit 0" >>/var/post_install
# echo "####################" >>/var/post_install
####################
# watch update process state
echo "update_state=good" >>/var/post_install
# ---
# flash mtds
echo "echo flash mtd partition '$var_kernel_mtdnr' ..." >>/var/post_install
if [ -x "/sbin/update_image" ] && [ -e "/dev/mtd$var_kernel_mtdnr" ] ; then
{
    echo "date"
    echo "/sbin/update_image -i /var/tmp/kernel.image -o /dev/mtd$var_kernel_mtdnr"
    echo '[ "$?" -ne 0 ] && echo ... failed with error "$?" && update_state=bad'
    echo "date"
} >>/var/post_install
# ---
# set urlader field 'linux_fs_start'
{
    echo 'if [ "$update_state" = "good" ] ; then'
    echo '    echo Setting linux_fs_start mirror...'
} >>/var/post_install
# toggle
    if [ -n "$linux_fs_start" ] ; then
        if [ "$linux_fs_start" -eq "0" ] ; then
            echo "    echo linux_fs_start 1 > $CONFIG_ENVIRONMENT_PATH/environment" >> /var/post_install
        else
            echo "    echo linux_fs_start 0 > $CONFIG_ENVIRONMENT_PATH/environment" >> /var/post_install
        fi
    else 
#fallbackdefault, if $linux_fs_start nonexistent
        echo "linux_fs_start nonexistent - fallback"
        if [ "$var_kernel_mtdnr" -gt "$var_non_res_kernel_mtdnr" ] ; then
            echo "    echo linux_fs_start 1 > $CONFIG_ENVIRONMENT_PATH/environment" >> /var/post_install
        else
            echo "    echo linux_fs_start 0 > $CONFIG_ENVIRONMENT_PATH/environment" >> /var/post_install
        fi
    fi
{
    echo 'else'
    echo '    echo Setting linux_fs_start skipped due to errors...'
    echo 'fi'
} >>/var/post_install
# ---
else
    abort_update "${INSTALL_OTHER_ERROR}" "Missing Flash Update Tool or destination to flash to."
fi
# due to append sequence add exit to prevent accidently second run.
echo "exit 0" >>/var/post_install
chmod +x /var/post_install
# next: tail
#! /bin/sh
##################################################################################
# Special actions - only if everything is fine here!
##################################################################################
##################################################################################
if [ "${need_reboot}" -eq "${INSTALL_SUCCESS_REBOOT}" ] ; then
    echo "set INFO led to blink (modul=7, state=4)"
    /bin/update_led_on
else
    echo "set INFO led to off (modul=7, state=1)"
    /bin/update_led_off
fi
##################################################################################
#  returnvalues:  0: no reboot,  1: do reboot
##################################################################################
exit "${need_reboot}"
##################################################################################
