fix: USB tether monitor — bring interface admin-up on thread start

operstate can't report carrier while interface is admin-down.
Now sets 'ip link set usb2 up' at monitor startup so carrier
changes are visible immediately when phone tethering is toggled.
This commit is contained in:
kayos 2026-03-25 15:19:46 -07:00
parent 3945f24f46
commit d09f2d4b35

View file

@ -1846,12 +1846,7 @@ def _start_usb_tether():
if not _is_tether_iface(iface):
return
logger.info(f"[usb-tether] {iface} carrier detected — bringing up tethering")
try:
subprocess.run(["ip", "link", "set", iface, "up"], timeout=5)
except Exception as e:
logger.warning(f"[usb-tether] ip link set up failed: {e}")
return
logger.info(f"[usb-tether] {iface} carrier detected — running DHCP")
try:
# Run udhcpc in background, store PID for cleanup
@ -1918,6 +1913,15 @@ def usb_tether_monitor():
"""Background thread: watch usb2 operstate, auto-connect/disconnect."""
iface = USB_TETHER_IFACE
logger.info(f"[usb-tether] Monitor started watching {iface}")
# Bring interface up immediately so kernel can report carrier changes.
# The interface stays admin-up but no IP until tethering is enabled on phone.
try:
subprocess.run(["ip", "link", "set", iface, "up"], timeout=5, check=False)
logger.info(f"[usb-tether] {iface} set admin-up (waiting for tethering)")
except Exception as e:
logger.warning(f"[usb-tether] Could not bring {iface} up: {e}")
last_state = _read_operstate(iface)
while True:
@ -1933,19 +1937,16 @@ def usb_tether_monitor():
last_state = state
continue
# 'up' or 'unknown' = active (Android USB tethering reports 'unknown' not 'up')
is_active = state in ("up", "unknown")
was_active_state = last_state in ("up", "unknown")
if is_active and not was_active_state:
# Carrier just arrived
# 'up' = carrier present (interface is already admin-up from monitor start)
if state == "up" and last_state != "up":
# Carrier just arrived — tethering enabled on phone
with _usb_tether_lock:
already_active = _usb_tether_state["active"]
if not already_active:
_start_usb_tether()
elif not is_active and was_active_state:
# Carrier just dropped
elif state != "up" and last_state == "up":
# Carrier lost — phone unplugged or tethering disabled
with _usb_tether_lock:
was_active = _usb_tether_state["active"]
if was_active: