Support WebUSB in repeater setup and console

This commit is contained in:
Jonathon Leight
2026-08-09 19:41:23 -04:00
parent 717b8bce2d
commit 4e191de98f
4 changed files with 17 additions and 9 deletions
+5 -1
View File
@@ -143,7 +143,10 @@
{{else if eq .Step "serial"}}
{{/* ---- Step 3 (serial): configure a brand-new repeater and run over USB ---- */}}
<div id="unsupported" class="alert alert-danger" role="alert" hidden>
This browser doesn't support the Web Serial API. Use Chrome, Edge, or another Chromium-based browser over HTTPS or on localhost.
<div>
This browser can't connect to USB devices. Use Chrome or Edge, or Firefox 151 or later,
on desktop — or Chrome on Android — over HTTPS or on localhost.
</div>
</div>
<div class="card">
@@ -279,6 +282,7 @@
<link rel="stylesheet" href="{{ asset "/static/leaflet.css" }}">
<script src="{{ asset "/static/leaflet.js" }}"></script>
<script src="{{ asset "/static/regionmap.js" }}"></script>
<script src="{{ asset "/static/serial-port.js" }}"></script>
<script src="{{ asset "/static/serial-setup.js" }}"></script>
{{else}}
+5 -1
View File
@@ -60,7 +60,10 @@ swap needs no new markup. The flex row is nested so the [hidden] attribute wins
<div class="card-header"><h2 class="card-title">Console</h2></div>
<div class="card-body">
<div id="unsupported" class="alert alert-danger" role="alert" hidden>
This browser does not support WebSerial. Use Chrome, Edge, or another Chromium-based browser over HTTPS or on localhost.
<div>
This browser can't connect to USB devices. Use Chrome or Edge, or Firefox 151 or later,
on desktop — or Chrome on Android — over HTTPS or on localhost.
</div>
</div>
<div class="mb-3">
<label class="form-label" for="path">Path <span class="form-label-description">optional</span></label>
@@ -154,5 +157,6 @@ swap needs no new markup. The flex row is nested so the [hidden] attribute wins
<script nonce="{{.Nonce}}">
window.MESHTENDER_WS = (location.protocol === "https:" ? "wss://" : "ws://") + location.host + "/repeaters/{{.Repeater.PublicID}}/console/ws{{if .Debug}}?debug=1{{end}}";
</script>
<script src="{{ asset "/static/serial-port.js" }}"></script>
<script src="{{ asset "/static/console.js" }}"></script>
{{end}}
+5 -5
View File
@@ -6,7 +6,7 @@
// separate "apply org configuration" script (console-config.js) can send commands
// and react to session state without owning the socket:
// window.MeshConsole.ready — is the modem connected & the session live?
// window.MeshConsole.supported — does this browser have WebSerial at all?
// window.MeshConsole.supported — can this browser reach a serial device at all?
// window.MeshConsole.connect() — open the modem + session (needs a user gesture)
// window.MeshConsole.send(text) — send a CLI command; returns false if not ready
// window.MeshConsole.getLocation() — ask the server to fetch the repeater's coords
@@ -26,8 +26,8 @@
// whether a command can be sent right now.
const api = {
ready: false,
supported: "serial" in navigator,
connect() {}, // replaced with the real routine below when WebSerial is present
supported: !!(window.MeshSerial && window.MeshSerial.supported),
connect() {}, // replaced with the real routine below when a serial transport is present
send(text) {
const t = String(text || "").trim();
if (!t || !api.ready || !ws || ws.readyState !== WebSocket.OPEN) return false;
@@ -57,7 +57,7 @@
return url;
}
if (!("serial" in navigator)) {
if (!api.supported) {
const unsupportedEl = document.getElementById("unsupported");
if (unsupportedEl) unsupportedEl.hidden = false;
if (connectBtn) connectBtn.disabled = true;
@@ -125,7 +125,7 @@
log.innerHTML = "";
try {
addLog("info", "Requesting serial port…");
port = await navigator.serial.requestPort();
port = await MeshSerial.requestPort();
await port.open({ baudRate: 115200 });
writer = port.writable.getWriter();
reader = port.readable.getReader();
+2 -2
View File
@@ -39,7 +39,7 @@
};
// --- feature detection -------------------------------------------------
var hasSerial = "serial" in navigator;
var hasSerial = !!(window.MeshSerial && window.MeshSerial.supported);
var hasEd25519 = !!(window.crypto && window.crypto.subtle);
if (!hasSerial || !hasEd25519) {
var u = $("unsupported");
@@ -276,7 +276,7 @@
var decoder = new TextDecoder();
try {
addLog("info", "Requesting serial port…");
port = await navigator.serial.requestPort();
port = await MeshSerial.requestPort();
await port.open({ baudRate: 115200 });
writer = port.writable.getWriter();
reader = port.readable.getReader();