# Revert firmware on the SAMA4D2
#
# To use:
#   1. Run `fwup -c -f fwup-revert.conf -o revert.fw` and copy revert.fw to
#      the device. This is done automatically as part of the Nerves system
#      build process. The file is stored in `/usr/share/fwup/revert.fw`.
#   2. On the device, run `fwup -t revert revert.fw -d $NERVES_FW_DEVPATH`. If
#      it succeeds, reboot. If not, then it's possible that there isn't a previous
#      firmware or the metadata about what's stored where is corrupt or out of
#      sync.

require-fwup-version="1.0.0"

include("${NERVES_SDK_IMAGES:-.}/fwup_include/fwup-common.conf")

task revert.a {
    # This task reverts to the A partition, so check that we're running on B
    require-uboot-variable(uboot-env, "nerves_fw_active", "b")

    # Verify that partition A has the expected platform/architecture
    require-uboot-variable(uboot-env, "a.nerves_fw_platform", "${NERVES_FW_PLATFORM}")
    require-uboot-variable(uboot-env, "a.nerves_fw_architecture", "${NERVES_FW_ARCHITECTURE}")

    on-init {
        info("Reverting to partition A")

        # Switch over
        uboot_setenv(uboot-env, "nerves_fw_active", "a")
        uboot_setenv(uboot-env, "nerves_fw_validated", "1")
    }
}

task revert.b {
    # This task reverts to the B partition, so check that we're running on A
    require-uboot-variable(uboot-env, "nerves_fw_active", "a")

    # Verify that partition B has the expected platform/architecture
    require-uboot-variable(uboot-env, "b.nerves_fw_platform", "${NERVES_FW_PLATFORM}")
    require-uboot-variable(uboot-env, "b.nerves_fw_architecture", "${NERVES_FW_ARCHITECTURE}")

    on-init {
        info("Reverting to partition B")

        # Switch over
        uboot_setenv(uboot-env, "nerves_fw_active", "b")
        uboot_setenv(uboot-env, "nerves_fw_validated", "1")
    }
}

task revert.unexpected.a {
    require-uboot-variable(uboot-env, "a.nerves_fw_platform", "${NERVES_FW_PLATFORM}")
    require-uboot-variable(uboot-env, "a.nerves_fw_architecture", "${NERVES_FW_ARCHITECTURE}")
    on-init {
        # Case where A is good, and the desire is to go to B.
        error("It doesn't look like there's anything to revert to in partition B.")
    }
}
task revert.unexpected.b {
    require-uboot-variable(uboot-env, "b.nerves_fw_platform", "${NERVES_FW_PLATFORM}")
    require-uboot-variable(uboot-env, "b.nerves_fw_architecture", "${NERVES_FW_ARCHITECTURE}")
    on-init {
        # Case where B is good, and the desire is to go to A.
        error("It doesn't look like there's anything to revert to in partition A.")
    }
}

task revert.wrongplatform {
    on-init {
        error("Expecting platform=${NERVES_FW_PLATFORM} and architecture=${NERVES_FW_ARCHITECTURE}")
    }
}

# Run "fwup /usr/share/fwup/revert.fw -t status -d /dev/mmcblk0 -q -U" to check the status.
task status.aa {
    require-path-on-device("/", "${ROOTFS_A_DEV}")
    require-uboot-variable(uboot-env, "nerves_fw_active", "a")
    on-init { info("a") }
}
task status.ab {
    require-path-on-device("/", "${ROOTFS_A_DEV}")
    require-uboot-variable(uboot-env, "nerves_fw_active", "b")
    on-init { info("a->b") }
}
task status.bb {
    require-path-on-device("/", "${ROOTFS_B_DEV}")
    require-uboot-variable(uboot-env, "nerves_fw_active", "b")
    on-init { info("b") }
}
task status.ba {
    require-path-on-device("/", "${ROOTFS_B_DEV}")
    require-uboot-variable(uboot-env, "nerves_fw_active", "a")
    on-init { info("b->a") }
}
task status.fail {
    on-init { error("fail") }
}
