Adopts hardware Channel Activity Detection (wired into
RadioLibWrapper::isChannelActive() alongside our RSSI-threshold check
and RX duty-cycle power-save), MCU temperature telemetry, LR2021
standby workaround, DISPLAY_SCALE/FLIP overrides, NRF52Board
shutdownPeripherals() refactor, and misc upstream fixes.
Declines upstream's ConfigSerializer-based NodePrefs rewrite,
MultiSerialInterface/interface_manager, and UIColor palette system —
each would have broken large parts of the Solo-specific feature set
(NodePrefs fields, per-variant single serial_interface, enum-based
DisplayDriver::Color). Flagged as candidate follow-up migrations, not
permanent no's.
Also fixes several pre-existing bugs surfaced while chasing silent
merge breaks (stale newMsg() override signature in ui-tiny/ui-orig,
dead UIEventType::newContactMessage case, missing ContactsIterator
init), bumps FIRMWARE_VERSION/MESHCORE_VERSION to 1.17, and fixes a
missing <cstdlib> include that broke the native ConfigSerializer unit
tests.
Verified via 13+ pio run builds across ESP32/nRF52, all 3 companion UI
variants, and 7 display drivers, plus the full native unit test suite
(33/33 passing).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Three power-saving additions, prompted by comparing this fork's existing
RX duty-cycle support against IoTThinks/EasySkyMesh:
- RX duty-cycle watchdog: the SX126x's hardware RX<->sleep sequencer runs
with no MCU polling, so a desync (a known failure mode) previously had
nothing watching for it. A new watchdog samples the BUSY pin every tick;
no transition for too long triggers a soft re-arm, then a full chip
reset (with cached radio params reapplied, since std_init() resets to
compiled firmware defaults) if that doesn't clear it. Soft/hard recovery
counts surface on Tools > Diagnostics > Live as "RXPS wd s/h".
- Noise-floor recalibration during power-save: sampling was previously
skipped entirely while duty-cycling, freezing int.thresh interference
detection at whatever the floor was when power-save turned on. Now
borrows a brief continuous-RX window once a minute to take a fresh
reading before re-arming duty-cycle.
- GPS duty-cycling (Settings > System > "GPS pwr"): cycles GPS off between
fixes instead of running it continuously. Each wake waits for a fix
(capped at 60s) before sleeping again for the configured interval.
Repurposes the long-dead NodePrefs::gps_interval byte rather than adding
a new persisted field. A "is anything live using GPS right now" hold in
UITask keeps GPS continuously on whenever trail recording, live-share,
an armed Locator, or the Compass/Nearby-navigate view actually need a
live fix, so none of those features degrade. Locator crossing-state is
reset on each wake so a still-settling first fix can't read as a false
geofence crossing.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
After soaking for a bit on the adverts without issue on multiple nodes,
I added more hardware crypto.
Supported nodes is unchanged in this PR addition, but if others can verify,
they can easily be added.
Some info on the CC310: https://docs.nordicsemi.com/r/bundle/ps_nrf9151/page/cryptocell.html
**Added:**
- AES-128 packet encryption/decryption now use hardware crypto
- HMAC-SHA-256 authentication now uses hardware crypto
- ACK hash computation and channel ID derivation now use hardware crypto
- RNG (random number generator) now uses hardware crypto rather than
radio noise + weak software RNG (which can have issues if there's
no surrounding radio noise.) NIST SP 800-90B certified.
- Runs hardware self-tests on startup
- Runs continuous health tests during operation
- Uses thermal noise/shot noise for randomness
**Unchanged:**
- calcSharedSecret remains software - it would be a split hw/sw solution
and added complexity for likely not a lot of gains. This only happens
when establishing a new contact, so not too frequent to be worth it.
- ed25519_create_keypair remains software. This is only called when a
node is first initialized. It does use the hardware RNG change, however,
so better randomization.
Tested on (so far):
- Heltec t096
Build test on:
- Heltec t096 companion ble
- t1000e companion ble
- RAK 4631 repeater
- RAK 3401 companion BLE
- Heltec v3 companion wifi
Settings > Radio gains a repeater toggle, 16 community-suggested radio
presets plus manual Freq/SF/BW/CR tuning (digit-by-digit Freq editor),
4 persisted user preset slots, and the packet pool bumped 16->32 so
queued retransmits stop starving incoming-packet allocation while
relaying.
Four opt-in politeness knobs (skip-advert, max-hops, yield, min-SNR),
all flood-only and off by default, plus overhear suppression that
cancels a queued retransmit if a peer relays the same packet first.
Adaptive Power Control is suppressed while relaying (pins TX power to
the ceiling) and duty-cycle RX is forced off, since a repeater needs
to hear and relay at consistent power.
A dedicated Tools > Repeater screen consolidates the toggle, the
politeness knobs, and live forwarding stats, plus an optional "Custom"
radio profile — a dedicated frequency/SF/BW/CR for relaying, separate
from the companion's own network, band-matched to the companion
frequency by default and used everywhere a radio change can happen
(boot, on-device toggle, app-driven CMD_SET_RADIO_PARAMS, Settings
radio edits) so the device never silently falls back to the wrong
params mid-relay.
Diagnostics gains the actually-forwarded packet count, real heap-free
via mallinfo(), a reset-counters popup, and hardened loop-detect
bounds. Also: a frequency-floor fix and a float-equality preset-match
fix in the repeater profile logic, deduped BW-table/valCol/profile-
seeding helpers shared between Settings and the Repeater screen, and
a build.sh fix tolerating control characters in `pio project config`'s
JSON dump.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two independent, default-off toggles under Settings › Radio.
Pwr save: hardware RX duty-cycle (SX126x SetRxDutyCycle via
startReceiveDutyCycleAuto). The chip cycles RX↔sleep and wakes on a preamble —
no MCU state machine; recvRaw reads the packet exactly as in continuous RX.
Falls back to continuous RX on non-SX126x. (Replaces an earlier software-CAD
state machine that fought the hardware: polling a warm-sleeping chip gave a
phantom-busy channel that stalled TX ~4 s and dropped ACKs in the scan gaps.)
Auto pwr: Adaptive Power Control. tx_power_dbm becomes a ceiling; actual TX
power tracks the reverse-link SNR margin (measured above the per-SF demod floor,
EWMA-smoothed, proportional step with a deadband). Feedback comes from direct /
room-server ACKs and, for channels (no ACK), from hearing a repeater rebroadcast
our own flood; a lost confirmation ramps power back up so channel sends can't get
stranded below what the repeaters can hear.
Prefs schema 0xC0DE0009 (rx_powersave, tx_apc). Radio page / name bar show the
live TX power; noise floor reads n/a while duty-cycling.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1. warm sleep
2. wake to stdby
3. Calibrate(0x7F) to reset all internal blocks
4. re-apply DIO2 RF / boosted gain & register patch to make sure
everything is as it was
This change counts when readData returns an err code other than RADIOLIB_ERR_NONE. In most cases this is going to be a CRC error. This counter is exposed in the `stats-packets` command, and in the repeater stats payload (4 additional bytes to the payload, which is now 56 bytes with this change. My incompetent robot claims the total payload size is 96 bytes (unverified but probably close).
This should significantly reduce power consumption in hibernation.
Fixes: #1014
Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
Signed-off-by: Frieder Schrempf <frieder@fris.de> # generalize for all radios and UIs