* NodeDB: 3-tier node store with persistent warm tier (long-tail identity retention)
Introduces a tiered NodeDB so the device retains identity (public key,
last_heard) for far more nodes than fit in the full-record hot store,
without growing heap or the persisted nodes.proto unboundedly.
- Hot store: full NodeInfoLite, MAX_NUM_NODES (120 on nRF52).
- Satellite maps: position/telemetry/environment/status capped at
MAX_SATELLITE_NODES (40 freshest); eviction via enforceSatelliteCaps /
evictSatelliteOverCap.
- Warm tier (WarmNodeStore): 40 B {num,last_heard,public_key} records for
evicted nodes so DMs to/from long-tail nodes keep encrypting/decrypting.
Persisted to /prefs/warm.dat, or on nRF52840 a dedicated 12 KB raw-flash
record-ring below LittleFS (3x4 KB pages; see linker scripts + the
nrf52_warm_region.py post-link guard).
NodeDB::getOrCreateMeshNode now demotes evicted nodes into the warm tier and
re-admits them (restoring key/last_heard). Router PKI decrypt/encode resolve
the peer key via NodeDB::copyPublicKey (hot store, then warm tier).
NodeInfoLite gains snr_q4 (sint32, Q4-encoded dB); the float snr is zeroed on
disk. NodeInfoLite grows 105 -> 112 B; backup 2432 -> 2468 B.
Note: the snr_q4 .proto change still needs to land in the protobufs submodule
(generated header is updated here; submodule pointer left at upstream).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* NodeDB: robust receive + retention for blocked (ignored) nodes
Hardens how ignored/favourite nodes are received over admin and retained,
closing paths where a block could be lost or accidentally cleared.
- Blocking keeps the node's public key (admin set_ignored_node and
addFromContact no longer zero it / drop the warm-tier key), so a blocked
peer stays a verifiable identity.
- set_ignored_node creates the node if absent, so a block by node ID sticks
even for a node we've never heard from (e.g. pushed by a remote admin) with
no NodeInfo or key.
- Eviction protection (favourite/ignored/manually-verified) now also applies to
the load-time hot-store migration and is never undone by cleanupMeshDB, which
previously purged ignored nodes that lacked user info.
- The hot-store migration leaves our own node (index 0) in place and prefers to
demote non-protected nodes, like the runtime eviction scan.
Caps the protected set (favourite + ignored + verified) at MAX_NUM_NODES-2 via
NodeDB::setProtectedFlag(), so at least two evictable slots always remain and
getOrCreateMeshNode can always make room — replacing the previous unconditional
append that could run off the end of the node vector when every node was
protected. A locally-set favourite/ignore that hits the cap reports back to the
phone via a ClientNotification.
Adds test_nodedb_blocked covering the migration, favourite/ignored eviction
protection, ignored-survives-cleanup, and the protected-node cap. The
maintenance methods stay private in production; the test reaches them through a
PIO_UNIT_TESTING-guarded friend shim.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
# Conflicts:
# src/mesh/NodeDB.h
* fix copilot comments
* once again
* WarmNodeStore: fix cppcheck warnings (uninitvar, constVariablePointer)
Zero-initialise `stranded[]` and `seqs[]/order[]` VLAs so cppcheck can
verify there are no unguarded reads of uninitialised memory (the guards
exist but are not visible to static analysis). Mark two local pointers
`const` where the pointed-to entry is never mutated after assignment.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* self-care added to assist 2.7 and 2.8 nodedb migration
* Tidy warm-store/self-care: comments, guards, log + flash cleanup
Style/cleanup pass over the branch (no behavior change except the noted
preprocessor simplifications, which are semantically identical):
- Comments: move function descriptions to the headers, cap in-function
comments at ~3-4 lines, drop leading-number step markers, label stacked
#endif blocks, de-decorate banner comments.
- dumpToLog: fully gate decl + definition + AdminModule call site behind
MESHTASTIC_NODEDB_MIGRATION_VERBOSE so it compiles out when disabled
(~1.2 KB when off).
- mesh-pb-constants: drop the dead nRF52832 WARM_NODE_COUNT branch and trim
the macro docs.
- WarmNodeStore: simplify the redundant `ARCH_NRF52 && NRF52840_XXAA` guards
to `NRF52840_XXAA`, add a kNoPage sentinel for the ring page state.
- Shorten the always-on LOG_WARN strings (~120 B flash).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* more tidying up, aligning with docs and undoing other-arch regressions
* Update protobufs (#19)
Co-authored-by: NomDeTom <116762865+NomDeTom@users.noreply.github.com>
* made the migration pathway cleareer
* address copilot review
* fixed a copilot review on a downstream PR.
* Address Copilot review comments for PR #10705 (warmstore/nodedb)
- WarmNodeStore.h: default MIGRATION_VERBOSE to 0 (suppress info-level
chatter on production builds; opt in with =1)
- WarmNodeStore.cpp load(): move memset to top of function so all
failure paths (header-read fail, invalid header) leave entries clear
- WarmNodeStore.cpp save(): replace manual spiLock lock/unlock around
mkdir with LockGuard covering the full SafeFile sequence, matching
the lock discipline in load()
- Router.cpp: memcpy(&p->public_key.bytes, ...) -> memcpy(p->public_key.bytes,
...) — pass decayed uint8_t* rather than pointer-to-array
- AdminModule.cpp: check setProtectedFlag return for PKC auto-favorite;
log cap-refusal warning instead of unconditional "auto-favoriting"
- nrf52_warm_region.py: error message references both v6.ld and v7.ld
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* NodeDB: formatting cleanup (blank lines after preprocessor blocks)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Lukewarm store
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
88 lines
3.6 KiB
INI
88 lines
3.6 KiB
INI
[nrf52840_base]
|
|
extends = nrf52_base
|
|
|
|
; Cap the app image at 0xEA000 (below the WarmNodeStore raw-flash region).
|
|
; Boards that have upgraded to S140 v7 override this in their own platformio.ini.
|
|
board_build.ldscript = src/platform/nrf52/nrf52840_s140_v6.ld
|
|
|
|
build_flags =
|
|
${nrf52_base.build_flags}
|
|
-DSERIAL_BUFFER_SIZE=4096
|
|
-DLED_BUILTIN=-1
|
|
|
|
lib_deps =
|
|
${nrf52_base.lib_deps}
|
|
${environmental_base.lib_deps}
|
|
${environmental_extra.lib_deps}
|
|
# renovate: datasource=git-refs depName=Kongduino-Adafruit_nRFCrypto packageName=https://github.com/Kongduino/Adafruit_nRFCrypto gitBranch=master
|
|
https://github.com/Kongduino/Adafruit_nRFCrypto/archive/8cde7189b5ead9dcd49f72601b43b969c0bbc06e.zip
|
|
|
|
; Common NRF52 debugging settings follow. See the Meshtastic developer docs for how to connect SWD debugging probes to your board.
|
|
|
|
; We want the initial breakpoint at setup() instead of main(). Also we want to enable semihosting at that point so instead of
|
|
debug_init_break = tbreak setup
|
|
; we just turn off the platformio tbreak and do it in .gdbinit (where we have more flexibility for scripting)
|
|
; also we use a permanent breakpoint so it gets reused each time we restart the debugging session?
|
|
; debug_init_break = tbreak main
|
|
|
|
; Note: add "monitor arm semihosting_redirect tcp 4444 all" if you want the stdout from the device to go to that port number instead
|
|
; (for use by meshtastic command line)
|
|
; monitor arm semihosting disable
|
|
; monitor debug_level 3
|
|
;
|
|
; IMPORTANT: fileio must be disabled before using port 5555 - openocd ver 0.12 has a bug where if enabled it never properly parses the special :tt name
|
|
; for stdio access.
|
|
; monitor arm semihosting_redirect tcp 5555 stdio
|
|
|
|
; Also note: it is _impossible_ to do non blocking reads on the semihost console port (an oversight when ARM specified the semihost API).
|
|
; So we'll neve be able to general purpose bi-directional communication with the device over semihosting.
|
|
debug_extra_cmds =
|
|
echo Running .gdbinit script
|
|
;monitor arm semihosting enable
|
|
;monitor arm semihosting_fileio enable
|
|
;monitor arm semihosting_redirect disable
|
|
commands 1
|
|
; echo Breakpoint at setup() has semihosting console, connect to it with "telnet localhost 5555"
|
|
; set wantSemihost = 1
|
|
set useSoftDevice = 0
|
|
end
|
|
|
|
; Only reprogram the board if the code has changed
|
|
debug_load_mode = modified
|
|
;debug_load_mode = manual
|
|
; We default to the stlink adapter because it is very cheap and works well, though others (such as jlink) are also supported.
|
|
;debug_tool = jlink
|
|
debug_tool = stlink
|
|
debug_speed = 4000
|
|
;debug_tool = custom
|
|
; debug_server =
|
|
; openocd
|
|
; -f
|
|
; /usr/local/share/openocd/scripts/interface/stlink.cfg
|
|
; -f
|
|
; /usr/local/share/openocd/scripts/target/nrf52.cfg
|
|
; $PLATFORMIO_CORE_DIR/packages/tool-openocd/openocd/scripts/interface/cmsis-dap.cfg
|
|
|
|
; Allows programming and debug via the RAK NanoDAP as the default debugger tool for the RAK4631 (it is only $10!)
|
|
; programming time is about the same as the bootloader version.
|
|
; For information on this see the meshtastic developers documentation for "Development on the NRF52"
|
|
; We manually pass in the elf file so that pyocd can reverse engineer FreeRTOS data (running threads, etc...)
|
|
;debug_server =
|
|
; pyocd
|
|
; gdbserver
|
|
; -j
|
|
; ${platformio.workspace_dir}/..
|
|
; -t
|
|
; nrf52840
|
|
; --semihosting
|
|
; --elf
|
|
; ${platformio.build_dir}/${this.__env__}/firmware.elf
|
|
|
|
; If you want to debug the semihosting support you can turn on extra logging in pyocd with
|
|
; -L
|
|
; pyocd.debug.semihost.trace=debug
|
|
|
|
; The following is not needed because it automatically tries do this
|
|
;debug_server_ready_pattern = -.*GDB server started on port \d+.*
|
|
;debug_port = localhost:3333
|