Position: the Fix line (or how long it has been searching), latitude and
longitude in decimal degrees or degrees-minutes-seconds (Settings ->
Coordinates), the Maidenhead locator, altitude, speed and course, HDOP
and UTC. Sky: the satellites by azimuth and elevation, coloured by
constellation, filled when used in the Fix, with used/in-view counts.
Tab switches. lib/gnss/geo_format holds the formatting, the locator and
the sky projection, host-tested (6 tests; locators checked against
FN31pr and JN58td).
Verified on the device by a window: 3D Fix from GPS, GLONASS, Galileo
and BeiDou.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
- EcdsaVerifier (mbedTLS, embedded public key) and EspOtaSink (writes
the inactive app slot, esp_ota_end validates the image, then sets
the boot partition)
- UpdateService: listens on TCP 3232 (and mDNS roro9stack-<id>) while
Wi-Fi is Connected; streams into UpdateParser; replies OK/ERR to the
sender; remembers the pending version so a Rollback is reported
after the reboot
- Probation (host-tested): confirm after the first frame + 30 s + Wi-Fi
(if configured); roll back if configured Wi-Fi never connects in 3 min
- Main loop: full-screen progress while receiving; restart once
installed, waiting up to 60 s for Text Entry to end
- Settings > Firmware: version, Probation status, push address and
name, and the .ota files in /updates on the SD card to install
- StorageService.runJob() runs work on the storage task (SD installs)
- wifi status prints IP and running version; RORO_TEST_CRASH test hook
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
- lib/wifi (host-tested): scan_log (CSV field quoting, header/row, a
once-per-interval throttle) and network_list_view (sort by signal /
channel / name, filter open-only / hide-hidden / strong-only)
- ScanEntry moved to lib/wifi so both are testable on the PC
- Wi-Fi Tools networks view: s sort, o/h/w filters, l toggles logging
to /wifi/scans/<date>.csv (header + one row per AP per logged scan,
throttled 30 s, needs the clock for timestamps); foreground-only
- Wi-Fi scan logs replace probe-request logs as a clean-up category
- Serial: cat <path>, and key <char> injects a character
Verified on the device: CSV written with header, timestamps, BSSID,
channel, RSSI, security and SSID; hidden networks marked.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
- Alt + ; / Alt + . scroll the Buffer back and forward
- Up / Down (Fn + ; / Fn + .) browse the last 30 sent lines, shell-style,
returning to the draft past the newest (InputHistory, host-tested)
- /j is short for /join
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
- With NickServ, auto-join waits for the logged-in reply (900) or 2 s
at most, so registered-only IRC channels let us in
- A failed SASL login falls back to NickServ (its own password, or the
SASL account and password)
- IDENTIFY names the account explicitly, and once logged in on a
fallback nick, REGAIN takes ours back from a stale session
- Auto-join entries take keys ("#private key, #public"); keys from
/join are reused when rejoining; keyed channels go first in JOIN
- Serial irc dump: whole Buffers, and which login is configured
(never the secrets)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
The IRC App edited the live config while the IRC task could be reading
it to connect. The App now edits a copy; applyConfig() validates it and
swaps it in under the lock, and the task connects from a snapshot.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
- lib/wifi (host-tested): channel occupancy (neighbour spill, signal
weighting, quietest of 1/6/11) and a signal tracker (history, lost
detection, click interval)
- WifiService: scan results carry BSSID, channel and security; a scan
can target one channel for quick tracker refreshes; endListScans()
turns the radio back off when Wi-Fi is disabled
- Wi-Fi Tools App: networks nearby, channel occupancy bars, signal
tracker with clicks (m to mute)
- M1 plan: Monitoring-mode views and captures deferred
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
- Chat: header (Buffer n/N, unread elsewhere, topic or connection
state), wrapped hh:mm <nick> lines (own in accent, Mentions green,
info grey), input line; Tab cycles Buffers, Fn+Up/Down scrolls back,
Enter sends, Back leaves while the IRC Service keeps running
- /settings: server form (host, port, TLS, self-signed pinning, nick,
SASL, NickServ, auto-join); Save & reconnect restarts the session
- Opening the App starts the IRC Service; viewing a Buffer clears its
unread count; IrcSession gains a revision counter for redraws
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
- lib/storage_model (host-tested): FAT-safe names, daily Log paths,
dates from Log/Capture file names, CleanupPlan by category and age,
byte formatting
- StorageService does all card I/O on its task: queued Log lines are
written in batches each second (dropped while Logs are paused),
plus file listing and deletion jobs
- Settings > Storage moves into StoragePage: usage, Clean up
(category, age with size preview, confirmation), Erase SD card
- Clock: local date for Log names
- Serial: log <text>, sd list
Verified on the device: lines land in /irc/dev/#test/2026-10-02.log
with folders created as needed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
- lib/wifi (host-tested): SavedNetworks (up to 8, validated, hidden
flag, persisted) and WifiController (joins the strongest Saved
Network, tries hidden ones in turn, backoff 10/30/60 s, connect
timeout, Monitoring override, radio off without Saved Networks)
- WifiService carries out the controller's actions, sets the EU
country code, and syncs the Clock over SNTP without touching the TZ
- Wi-Fi On/Off setting; Settings > Wi-Fi page: status, add from a scan
or a hidden network, forget
- Status Bar: W + signal bars, W? while searching, MON while monitoring
- Serial: wifi add / wifi status (replaces the step 1 heap probe)
Verified on the device: joins the test network ~5 s after boot, clock
set over NTP, ~129 KB free heap while connected.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
- lib/apps_model (host-tested): SettingsMenu (rows, readable values,
choices, validation messages) and SetupWizard (names, Region
confirmation, timezone; saves only when finished)
- AppManager: modal Apps that Home/Back can't leave (setup wizard)
- SettingsApp: all settings plus Storage (usage, erase SD behind a
dialog) and About (version, node id, battery, memory, uptime) pages,
replacing the temporary Diagnostics App
- SetupApp: first-boot wizard, opened modally until SetupDone
- Node id and default names derived from the MAC like Meshtastic
- Widget demo is now hidden (About, then w)
- lib_ldf_mode = deep+ so libraries see each other's headers
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT