Add resilient dual-radio network failover
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
CONFIG_FILE="/etc/pi-car-companion/companion.env"
|
||||
HOTSPOT_CONNECTION="pi-car-hotspot"
|
||||
HOTSPOT_INTERFACE="wlan0"
|
||||
UPSTREAM_INTERFACE="wlan1"
|
||||
HOTSPOT_ADDRESS="10.42.0.1/24"
|
||||
HOTSPOT_SSID="${1:-MG4-Companion}"
|
||||
|
||||
if [[ ${EUID} -ne 0 ]]; then
|
||||
exec sudo -- "$0" "$@"
|
||||
fi
|
||||
if [[ ! -f "${CONFIG_FILE}" ]]; then
|
||||
echo "Pi Car Companion is not installed. Run install.sh first." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! "${HOTSPOT_SSID}" =~ ^[[:alnum:]_.-]{1,32}$ ]]; then
|
||||
echo "The hotspot SSID must contain 1-32 letters, numbers, dots, hyphens, or underscores." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$(nmcli --get-values GENERAL.STATE device show "${UPSTREAM_INTERFACE}" 2>/dev/null || true)" != 100* ]]; then
|
||||
echo "${UPSTREAM_INTERFACE} must be connected to a saved upstream network before failover is enabled." >&2
|
||||
echo "Connect it first with: sudo nmcli --ask device wifi connect '<SSID>' ifname ${UPSTREAM_INTERFACE} name upstream-home" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
read -r -s -p "Password for ${HOTSPOT_SSID} (8-63 characters): " hotspot_password
|
||||
echo
|
||||
if (( ${#hotspot_password} < 8 || ${#hotspot_password} > 63 )) || [[ ! "${hotspot_password}" =~ ^[[:alnum:]_.-]+$ ]]; then
|
||||
echo "The hotspot password must contain 8-63 letters, numbers, dots, hyphens, or underscores." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
hotspot_file="/etc/NetworkManager/system-connections/${HOTSPOT_CONNECTION}.nmconnection"
|
||||
hotspot_uuid="$(uuidgen)"
|
||||
temporary_file="$(mktemp)"
|
||||
trap 'rm -f -- "${temporary_file}"' EXIT
|
||||
cat > "${temporary_file}" <<EOF
|
||||
[connection]
|
||||
id=${HOTSPOT_CONNECTION}
|
||||
uuid=${hotspot_uuid}
|
||||
type=wifi
|
||||
interface-name=${HOTSPOT_INTERFACE}
|
||||
autoconnect=false
|
||||
|
||||
[wifi]
|
||||
band=bg
|
||||
mode=ap
|
||||
ssid=${HOTSPOT_SSID}
|
||||
|
||||
[wifi-security]
|
||||
key-mgmt=wpa-psk
|
||||
psk=${hotspot_password}
|
||||
|
||||
[ipv4]
|
||||
address1=${HOTSPOT_ADDRESS}
|
||||
method=shared
|
||||
|
||||
[ipv6]
|
||||
method=disabled
|
||||
EOF
|
||||
if nmcli --get-values NAME connection show | grep -Fxq "${HOTSPOT_CONNECTION}"; then
|
||||
nmcli connection delete "${HOTSPOT_CONNECTION}"
|
||||
fi
|
||||
install -m 0600 -o root -g root "${temporary_file}" "${hotspot_file}"
|
||||
nmcli connection load "${hotspot_file}"
|
||||
hotspot_password=""
|
||||
|
||||
set_env() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
if grep -q "^${key}=" "${CONFIG_FILE}"; then
|
||||
sed -i "s|^${key}=.*|${key}=${value}|" "${CONFIG_FILE}"
|
||||
else
|
||||
printf '%s=%s\n' "${key}" "${value}" >> "${CONFIG_FILE}"
|
||||
fi
|
||||
}
|
||||
|
||||
set_env NETWORK_MANAGER_ENABLED true
|
||||
set_env NETWORK_HOTSPOT_INTERFACE "${HOTSPOT_INTERFACE}"
|
||||
set_env NETWORK_UPSTREAM_INTERFACE "${UPSTREAM_INTERFACE}"
|
||||
set_env NETWORK_HOTSPOT_CONNECTION "${HOTSPOT_CONNECTION}"
|
||||
set_env NETWORK_PROBE_TIMEOUT_SECONDS 60
|
||||
set_env NETWORK_STABILITY_SECONDS 10
|
||||
set_env NETWORK_POLL_SECONDS 5
|
||||
|
||||
systemctl enable --now pi-car-companion-network.service
|
||||
systemctl restart pi-car-companion.service
|
||||
|
||||
upstream_address="$(nmcli --get-values IP4.ADDRESS device show "${UPSTREAM_INTERFACE}" | head -n 1)"
|
||||
echo "Network failover is enabled."
|
||||
echo "The dashboard will remain reachable through ${UPSTREAM_INTERFACE} at ${upstream_address:-its current address}."
|
||||
echo "The car hotspot is ${HOTSPOT_SSID} and its dashboard address is http://10.42.0.1:8787."
|
||||
Reference in New Issue
Block a user