diff --git a/BUGS.md b/BUGS.md index d202dd8..efc540b 100644 --- a/BUGS.md +++ b/BUGS.md @@ -8,7 +8,20 @@ When CLOSED, move the entire entry to Resolved — don't duplicate. ## Open bugs -(No open bugs) +### BUG-15 — Phone can't host the hotspot and connect to the Pi's AP at once +- **Status**: `OPEN` 2026-08-12 +- **Symptom**: With the phone hosting the hotspot (Pi's uplink) *and* connected to the + Pi's AP ("vroom vroom yaris de course"), the Pi loses internet. Uploads fail with + `NameResolutionError` — the phone's WiFi-sharing routes the hotspot's traffic back + through the no-internet AP, creating a routing loop. +- **Cause**: phone-OS limitation — a single phone can't cleanly be both the Pi's + internet uplink (AP/hotspot host) and its WiFi client (on the Pi's AP) simultaneously. +- **Intended use / workaround**: phone must be **LTE-only** (WiFi off) to serve as the + Pi's uplink. Reach the Pi UI from that phone over the hotspot at + `http://` (Settings → "In-car hotspot" shows it), or from a second + device on the AP. +- **Pi-side hardening shipped 2026-08-12**: `phone-hotspot` now forces public DNS + (`8.8.8.8`/`1.1.1.1`) and the Settings page surfaces the correct URL per uplink mode. --- diff --git a/static/js/settings.js b/static/js/settings.js index 45a9658..ea1ac48 100644 --- a/static/js/settings.js +++ b/static/js/settings.js @@ -302,22 +302,35 @@ async function loadUplinkStatus() { // In-car access card const hotspotInfo = document.getElementById('in-car-hotspot-info'); + const phoneInfo = document.getElementById('in-car-phone-info'); const wifiInfo = document.getElementById('in-car-wifi-info'); const disconnectedInfo = document.getElementById('in-car-disconnected-info'); const hotspotUrl = document.getElementById('hotspot-url'); + const phoneUrl = document.getElementById('phone-url'); const copyBtn = document.getElementById('copy-hotspot-url'); - if (status.ap_active && status.ap_ip) { + const copyPhoneBtn = document.getElementById('copy-phone-url'); + if (status.mode === 'phone' && status.ip_address) { + phoneUrl.textContent = `http://${status.ip_address}`; + hotspotInfo.hidden = true; + phoneInfo.hidden = false; + wifiInfo.hidden = true; + disconnectedInfo.hidden = true; + if (copyPhoneBtn) copyPhoneBtn.onclick = () => navigator.clipboard.writeText(`http://${status.ip_address}`); + } else if (status.ap_active && status.ap_ip) { hotspotUrl.textContent = `http://${status.ap_ip}`; hotspotInfo.hidden = false; + phoneInfo.hidden = true; wifiInfo.hidden = true; disconnectedInfo.hidden = true; if (copyBtn) copyBtn.onclick = () => navigator.clipboard.writeText(`http://${status.ap_ip}`); - } else if (status.mode === 'wifi' || status.mode === 'phone') { + } else if (status.mode === 'wifi') { hotspotInfo.hidden = true; + phoneInfo.hidden = true; wifiInfo.hidden = false; disconnectedInfo.hidden = true; } else { hotspotInfo.hidden = true; + phoneInfo.hidden = true; wifiInfo.hidden = true; disconnectedInfo.hidden = false; } diff --git a/templates/settings.html b/templates/settings.html index 562ab7f..989f3aa 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -133,6 +133,19 @@ If the page doesn't load, try disabling cellular/mobile data on your phone. +