#!/bin/bash # Parahub Mesh Firmware Builder # Uses OpenWrt Image Builder to create custom firmware with mesh packages. # # Usage: ./scripts/build.sh # Example: ./scripts/build.sh glinet_gl-axt1800 set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$(dirname "$SCRIPT_DIR")" # ============================================================================ # Configuration # ============================================================================ OPENWRT_VERSION="${OPENWRT_VERSION:-23.05.5}" OPENWRT_TARGET="${OPENWRT_TARGET:-mediatek/filogic}" BUILDER_URL="https://downloads.openwrt.org/releases/${OPENWRT_VERSION}/targets/${OPENWRT_TARGET}/openwrt-imagebuilder-${OPENWRT_VERSION}-${OPENWRT_TARGET//\//-}.Linux-x86_64.tar.xz" BUILDER_DIR="${PROJECT_DIR}/imagebuilder" # Profile mapping (friendly name → Image Builder profile) declare -A PROFILES=( ["axt1800"]="glinet_gl-axt1800" ["mt3000"]="glinet_gl-mt3000" ["ax6s"]="xiaomi_redmi-router-ax6s" ) # ============================================================================ # Packages # ============================================================================ # Core mesh packages (always included) PACKAGES_CORE=( # batman-adv mesh kmod-batman-adv batctl-full # 802.11s mesh support wpad-mesh-mbedtls -wpad-basic-mbedtls # SQM traffic shaping sqm-scripts kmod-sched-cake # Utilities luci luci-app-sqm ) # Full package set PACKAGES_FULL=( "${PACKAGES_CORE[@]}" # Diagnostics tcpdump iperf3 iwinfo curl ) # ============================================================================ # Functions # ============================================================================ usage() { echo "Usage: $0 " echo "" echo "Profiles:" for key in "${!PROFILES[@]}"; do echo " ${key} → ${PROFILES[$key]}" done echo "" echo "Environment variables:" echo " OPENWRT_VERSION OpenWrt release (default: ${OPENWRT_VERSION})" echo " OPENWRT_TARGET Target platform (default: ${OPENWRT_TARGET})" echo " PACKAGES_EXTRA Additional packages (space-separated)" exit 1 } download_builder() { if [ -d "$BUILDER_DIR" ]; then echo "Image Builder already downloaded, skipping..." return fi echo "Downloading OpenWrt Image Builder ${OPENWRT_VERSION}..." mkdir -p "$BUILDER_DIR" wget -q --show-progress -O- "$BUILDER_URL" | tar -xJ --strip-components=1 -C "$BUILDER_DIR" } build_firmware() { local profile="$1" local packages="${PACKAGES_FULL[*]} ${PACKAGES_EXTRA:-}" echo "Building firmware for profile: ${profile}" echo "Packages: ${packages}" echo "Custom files: ${PROJECT_DIR}/files" make -C "$BUILDER_DIR" image \ PROFILE="$profile" \ PACKAGES="$packages" \ FILES="${PROJECT_DIR}/files" \ BIN_DIR="${PROJECT_DIR}/output" echo "" echo "Build complete! Firmware images:" ls -lh "${PROJECT_DIR}/output/"*.bin 2>/dev/null || echo "(no .bin files found)" ls -lh "${PROJECT_DIR}/output/"*.img* 2>/dev/null || echo "(no .img files found)" } # ============================================================================ # Main # ============================================================================ if [ $# -lt 1 ]; then usage fi INPUT_PROFILE="$1" # Resolve profile name if [ -n "${PROFILES[$INPUT_PROFILE]+x}" ]; then PROFILE="${PROFILES[$INPUT_PROFILE]}" else # Assume it's a raw Image Builder profile name PROFILE="$INPUT_PROFILE" fi echo "=== Parahub Mesh Firmware Builder ===" echo "OpenWrt: ${OPENWRT_VERSION}" echo "Target: ${OPENWRT_TARGET}" echo "Profile: ${PROFILE}" echo "" download_builder build_firmware "$PROFILE"