v0.1.0
Added
- Security: optional duress password (Settings > Security > Duress
Password). Entering it at the boot unlock screen instead of the real
password wipes the identity, messages, contacts, and settings on every
storage tier (NVS, SD, flash), then reboots straight into the normal
first-time-setup screen with no "wiped" indicator shown. The new
Duressmodule stores a verifier blob in NVS and checks candidate
passwords by reusingIdentityCrypto's wrap/unwrap envelope, so a
wrong guess never derives a real key. The wipe routine itself is a new
sharedFactoryWipemodule, also used by the existing manual Factory
Reset. Configured via a small popup (Enable/Disable/Reset), with
validation that the duress password differs from the real one. See
docs/duress-password.md. - Security: optional auto-lock (Settings > Security > Auto-Lock).
Pick an idle timeout — 30 min, 1h, 4h, 8h, 12h, or Disabled (the
default) — and once the device has been idle that long it reboots
back to the at-rest password screen, discarding the decrypted identity
from RAM until the real password is re-entered. - Messaging: anti-spam proof-of-work stamps (
LXStamper), for peers
that require one before accepting a message. Stamps generate in the
background on their own task so sending stays responsive while the
device grinds the proof of work; a confirm overlay asks first if the
required cost is high enough to take a while. Settings > Messaging
gets a stamp cost ceiling editor — stamps above it prompt instead of
generating silently. Seedocs/lxmf-stamps.md. - Radio: new Diagnostics screen (Settings > Radio > Diagnostics),
separate from the existing Frequency/SF/BW/CR/TX Power editor (now
under Settings > Radio > Config). Three pages, cycled with;/.:
Live (TX/RX throughput graph, RSSI/SNR/noise floor, airtime usage,
chip/link status, time since last RX/TX), Counters (packet/failure/
CRC-fail/queue-drop counts and decoded radio device errors, clearable),
and Network (current PHY config, Reticulum path/link counts, last
announce time, known peers, LXMF outbox depth, heap/loop health).
Backed by new packet/error counters on SX1262/LoRaInterface and a new
reusableStatGraphwidget. - GPS: system clock now syncs to UTC directly from the GPS RMC
sentence instead of relying on a user-picked timezone. For local time
display,GPSManagerchecks the GPS fix's coordinates against a new
TimeZoneDBtable of real POSIX TZ rules covering major regions, so
DST transitions land on the correct date; positions outside the table
fall back to a longitude/season estimate. Settings > Time adds a
manual override (toggle + UTC offset field) for when the automatic
estimate is wrong. The status bar clock now has its own permanent
spot instead of alternating with battery percentage, and dims until
GPS confirms a real satellite fix.
Fixed
- LoRa: the radio had no collision avoidance at all — it keyed up
immediately whenever it wasn't itself mid-TX/RX, with no notion of
another node transmitting on the same channel. On a shared
half-duplex channel with more than one active node, this was a direct
cause of delayed/dropped/reordered delivery. Added listen-before-talk:
SX1262::dcd()detects an in-progress carrier/header via the modem's
PREAMBLE_DET/HEADER_DET IRQ flags, andLoRaInterfacenow queues
instead of transmitting into a busy channel, draining the queue once
the channel clears after a randomized contention window sized from
the radio's own symbol time. - LoRa: fixed a duplicate-detection bug in microReticulum's
packet-hashlist eviction — it's astd::set<Bytes>ordered by hash
value, but eviction was erasing from.begin()as if that were
insertion order, so culling discarded whichever hashes were
numerically smallest instead of the actually-oldest ones. Under
sustained traffic this silently undermined duplicate detection. Now
tracks real insertion order separately
(0x00001312/microReticulum@3481921). - Routing: routing and reply targets broke across every reboot —
the message store was initialized before the identity was loaded, and
saved conversation directories were keyed by a truncated hash too
short to address a reply back to. Fixed by initializing the message
store with the loaded identity before refresh, and resolving saved
conversation directories to full peer hashes for reply targets. - LXMF: sends to a peer with no known path were gated on a flat
10s retry timer even after the path had already arrived, so the best
case was a full 10-20s wait.sendDirect()now re-checks
recall()/has_path()every queue-drain pass (10Hz) and only
throttles the actual network-touchingrequest_path()/
ensureOutboundLink()calls to the 10s interval. - LXMF: replaced the reactive, one-shot path nudge for single-hop
peers (raced the reply it was meant to fix, and missed any relayed
message) with a durable per-peer preferred-interface record in
AnnounceManager, persisted across reboots alongside saved contacts. - LXMF: peer names could go stale or vanish after a reboot, or even
mid-session, because names were only ever learned from
AnnounceManager's own rate-limited, debounced announce handler. Name
lookups now fall back to RNS's ownIdentity::recall_app_data()
cache — populated for every announce Transport validates, independent
ofAnnounceManager— and opportunistically backfill the on-disk name
cache when they resolve a name from it. - LXMF: a peer name change never marked the UI dirty, so
MessagesScreenwouldn't pick up an updated name while idle on
screen; a name-change callback now callsui.markContentDirty()
directly. - microReticulum: picked up two upstream fixes via dependency pin
bumps: the previously-stubbed Link retransmission watchdog plus two
resource-transfer bugs (windowed part requests, and outbound/inbound
resource slots never freeing after a transfer concludes;
a71a676); and aRequestReceiptconstructor that threw
new std::invalid_argument(...)(a pointer, not a value), which
silently slipped past any upstreamcatch (const std::exception&)
and leaked the heap-allocated exception (72bdc81).
Changed
- Settings > Wi-Fi > Mode now opens a popup listing OFF/AP/STA with the
active mode marked, instead of silently cycling to the next mode on
every Enter press. - Unified every small fixed-choice setting (Audio, Time Source,
Auto-discover LAN, Theme input mode, Auto-Lock, WiFi Mode, Duress
Password) onto one sharedOptionPopupwidget, replacing a mix of
silent cycle-on-Enter toggles, a dedicated full-screen page, and an
ad-hoc popup. Full-screen lists are now reserved for genuinely
open-ended choices (WiFi scan, TCP connections, Theme presets). Also
cleaned up unclear labels (Radio Config's SF/BW/CR, SD Card's
"Initialize Standalone", TCP's "+ Add Connection", Display's bare
"Name:") and moved SD Card to sit with About/Factory Reset instead of
next to frequently-tuned settings. No stored values, validation, or
applied behavior changed — UI/IA only. - Duress Password moved from a dedicated settings page into the same
popup style, with Enable/Disable/Reset rows.
Removed
- LXMF propagation node (offline messaging via PN) client, added
earlier in this cycle and fully removed before release: PN sync kept
crashing and destabilizing routing on real hardware, and chasing it
down kept colliding with the parts of this firmware that need to be
solid — delivery, routing, the radio link.PropagationClientis
deleted along with every call site, Settings UI screen, and config
field that existed only to support it. Direct LXMF delivery, anti-spam
stamps, routing/interface stickiness, and announce handling are
unaffected — a message either reaches its recipient directly now, or
it fails, same as before PN existed.docs/propagation-nodes.mdkept
as a short note on why this was dropped. - Dead radio-preset code on the Home screen, and the status card it fed.
Build
microReticulumdependency now points at a personal fork (pinned
commit) so the stamp/field supportLXStamperneeds, plus the
reliability fixes above, can land as real commits there instead of
local patches.- The packaged factory
.binnow lands in the.piobuild dir instead
of the project root.
Docs
- New
docs/duress-password.mdanddocs/lxmf-stamps.md, plus
docs/propagation-nodes.mdexplaining why propagation-node support
was attempted and then removed. Cross-linked from the boot sequence,
threat model, encryption overview, and UI framework docs. - Noted a one-time UX side effect for installs migrating from upstream
ratspeak/rsCardputer configs: the old boot-time timezone picker is
gone (superseded by GPS time sync), so first boot after migrating
re-runs LoRa region/frequency setup via the newRadioSetupScreen
instead of inheriting it from a timezone pick.
Full diff: https://github.com/0x00001312/rsCardputer-CE/compare/v0.0.5...v0.1.0