159 lines
5.0 KiB
Bash
159 lines
5.0 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
# shellcheck disable=SC1091
|
|
source "${SCRIPT_DIR}/common.sh"
|
|
|
|
STEP="5g-dial"
|
|
|
|
read_detected_interface() {
|
|
local info_json="$1"
|
|
|
|
if [[ ! -f "${info_json}" ]]; then
|
|
return 1
|
|
fi
|
|
|
|
python3 -c 'import json, sys; print((json.load(open(sys.argv[1], encoding="utf-8")).get("interface") or "").strip())' "${info_json}"
|
|
}
|
|
|
|
disable_interfaces() {
|
|
local raw_list="$1"
|
|
local iface
|
|
local nmcli_available=0
|
|
|
|
if [[ -z "${raw_list}" ]]; then
|
|
return 0
|
|
fi
|
|
if command -v nmcli >/dev/null 2>&1; then
|
|
nmcli_available=1
|
|
fi
|
|
|
|
for iface in ${raw_list//,/ }; do
|
|
if [[ -z "${iface}" ]]; then
|
|
continue
|
|
fi
|
|
blitz_log "${STEP}" "disable-interface" "start" "iface=${iface}" 0
|
|
if [[ "${nmcli_available}" -eq 1 ]]; then
|
|
nmcli device disconnect "${iface}" >/dev/null 2>&1 || true
|
|
fi
|
|
if ip link show dev "${iface}" >/dev/null 2>&1; then
|
|
if ip link set dev "${iface}" down; then
|
|
blitz_log "${STEP}" "disable-interface" "success" "iface=${iface}" 0
|
|
else
|
|
rc=$?
|
|
blitz_log "${STEP}" "disable-interface" "failure" "iface=${iface}" "${rc}"
|
|
return "${rc}"
|
|
fi
|
|
else
|
|
blitz_log "${STEP}" "disable-interface" "success" "iface=${iface} not present, skipping" 0
|
|
fi
|
|
done
|
|
}
|
|
|
|
wait_for_serial() {
|
|
local serial_port="$1"
|
|
local timeout_sec="$2"
|
|
local waited=0
|
|
|
|
while (( waited < timeout_sec )); do
|
|
if [[ -e "${serial_port}" ]]; then
|
|
blitz_log "${STEP}" "wait-serial" "success" "serial_port=${serial_port} waited_sec=${waited}" 0
|
|
return 0
|
|
fi
|
|
if (( waited == 0 || waited % 5 == 0 )); then
|
|
blitz_log "${STEP}" "wait-serial" "waiting" "serial_port=${serial_port} waited_sec=${waited}" 0
|
|
fi
|
|
sleep 1
|
|
waited=$(( waited + 1 ))
|
|
done
|
|
|
|
blitz_log "${STEP}" "wait-serial" "failure" "serial_port=${serial_port} timeout_sec=${timeout_sec}" 1
|
|
return 1
|
|
}
|
|
|
|
wait_for_route() {
|
|
local target_ip="$1"
|
|
local timeout_sec="$2"
|
|
local expected_interface="${3:-}"
|
|
local waited=0
|
|
local route_output
|
|
|
|
while (( waited < timeout_sec )); do
|
|
route_output="$(blitz_route_ready "${target_ip}" "${expected_interface}" || true)"
|
|
if [[ -n "${route_output}" ]]; then
|
|
blitz_log "${STEP}" "route-check" "success" "target_ip=${target_ip} interface=${expected_interface:-auto} route=${route_output}" 0
|
|
return 0
|
|
fi
|
|
if (( waited == 0 || waited % 5 == 0 )); then
|
|
blitz_log "${STEP}" "route-check" "waiting" "target_ip=${target_ip} interface=${expected_interface:-auto} waited_sec=${waited}" 0
|
|
fi
|
|
sleep 1
|
|
waited=$(( waited + 1 ))
|
|
done
|
|
|
|
blitz_log "${STEP}" "route-check" "failure" "target_ip=${target_ip} interface=${expected_interface:-auto} timeout_sec=${timeout_sec}" 1
|
|
return 1
|
|
}
|
|
|
|
blitz_load_boot_env
|
|
blitz_require_root "${STEP}"
|
|
blitz_require_command ip "${STEP}"
|
|
blitz_require_command python3 "${STEP}"
|
|
blitz_require_file "${BLITZ_5G_DIAL_DIR}/rndis_dial.py" "${STEP}"
|
|
|
|
if [[ -z "${BLITZ_TIME_SERVER_IP}" ]]; then
|
|
blitz_log "${STEP}" "precheck" "failure" "BLITZ_TIME_SERVER_IP is empty and no fallback could be derived" 1
|
|
exit 1
|
|
fi
|
|
|
|
disable_interfaces "${BLITZ_5G_DISABLE_INTERFACES:-}"
|
|
|
|
if [[ -n "${BLITZ_5G_INTERFACE:-}" ]]; then
|
|
route_output="$(blitz_route_ready "${BLITZ_TIME_SERVER_IP}" "${BLITZ_5G_INTERFACE}" || true)"
|
|
if [[ -n "${route_output}" ]]; then
|
|
blitz_log "${STEP}" "dial" "already_up" "target_ip=${BLITZ_TIME_SERVER_IP} interface=${BLITZ_5G_INTERFACE} route=${route_output}" 0
|
|
exit 0
|
|
fi
|
|
else
|
|
blitz_log "${STEP}" "route-check" "info" "BLITZ_5G_INTERFACE is empty, skipping pre-dial route shortcut and using auto-detect mode" 0
|
|
fi
|
|
|
|
wait_for_serial "${BLITZ_5G_SERIAL_PORT}" "${BLITZ_5G_SERIAL_WAIT_SEC}"
|
|
|
|
dial_cmd=(
|
|
python3
|
|
rndis_dial.py
|
|
--serial-port "${BLITZ_5G_SERIAL_PORT}"
|
|
--modem-subnet "${BLITZ_5G_MODEM_SUBNET}"
|
|
)
|
|
if [[ -n "${BLITZ_5G_INTERFACE:-}" ]]; then
|
|
dial_cmd+=(--interface "${BLITZ_5G_INTERFACE}")
|
|
fi
|
|
case "${BLITZ_5G_SKIP_DHCP:-0}" in
|
|
1|true|TRUE|yes|YES)
|
|
dial_cmd+=(--skip-dhcp)
|
|
;;
|
|
esac
|
|
|
|
pushd "${BLITZ_5G_DIAL_DIR}" >/dev/null
|
|
blitz_run "${STEP}" "dial" "${dial_cmd[@]}"
|
|
popd >/dev/null
|
|
|
|
resolved_interface="${BLITZ_5G_INTERFACE:-}"
|
|
if [[ -z "${resolved_interface}" ]]; then
|
|
resolved_interface="$(read_detected_interface "${BLITZ_5G_INFO_JSON}" || true)"
|
|
if [[ -n "${resolved_interface}" ]]; then
|
|
blitz_log "${STEP}" "resolve-interface" "success" "resolved interface from ${BLITZ_5G_INFO_JSON}: ${resolved_interface}" 0
|
|
else
|
|
blitz_log "${STEP}" "resolve-interface" "failure" "failed to read detected interface from ${BLITZ_5G_INFO_JSON}" 1
|
|
fi
|
|
fi
|
|
|
|
if [[ -n "${resolved_interface}" ]]; then
|
|
wait_for_route "${BLITZ_TIME_SERVER_IP}" "${BLITZ_5G_ROUTE_WAIT_SEC}" "${resolved_interface}"
|
|
blitz_log "${STEP}" "complete" "success" "5G dial completed and route is ready on ${resolved_interface}" 0
|
|
else
|
|
blitz_log "${STEP}" "complete" "success" "5G dial completed but route wait was skipped because no interface could be resolved; refer to rndis_dial.py logs" 0
|
|
fi
|