fix: show correct 'reach the Pi' URL per uplink mode + BUG-15

- Settings: when the Pi is on the phone's hotspot (mode phone), show the
  Pi's hotspot IP (http://<ip>) with an LTE-only hint instead of the AP URL
- BUG-15 documents the phone dual-role routing loop (host hotspot + connect
  to AP simultaneously breaks the uplink)
This commit is contained in:
Mathieu Moran
2026-08-12 22:38:31 -04:00
parent 51417abf75
commit 7f6d6c3a89
3 changed files with 42 additions and 3 deletions
+14 -1
View File
@@ -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://<pi-hotspot-ip>` (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.
---
+15 -2
View File
@@ -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;
}
+13
View File
@@ -133,6 +133,19 @@
If the page doesn't load, try <strong>disabling cellular/mobile data</strong> on your phone.
</div>
</div>
<div id="in-car-phone-info" hidden>
<p class="mb-2 fw-semibold">Your phone can reach the Pi at:</p>
<div class="d-flex align-items-center gap-2 mb-3">
<code class="fs-5" id="phone-url">http://10.21.0.112</code>
<button class="btn btn-outline-secondary btn-sm" id="copy-phone-url" type="button" title="Copy">
<i class="fas fa-copy"></i>
</button>
</div>
<div class="alert alert-info py-2 mb-0 small">
<i class="fas fa-info-circle me-1"></i>
The Pi is on your phone's hotspot. Keep the phone on <strong>mobile data (LTE)</strong> — don't also connect it to the Pi's WiFi.
</div>
</div>
<div id="in-car-wifi-info" hidden>
<p class="mb-1 small text-muted">The Pi is connected to WiFi. Open <code>http://yaris.local</code> from any device on the same network.</p>
</div>