#!/bin/sh
#===============================================================================
#
#  update-firmware
#
#  Copyright (C) 2021-2022 by Digi International Inc.
#  All rights reserved.
#
#  This program is free software; you can redistribute it and/or modify it
#  under the terms of the GNU General Public License version 2 as published by
#  the Free Software Foundation.
#
#
#  !Description: Dual boot firmware update script
#
#===============================================================================


if [ "$(fw_printenv -n dualboot 2>/dev/null)" != "yes" ]; then
	exec update-firmware.recovery "$@"
fi

SCRIPTNAME="$(basename "$(readlink -f "${0}")")"
VERBOSE=""
PUBLIC_KEY="/etc/ssl/certs/key.pub"
ACTIVE_SYSTEM="$(fw_printenv -n active_system 2>/dev/null)"

## Local functions
usage() {
	cat <<EOF

Usage: ${SCRIPTNAME} [OPTIONS] </your-path/your-filename>.swu

    -a               Show currently active system
    -v               Enable verbosity
    -h               Show this help

EOF
}

show_active_system() {
	if [ "${ACTIVE_SYSTEM}" = "linux_a" ]; then
		echo "Active system is A"
	else
		echo "Active system is B"
	fi
}

while :; do
	case $1 in
		-a|--active) show_active_system;exit
		;;
		-v|--verbose) VERBOSE="-v"
		;;
		-h|--help) usage;exit
		;;
		*) UPDATE_FILE="${1}"
		    break
		;;
	esac
	shift
done

# Check update file parameter.
if [ -z "${UPDATE_FILE}" ]; then
	echo "[ERROR] Update file not specified"
	exit
fi

# Check if the rootfs is ubifs to determine if it is a nand or emmc device
NANDROOTFS="$(sed -ne "s/\(rootfs\).*\<ubifs\>.*/\1/g;T;p" /proc/mounts 2>/dev/null)"

if [ -z "${NANDROOTFS}" ]; then
	# Get current partition information so we can
	# determine where to flash the images.
	if [ "${ACTIVE_SYSTEM}" = "linux_a" ]; then
		echo "Current system is A; Updating system on B"
		KERNELBOOT="linux_b"
		ROOTFS="rootfs_b"
		IMAGE_SET="mmc,secondary"
	else
		echo "Current system is B; Updating system on A"
		KERNELBOOT="linux_a"
		ROOTFS="rootfs_a"
		IMAGE_SET="mmc,primary"
	fi

	# get boot and rootfs partition index
	MMC_PART="$(realpath /dev/disk/by-partlabel/${KERNELBOOT} | grep -o '[[:digit:]]\+$')"

	# search rootfs UUID
	MMCROOT_DEV="$(realpath /dev/disk/by-partlabel/${ROOTFS})"
	for uuid in /dev/disk/by-partuuid/*; do
		if [ "$(realpath "${uuid}")" = "${MMCROOT_DEV}" ]; then
			PART_UUID="$(basename "${uuid}")"
			break
		fi
	done

	if [ -z "${MMC_PART}" ] || [ -z "${PART_UUID}" ]; then
		echo "[ERROR] detecting partitions to update."
		exit
	fi

	echo ""
	echo "Updating '${IMAGE_SET}' image set from '${UPDATE_FILE}'..."
	echo ""

	# Execute the update.
	swupdate ${VERBOSE} -i "${UPDATE_FILE}" -e "${IMAGE_SET}"
	if [ "$?" = "0" ]; then
		fw_setenv mmcroot "PARTUUID=${PART_UUID}"
		fw_setenv mmcpart "${MMC_PART}"
		fw_setenv active_system ${KERNELBOOT}
		fw_setenv bootcount 0
		echo "Firmware update finished; Rebooting system."
		reboot -f
	else
		echo "[ERROR] $? There was an error performing the update"
	fi
else
	# Get current partition information so we can
	# determine where to flash the images.
	if [ "${ACTIVE_SYSTEM}" = "linux_a" ]; then
		echo "Current system is A; Updating system on B"
		KERNELBOOT="linux_b"
		ROOTFS="rootfs_b"
		IMAGE_SET="mtd,secondary"
	else
		echo "Current system is B; Updating system on A"
		KERNELBOOT="linux_a"
		ROOTFS="rootfs_a"
		IMAGE_SET="mtd,primary"
	fi

	echo ""
	echo "Updating '${IMAGE_SET}' image set from '${UPDATE_FILE}'..."
	echo ""

	# Execute the update.
	if [ -f "${PUBLIC_KEY}" ]; then
		swupdate ${VERBOSE} -i "${UPDATE_FILE}" -e "${IMAGE_SET}" -k "${PUBLIC_KEY}"
	else
		swupdate ${VERBOSE} -i "${UPDATE_FILE}" -e "${IMAGE_SET}"
	fi
	if [ "$?" = "0" ]; then
		fw_setenv mtdbootpart ${KERNELBOOT}
		fw_setenv mtdrootfspart ${ROOTFS}
		fw_setenv rootfsvol ${ROOTFS}
		fw_setenv active_system ${KERNELBOOT}
		fw_setenv bootcount 0
		echo "Firmware update finished; Rebooting system."
		reboot -f
	else
		echo "[ERROR] $? There was an error performing the update"
	fi
fi
