feat(network): wlan0 fallback if T3U dongle is absent
- PRIMARY_INTERFACE=wlan1, FALLBACK_INTERFACE=wlan0 - resolve_interface() checks /sys/class/net at startup and picks whichever exists - INTERFACE is module-level, so all functions use the correct iface automatically - restore_fallback() now also tries home-wifi-fb / Hotspot on wlan0 if wlan1 is primary but failed - install_netwatch.sh creates home-wifi-fb profile on wlan0 (lower autoconnect-priority=5) - wlan0 stays managed=yes (fallback) instead of being hard-disabled - Status JSON now includes 'interface' field for diagnostics Co-authored-by: Copilot <[email protected]>
This commit is contained in:
@@ -13,6 +13,7 @@ set -euo pipefail
|
||||
|
||||
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
WLAN=wlan1 # T3U dongle — change to wlan0 if reverting to onboard
|
||||
WLAN_FB=wlan0 # onboard fallback
|
||||
|
||||
sudo systemctl stop yaris-uplink-wait.service 2>/dev/null || true
|
||||
sudo systemctl stop yaris-netwatch.timer yaris-netwatch.service 2>/dev/null || true
|
||||
@@ -39,9 +40,27 @@ if nmcli connection show phone-hotspot >/dev/null 2>&1; then
|
||||
802-11-wireless.mtu 1400
|
||||
fi
|
||||
|
||||
# Disable onboard wlan0 so it doesn't interfere
|
||||
sudo nmcli device disconnect wlan0 2>/dev/null || true
|
||||
sudo nmcli device set wlan0 managed no 2>/dev/null || true
|
||||
# Create wlan0 fallback profiles (lower autoconnect-priority so wlan1 wins)
|
||||
# home-wifi-fb: same SSID as home-wifi but on wlan0
|
||||
HOME_SSID=$(nmcli -g 802-11-wireless.ssid connection show home-wifi 2>/dev/null || true)
|
||||
HOME_PSK=$(sudo nmcli -g 802-11-wireless-security.psk connection show --show-secrets home-wifi 2>/dev/null || true)
|
||||
if [ -n "$HOME_SSID" ] && [ -n "$HOME_PSK" ]; then
|
||||
nmcli connection delete home-wifi-fb 2>/dev/null || true
|
||||
sudo nmcli connection add \
|
||||
type wifi \
|
||||
con-name home-wifi-fb \
|
||||
ifname "$WLAN_FB" \
|
||||
ssid "$HOME_SSID" \
|
||||
-- \
|
||||
wifi-security.key-mgmt wpa-psk \
|
||||
wifi-security.psk "$HOME_PSK" \
|
||||
connection.autoconnect yes \
|
||||
connection.autoconnect-priority 5
|
||||
echo "Created home-wifi-fb fallback on $WLAN_FB"
|
||||
fi
|
||||
|
||||
# Re-enable wlan0 as a managed (but low-priority) fallback
|
||||
sudo nmcli device set "$WLAN_FB" managed yes 2>/dev/null || true
|
||||
|
||||
sudo cp "$REPO_DIR/deploy/yaris-netwatch.service" /etc/systemd/system/yaris-netwatch.service
|
||||
sudo cp "$REPO_DIR/deploy/yaris-netwatch.timer" /etc/systemd/system/yaris-netwatch.timer
|
||||
|
||||
+32
-1
@@ -12,7 +12,8 @@ import uuid
|
||||
PHONE_CONNECTION = "phone-hotspot"
|
||||
HOME_CONNECTION = "home-wifi"
|
||||
AP_CONNECTION = "Hotspot"
|
||||
INTERFACE = "wlan1" # TP-Link T3U dongle — all client + AP traffic
|
||||
PRIMARY_INTERFACE = "wlan1" # TP-Link T3U dongle — preferred
|
||||
FALLBACK_INTERFACE = "wlan0" # onboard — used if T3U is absent
|
||||
STATUS_PATH = "/var/lib/yaris-obd/uplink-status.json"
|
||||
PHONE_KEYFILE = (
|
||||
"/etc/NetworkManager/system-connections/"
|
||||
@@ -24,6 +25,24 @@ class UplinkError(RuntimeError):
|
||||
pass
|
||||
|
||||
|
||||
def _interface_exists(iface):
|
||||
"""Return True if the kernel sees this network interface."""
|
||||
return os.path.exists(f"/sys/class/net/{iface}")
|
||||
|
||||
|
||||
def resolve_interface():
|
||||
"""Return PRIMARY_INTERFACE if it exists, else FALLBACK_INTERFACE."""
|
||||
if _interface_exists(PRIMARY_INTERFACE):
|
||||
return PRIMARY_INTERFACE
|
||||
if _interface_exists(FALLBACK_INTERFACE):
|
||||
return FALLBACK_INTERFACE
|
||||
return PRIMARY_INTERFACE # return primary anyway; nmcli will error clearly
|
||||
|
||||
|
||||
# Module-level convenience — resolved once at startup.
|
||||
INTERFACE = resolve_interface()
|
||||
|
||||
|
||||
def run_nmcli(*args, timeout=45, check=True):
|
||||
process = subprocess.run(
|
||||
["nmcli", *args],
|
||||
@@ -149,6 +168,7 @@ def write_status(action, error=None):
|
||||
status = {
|
||||
"action": action,
|
||||
"active_connection": current,
|
||||
"interface": INTERFACE,
|
||||
"error": error,
|
||||
"last_phone_ip": last_phone_ip,
|
||||
"updated_at": time.time(),
|
||||
@@ -182,6 +202,17 @@ def restore_fallback():
|
||||
if activate(HOME_CONNECTION):
|
||||
write_status("connected_home")
|
||||
return True
|
||||
# If the primary interface (wlan1) failed, try the wlan0 fallback profiles
|
||||
if INTERFACE == PRIMARY_INTERFACE and _interface_exists(FALLBACK_INTERFACE):
|
||||
# Temporarily try connections bound to wlan0
|
||||
for conn in (f"{HOME_CONNECTION}-fb", AP_CONNECTION):
|
||||
proc = subprocess.run(
|
||||
["nmcli", "--wait", "30", "connection", "up", conn],
|
||||
capture_output=True, text=True, timeout=35,
|
||||
)
|
||||
if proc.returncode == 0:
|
||||
write_status(f"fallback_wlan0_{conn}")
|
||||
return True
|
||||
if activate(AP_CONNECTION):
|
||||
write_status("restored_local_hotspot")
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user