mirror of
https://github.com/alexhopeoconnor/WiFiManager.git
synced 2026-10-04 02:48:13 +10:00
158 lines
5.4 KiB
Bash
Executable File
158 lines
5.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
# shellcheck source=tools/lib/portal-hardware-session.sh
|
|
source "$root/tools/lib/portal-hardware-session.sh"
|
|
|
|
usage() {
|
|
cat <<'USAGE' >&2
|
|
Usage:
|
|
./tools/portal-hardware doctor --client-interface IFACE [--take-over-client-adapter]
|
|
./tools/portal-hardware up --platform esp8266|esp32 --port /dev/serial/by-id/... \
|
|
--client-interface IFACE [--take-over-client-adapter] [--output DIRECTORY]
|
|
./tools/portal-hardware run --platform esp8266|esp32 --port /dev/serial/by-id/... \
|
|
--client-interface IFACE [--take-over-client-adapter] [--keep] \
|
|
[--browser auto|skip] [--station-env PATH] [--output DIRECTORY]
|
|
./tools/portal-hardware down
|
|
|
|
Only the named client interface may be disconnected or reconfigured. The tool
|
|
refuses the host default-route interface and preserves the created connection
|
|
in a 0600 state file until `down` or normal `run` cleanup.
|
|
USAGE
|
|
exit 2
|
|
}
|
|
|
|
command_name="${1:-}"
|
|
[[ -n "$command_name" ]] || usage
|
|
shift || true
|
|
|
|
platform=""
|
|
port=""
|
|
client_interface=""
|
|
takeover="no"
|
|
keep="no"
|
|
browser="auto"
|
|
station_env=""
|
|
output_dir=""
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--platform) [[ $# -ge 2 ]] || usage; platform="$2"; shift 2 ;;
|
|
--port) [[ $# -ge 2 ]] || usage; port="$2"; shift 2 ;;
|
|
--client-interface) [[ $# -ge 2 ]] || usage; client_interface="$2"; shift 2 ;;
|
|
--take-over-client-adapter) takeover="yes"; shift ;;
|
|
--keep) keep="yes"; shift ;;
|
|
--browser) [[ $# -ge 2 ]] || usage; browser="$2"; shift 2 ;;
|
|
--station-env) [[ $# -ge 2 ]] || usage; station_env="$2"; shift 2 ;;
|
|
--output) [[ $# -ge 2 ]] || usage; output_dir="$2"; shift 2 ;;
|
|
*) usage ;;
|
|
esac
|
|
done
|
|
|
|
require_common() {
|
|
wm_require ip
|
|
wm_require nmcli
|
|
wm_require pio
|
|
wm_require docker
|
|
docker compose version >/dev/null
|
|
}
|
|
|
|
prepare_output_dir() {
|
|
if [[ -z "$output_dir" ]]; then
|
|
output_dir="$(wm_portal_state_root)/runs/$(date -u +%Y%m%dT%H%M%SZ)-$platform"
|
|
fi
|
|
install -d -m 700 "$output_dir"
|
|
output_dir="$(cd "$output_dir" && pwd)"
|
|
}
|
|
|
|
validate_run_arguments() {
|
|
[[ "$platform" == "esp8266" || "$platform" == "esp32" ]] || usage
|
|
[[ -n "$client_interface" ]] || usage
|
|
[[ -n "$port" && -e "$port" ]] || {
|
|
echo "Serial port not found: $port" >&2
|
|
exit 1
|
|
}
|
|
[[ "$browser" == "auto" || "$browser" == "skip" ]] || usage
|
|
[[ -z "$station_env" || -r "$station_env" ]] || {
|
|
echo "Station environment file is not readable: $station_env" >&2
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
start_portal_session() {
|
|
local ssid
|
|
validate_run_arguments
|
|
require_common
|
|
wm_acquire_hardware_lock
|
|
wm_require_no_active_session
|
|
wm_require_client_adapter "$client_interface" "$takeover"
|
|
prepare_output_dir
|
|
ssid="$(wm_portal_ssid "$platform")"
|
|
|
|
pio run -d "$root/test/portal-harness" -e "$platform" -t upload --upload-port "$port"
|
|
if ! wm_create_portal_connection "$client_interface" "$ssid" "default1"; then
|
|
return 1
|
|
fi
|
|
if ! wm_verify_portal_route "$client_interface"; then
|
|
wm_remove_connection "$WM_PORTAL_CONNECTION_UUID"
|
|
return 1
|
|
fi
|
|
if ! wm_write_state "$client_interface" "$platform" "$WM_PORTAL_CONNECTION_UUID" "$WM_PORTAL_CONNECTION_NAME"; then
|
|
wm_remove_connection "$WM_PORTAL_CONNECTION_UUID"
|
|
return 1
|
|
fi
|
|
printf 'Portal connected on %s. Artifacts: %s\n' "$client_interface" "$output_dir"
|
|
}
|
|
|
|
finish_portal_session() {
|
|
wm_load_state
|
|
wm_remove_connection "$WM_PORTAL_CONNECTION_UUID"
|
|
wm_clear_state
|
|
}
|
|
|
|
case "$command_name" in
|
|
doctor)
|
|
[[ -n "$client_interface" ]] || usage
|
|
require_common
|
|
wm_acquire_hardware_lock
|
|
wm_require_client_adapter "$client_interface" "$takeover"
|
|
printf 'Portal hardware prerequisites are ready. Main route is untouched; client adapter: %s\n' "$client_interface"
|
|
;;
|
|
up)
|
|
start_portal_session
|
|
;;
|
|
down)
|
|
[[ -z "$platform$port$client_interface$station_env$output_dir" ]] || usage
|
|
wm_acquire_hardware_lock
|
|
finish_portal_session
|
|
echo 'Portal client connection removed.'
|
|
;;
|
|
run)
|
|
start_portal_session
|
|
cleanup() {
|
|
if [[ "$keep" != "yes" ]]; then
|
|
finish_portal_session || true
|
|
fi
|
|
}
|
|
trap cleanup EXIT INT TERM
|
|
export PORTAL_ARTIFACT_DIR="$output_dir"
|
|
export LOCAL_UID="$(id -u)"
|
|
export LOCAL_GID="$(id -g)"
|
|
export PORTAL_BROWSER_MODE="$browser"
|
|
compose_files=(-f "$root/tests/portal-contract/compose.yaml")
|
|
if [[ -n "$station_env" ]]; then
|
|
export PORTAL_STATION_ENV_HOST="$(cd "$(dirname "$station_env")" && pwd)/$(basename "$station_env")"
|
|
compose_files+=(-f "$root/tests/portal-contract/compose.station.yaml")
|
|
fi
|
|
# The contract source is copied into the image; rebuild with Docker cache so
|
|
# this invocation always tests the checked-out files, not a stale image.
|
|
docker compose "${compose_files[@]}" build portal-contract
|
|
docker compose "${compose_files[@]}" run --rm portal-contract
|
|
printf 'Portal contract passed. Artifacts: %s\n' "$output_dir"
|
|
if [[ "$keep" == "yes" ]]; then
|
|
printf 'Portal session remains connected; run ./tools/portal-hardware down when finished.\n'
|
|
fi
|
|
;;
|
|
*) usage ;;
|
|
esac
|