Crash reports carry elf_sha256 (first 16 hex chars of the crashing build's
ELF SHA-256). ELFs are now stored under that key in
{firmware_storage_path}/elf/, uploaded either with a firmware release
(optional elf_file on POST /upload and PUT /{id}) or standalone via
POST /api/firmware/elf. The ELF is validated before the release is created.
GET /api/firmware/elf/{sha} reports whether that build's ELF exists and
whether the decoder is available; POST /api/firmware/elf/{sha}/decode runs
xtensa-esp32-elf-addr2line -pfiaC over the addresses. The decoder is looked
up via settings.addr2line_path or PATH. It is NOT in the Docker image yet,
so decoding reports "not installed" until the toolchain is added; the
console falls back to a copy-paste addr2line command.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The shared legacy password is still needed for boards on pre-HMAC
firmware, but it was accepted for any username. Now:
- controlled by MQTT_ALLOW_LEGACY_PASSWORD (config.py, default true;
documented in .env.example) so it can be switched off without a deploy,
- only accepted for device-shaped usernames (uppercase alphanumeric
segments joined by "-", optional "-kiosk"), never for app_ users or
any other shape,
- every successful legacy login is logged at WARNING with the username,
rate-limited to once per username per hour, so the boards still
depending on it are visible before the flag is turned off.
HMAC auth is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ESP32 devices can't spare the 40KB+ RAM a TLS client needs, so Firebase
Storage's HTTPS-only download URLs were blocking melody downloads. Binaries
are now written to local disk (./data/melody_binaries) and served through a
new unauthenticated /api/melodies/download/{pid} route, exposed publicly on
a separate melodies.bellsystems.net vhost (plain HTTP, no TLS) so the main
console domain can stay HTTPS-only with no exceptions. Preview audio still
uses Firebase Storage since it's only ever fetched by the HTTPS admin UI.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>