# Firmware configuration file for the OpenWRT One
#
# This system has two distinct fwup paths:
#
#   * `mix firmware` produces a normal Nerves .fw containing the kernel,
#     dtb, squashfs rootfs and a pre-built initramfs FIT (.itb). The .fw
#     is what `mix upload` ships to a running device for OTA updates;
#     see scripts/upload-ota.sh and scripts/apply-ota.exs for the device
#     side of that flow.
#
#   * `mix burn` writes a recovery USB stick using the `complete` task
#     defined below. The stick contains:
#       - openwrt-mediatek-filogic-openwrt_one-snand-preloader.bin  (BL2)
#       - openwrt-mediatek-filogic-openwrt_one-factory.ubi          (= our
#         openwrt-one-nand.ubi, the multi-volume UBI image with fit_a/
#         fit_b/fip/ubootenv*/rootfs_data)
#     With the boot switch flipped to NOR + the front button held during
#     power-on, OpenWrt's recovery U-Boot in SPI NOR loads those exact
#     filenames from FAT partition 1 of the stick and reflashes the
#     entire NAND. See README.md "Initial install" for the user steps.
#
# We deliberately do NOT use fwup tasks to write to the device's NAND
# directly: writing to /dev/ubi* needs the UBI_IOCVOLUP ioctl which
# fwup's raw_write/path_write/pipe_write can't issue. The OTA path
# uses ubiupdatevol via SSH instead. The `mix burn` recovery path
# sidesteps the issue by handing flashing off to OpenWrt's NOR
# recovery U-Boot, which knows how to write the raw .ubi to mtd5.

require-fwup-version="1.0.0"

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

# Resources for the standard `mix firmware` .fw archive (consumed by
# `mix upload` -> wrap-firmware.sh, which extracts these from the .fw
# and assembles a FIT image to ship to the running device).
file-resource Image {
    host-path = "${NERVES_SYSTEM}/images/Image"
}
file-resource mt7981b-openwrt-one.dtb {
    host-path = "${NERVES_SYSTEM}/images/mediatek/mt7981b-openwrt-one.dtb"
}
file-resource rootfs.img {
    host-path = ${ROOTFS}
}
file-resource openwrt-one-initramfs.itb {
    host-path = "${NERVES_SYSTEM}/images/openwrt-one-initramfs.itb"
}

# Resources for the `mix burn` recovery USB path. These get packaged
# into the .fw archive too, which costs ~43 MiB extra in the .fw, but
# makes `mix burn` work without any per-app config.
file-resource openwrt-one-snand-preloader.bin {
    host-path = "${NERVES_SYSTEM}/images/openwrt-one-snand-preloader.bin"
}
file-resource openwrt-one-nand.ubi {
    host-path = "${NERVES_SYSTEM}/images/openwrt-one-nand.ubi"
}

# Placeholder uboot-environment so the standard tasks compile.
# The real U-Boot env on this board lives in two ubootenv UBI volumes
# on SPI NAND and is managed by fw_setenv at runtime, not by fwup
# directly.
uboot-environment uboot-env {
    block-offset = 0
    block-count = 16
}

# MBR for the recovery USB stick. One FAT32 partition spanning ~96 MiB
# (large enough to hold the ~43 MiB .ubi + the ~256 KiB preloader with
# headroom for FAT bookkeeping; small enough not to wipe more of the
# stick than necessary). The user can reformat the rest of the stick
# afterwards if they want.
mbr recovery-mbr {
    partition 0 {
        block-offset = 2048
        block-count = 196608     # 96 MiB
        type = 0xc                # Win95 FAT32 LBA
        boot = true
    }
}

define(RECOVERY_PART_OFFSET, 2048)
define(RECOVERY_PART_COUNT, 196608)

# `mix burn` writes a recovery USB stick. The stick is then used with
# OpenWrt's NOR full-recovery mode (boot switch -> NOR, hold front
# button, power on) to flash the device's SPI NAND end-to-end. No
# serial console, no TFTP server, no typing of U-Boot commands.
task complete {
    on-init {
        info("Preparing OpenWRT One recovery USB stick...")
        mbr_write(recovery-mbr)
        fat_mkfs(${RECOVERY_PART_OFFSET}, ${RECOVERY_PART_COUNT})
        fat_setlabel(${RECOVERY_PART_OFFSET}, "OWRT-RECOV")
    }
    on-resource openwrt-one-snand-preloader.bin {
        fat_write(${RECOVERY_PART_OFFSET}, "openwrt-mediatek-filogic-openwrt_one-snand-preloader.bin")
    }
    on-resource openwrt-one-nand.ubi {
        fat_write(${RECOVERY_PART_OFFSET}, "openwrt-mediatek-filogic-openwrt_one-factory.ubi")
    }
    on-finish {
        info("")
        info("Recovery USB stick ready. To flash a fresh OpenWRT One:")
        info("  1. Power down the device.")
        info("  2. Plug the USB stick into the Type-A port.")
        info("  3. Move the boot switch to the NOR position.")
        info("  4. Hold the front button and apply power.")
        info("  5. Release the button when the front-panel LEDs all turn off.")
        info("  6. Wait for the front LED to turn green (~30s).")
        info("  7. Move the boot switch back to NAND.")
        info("  8. Power-cycle the device. It will autoboot Nerves.")
    }
}

# `mix upload` is wired through the user app's mix.exs alias to call
# scripts/upload-ota.sh in this system, NOT through fwup tasks.
# fwup cannot write UBI volumes, so the upgrade.{a,b} tasks are kept
# as placeholders for tooling that may invoke them by name.
task upgrade.a {
    on-init {
        error("OTA upgrade goes through scripts/upload-ota.sh in nerves_system_openwrt_one, not fwup tasks. See README.md.")
    }
}
task upgrade.b {
    on-init {
        error("OTA upgrade goes through scripts/upload-ota.sh in nerves_system_openwrt_one, not fwup tasks. See README.md.")
    }
}
