What Has Changed
1. Store-and-Forward (S&F) for Direct Messages
Files: src/msgstore.cpp, src/msgstore_api.h, src/msgstore_glue.cpp, src/msgstore_settings.{h,cpp},
src/sto_notice.{h,cpp}, src/dm_dedup.{h,cpp}, src/reack_limiter.{h,cpp}, src/dm_stats.{h,cpp}, checkbox in
src/lora_functions.cpp and src/loop_functions.cpp, website /?page=mailbox.
- Problem: A direct message (DM) sent to a station that is currently unreachable gets lost.
- Sender side unchanged from upstream:
MAX_RETRANSMIT3 at 40-second intervals, or 4 transmissions in approximately
2 minutes, newmsg_idper copy (pnRetryId) with stable{NNN. The only new item is an acknowledgment code of 0x03
"Failed" when submitting to the app and additional counters (ack=,rtt=,att=). - Recipient: Duplicate DMs are discarded (deduplication based on source and NNN), but acknowledged again (Re-ACK, limited by
reack_limiter), so that a lost ACK does not trigger an infinite loop. - Mailbox node (Store Node): stores a DM that it cannot deliver to its destination (no hop check during storage).
As soon as it hears the destination directly again (path without a comma), it returns a 9-level ladder at
max_hop 0From: Broadcasts at 0/40/80/180/220/260/360/400/440 seconds (total of 7 minutes 20 seconds), followed by a 1-hour break after each
Entry. Each shipment has a newmsg_id(millis()),{NNNremains. Random delay of 5–60 seconds; if he hears a
If a different node is selected for the same (source, NNN), the transmission is aborted; an ACK terminates the sequence. The
The mailbox is stored only in RAM; a reboot will discard it. - Limitations: One action every 30 seconds at most; a maximum of 20 actions per hour and per node; no delivery during QRS/QRT
or when channel utilization exceeds 25% (5 min). Payload up to 160 bytes. - Response to the sender: Status 0x04 (held, holder attached) and, optionally, the text
:stoNNN <Ziel>
(rate-limited,--storenotice, "Standard" selected). - Modi (
--store):off(Default) |own(Destinations with the same base call sign as the node) |list
(Call sign from--storecall, max. 16) |heard(Target heard in the last 12 hours). - Hardware: Boards with
ENABLE_MSGSTORE(all ESP32-S3 environments, RAK4631, T114, T-Echo). Not otherwise integrated. - Persistence: separate sentence (NVS on ESP32,
/msgstore.cfgin LittleFS on nRF52), not ins_meshcom_settings.
2. Neighborhood Matrix (NBR)
Files: src/nbr_matrix.{h,cpp}, src/nbr_mask.h, src/nbr_views.{h,cpp}, src/topo_ui.{h,cpp}, connection to
src/lora_functions.cpp and src/txring_functions.cpp, Ad /?page=neighbours, Command --neighbours.
- Calculates a local two-hop matrix "Station Y hears Station X" from the path fields of received frames (12-hour window)
and HEY signal reports. The matrix itself is not transmitted. - For each frame to be relayed (source, NNN): Demand(F) = direct neighbors who do not yet have the frame; Solo(F) =
neighbors that only I can reach. Case A (Solo not empty): I relay with priority, never abort. Case B:
others provide coverage; I relay with backoff and abort as soon as the coverage is heard (coverage-based, not
counter-based). The abort check now re-scans the TX ring below the ring lock before releasing a slot
. - Text frames (
:) and, consequently, frames fed in by the server also feed only their own step (ME), not any
Path edges; this prevents phantom neighbors from occurring. - No new broadcast format for the decision: Older firmware continues to flood in as before. Optional HN report
(--nbrreport, Defaultauto): one HEY frame to "HN" every 15 minutes atmax_hop 0; Stock firmware rejects it because
"HN" fails the call sign test. - Memory: ESP32-S3 and nRF52840, 128 lines / 512 edges,
NbrMatrix13,992 B, TX-ring masks 660 B; classic
ESP32 64 lines / 256 edges, 5,592 B, 340 B. - Switches are located in
node_sset40x0100–0x2000, which is outside the KISS/TCP bits 0x0010–0x0080.
3. MHeard and path table replaced by NBR (noticeable change in behavior)
src/mheard_functions.{cpp,h} and src/mheard_throttle.h omitted, src/mh_phone.{h,cpp} is the succession.
--mheard(serial): rows instead of the ASCII table[MH] key=value, newest first; "pl/mesh" and numeric columns
HW-ID is omitted.--path, Web Path page, T-Deck Path tab: display the number of hops and neighbors from the matrix instead of the complete
Relay path string.- Web-MHeard page: SNR as an 8-frame average, different labels, additional fields.
- BLE-MHeard frames for the app: newest first, at most one live frame per station per minute, seven new keys
(AGE HM ROLE EX NB GW VIA) appended at the end; the old 13 keys and their order remain unchanged. For direct
stations without a detail slot (more than 64 / 48 direct neighbors on S3, RAK / classic ESP32), RSSI, SNR,
PLT, MOD, PL, and MESH are missing from the frame instead of placeholder values; DIST always remains numeric. The stock app tolerates
unknown keys and missing values (verified against the app source code). - On the air, the value—not the format—of the adjacent number in HEY changes
R<n>, Position/Nand the HEY Signal Report:
beforegetMheardCount()(all stations heard in 60 minutes), nowNCNT(neighbors on both sides, at most 99,
less than or equal to the old value). The server and map therefore consistently display smaller numbers for new nodes. - Persistence:
/mheard.datand/mhpath.datare deleted the first time the program is launched (the history is lost once),
Logging interval 30 s → 10 min; T-Deck Pro rewrites/topo.datto the SD card. - Capacity with full detail line: S3/RAK 80 -> 64, standard ESP32 30 -> 48.
4. New serial/USB commands (19)
Default values in the "Std." column. Only --nbrdebug, --nbrrelay, --nbrsym, --nbrreport are rows in the table
COMMAND_TOGGLES (src/command_functions.cpp, 80 lines total, types in src/command_toggles.h); all others
are handwritten steps in the chain of command.
| Command | Arguments | Hrs. | Effect | Save | Restriction |
|---|---|---|---|---|---|
--neighbours |
– | – | Display Neighbor Matrix (Short Form) --nbr) |
no | |
--nbrreset |
– | – | Clear Matrix | no | |
--nbrcheck |
– | – | Consistency Check of the Matrix | no | |
--nbrdebug |
on/off | off | Debug output of all NBR decisions | yes | |
--nbrrelay |
off/count/on | off | Relay Decision: Off / Log Only / Abort Actively | yes | |
--nbrsym |
on/off | on | Assumption of symmetry (SNR >= -16 dB) when no direct observation is available | yes | |
--nbrreport |
off/auto/on | car | HN Neighborhood Report (auto: only if the mesh and gateway are off) |
yes | |
--store |
off/own/list/heard | off | Mailbox mode; if no value is specified: Status | yes | ENABLE_MSGSTORE |
--storecall |
List/none | empty | Call Sign for Mode list (max. 16) |
yes | ENABLE_MSGSTORE |
--storeslots |
1–50 | 50 | Mailbox Spaces | yes | ENABLE_MSGSTORE |
--storetime |
1-168 | 24 | Holding time in hours | yes | ENABLE_MSGSTORE |
--storenotice |
on/off | on | :sto-Note to the sender |
yes | ENABLE_MSGSTORE |
--mbox |
– | – | View Mailbox Contents | no | ENABLE_MSGSTORE |
--msgid |
– | – | Show message counter | no | |
--airgap |
on/off/show | off | Test Stand: Discard Reception, Deny Transmission | no | |
--battprobe |
[n] 1–10 | 1 | Battery ADC measurement (approx. 7.5 s per cycle) | no | INSTRUMENT_ENABLED, Heltec with a connected divider |
--dumpsettings |
– | – | Raw dump of the settings | no | only nRF52 |
--keylock |
on/off | off | Key Lock (SYM+K) | yes | T-Deck, T-Deck Plus |
--ethmtu |
1280–1500 | 1500 | Ethernet MTU (if less than 1500, it limits the web server's TCP MSS) | yes | RAK4631 |
Additional changes: --help is organized into groups and led by the respective handlers; some of the
Commands still do not have a help text. Exact tokens instead of prefix matches in the toggle table. The following was removed:
commented-out code for the test commands --compress and --softser test|test0|xml.
5. Structural Changes
s_meshcom_settingshas a single definition insrc/meshcom_settings.h; Schema and Flash paths in
src/settings_schema.*,src/settings_store.*(ESP32: NVS with unchanged key names, nRF52: file).
The value ranges of the schema are the upper bounds of the setters (including, among others,node_postimeup to 86,400 s,node_altuntil
40000,node_gpsdebugup to 3,--postime(now limited to one day).- Counter (
node_msgid(among other things) broken down intosrc/counters_store.h;finalizeAndSendAPRS()Replaces the individual copies
the end of the broadcast;save_msgid()Not applicable. - BLE: Phone Frame Parsing and Drain In
src/ble_phone_*.h; UDP/Gateway insrc/udp_frame*,src/gateway_service*. - Database/Utility Modules:
src/country_profile.*,src/radio_units.*,src/loop_scheduler.*,src/uptime_min.h,
src/batt_pipeline.h,src/ui_common/*.
6. Build Changes (visible to the reviewer)
- RAK4631 is building with
-Osinstead of-Ofast(variants/wiscore_rak4631/platformio.ini,build_unflags = -Ofast,-Os):
Flash 96.1% -> approx. 70%, RAM unchanged; stops there-ffast-math, so that it worksisnan()-Exams in
upstream code (e.g.,bmx280.cpp,onewire_functions.cpp) again. T114 and T-Echo remain at-Ofast. - Classic T-Beam environments: PSRAM build flags removed. E22_XML: KISS/TCP recompiled,
MC_CAPTURE=0->
MC_DIAG=0,tinyxml2as an embedded copy atlib/tinyxml2. t5_epaperis now building (newconfiguration.h, bq27220 sources,lib_deps); T-Deck-Pro-LVGL storage in PSRAM.- New Basic Sections
[esp32_s3]/[esp32_classic]with a sharedupload_commandabout$BUILD_DIR
(Addresses, files, and--port(unchanged). - New Battery Pipeline for All Boards (
src/batt_pipeline.h, different sampling).OneWire_GPIO99 -> -1 with 8 boards. settings_schema.cppis in the Safeboot environments in the source filter (the Flash paths follow this scheme).default_envs, partition tables, and-Werrorremain unchanged; the workflow filemeshcom-ci.ymldoesn't need any
Change (same environments, same artifact paths).safeboot.binandsafeboot-s3.binwere newly built from this site (inputsesp32_flash.*and
settings_schema.cpphave changed).
7. Removed
- 43 unused Adafruit GFX fonts at
src/Fonts/, 11 AVR/SAMD/ESP8266 files atsrc/Platforms/,
src/nrf52/glcdfont.c(Duplicate),src/t-deck-pro/ui_scr_mrg.c(replaced bysrc/ui_common/scr_mgr.c),
src/idf_component.yml.orig.
Fixes
Only errors that occur in upstream/dev 1d4f525 are still available.
- BLE-N1/N2/N3 (nRF52): A rejected Notify caused the frame to be lost (the upstream discards the frame regardless of the
Send result); now returnBLE_SEND_*and repetition. - BLE-N4: A phone with an incorrect PIN checksum is immediately disconnected (the upstream device checks only in the Rx callback).
- nRF52: Writing the settings via BLE copied the entire phone image, including obsolete
node_msgid
about the current settings; the counter went down. - P13: A Pong message sent to the device's own call sign reaches the BLE client.
- P14:
{ping}was made fromsendMessage()Sent repeatedly; now just once. - P15: Messages sent by the device itself, without being repeated, retain their TX-Ring priority (the upstream treats them as relays).
- Feature Request / Bug: Heltec Wireless Tracker – Screen backlight does not turn off via the Android app's "Display OFF" command (TFT\_BL GPIO 21)#1182: T-Tracker: TFT backlight does not respond to “Display Off.”
- Web server does not work from another subnet – RAK with LAN#1183 (opt-in): The W5100S (RAK4631) does not limit the TCP MSS;
--ethmtuShe sets it to less than 1,500 for the web server.
Standard 1500 leaves the behavior unchanged. - Corrupted special/diacritical characters when sending messages via Web Service#1173 (Rest): The message counter in the web interface counts UTF-8 bytes.
- Web: Removed broken buttons from the info page (the buttons are now protected against features that haven't been implemented).