fix: restore 'repeats heard' on scoped floods + guard trace-route crash

- MyMesh.cpp logRxRaw: the self-echo parser tested (raw[0] & 0x80) for transport
  codes, but 0x80 is the top of the payload VERSION field, not a flag. Transport
  codes are present iff route_type (raw[0]&0x03) is TRANSPORT_FLOOD/DIRECT. Since
  beta_12's region scope, scoped floods carry transport codes -> the parser hashed
  the wrong payload slice -> the echo never matched -> 'repeats heard' showed 0 for
  anyone with a region set. Now route-type aware (matches uiStashRxMeta). Also fixed
  the diagnostic dst= decoder + the header-layout comment.
- MyMesh.h uiSendTraceRoute: walking c.out_path with an unchecked out_path_len
  (uint8_t, can be 65..254 if a contact's path is corrupt) overran sendDirect's
  payload memcpy -> reboot when tapping 'Trace route' on a sent DM. Clamp to
  <= MAX_PATH_SIZE, else fall back to the single-hop trace.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kaj Schittecat
2026-06-13 22:11:17 +02:00
co-authored by Claude Opus 4.8
parent 9e2eed1551
commit ec3b47bbc2
2 changed files with 12 additions and 6 deletions
+9 -4
View File
@@ -1359,8 +1359,10 @@ void MyMesh::logRxRaw(float snr, float rssi, const uint8_t raw[], int len) {
#if defined(DISPLAY_CLASS)
// Diagnostic: log EVERY received frame so we can prove what reaches the
// radio. Header byte layout is
// [hasXportCodes:1][reserved:1][payload_type:4][route_type:2]
// so payload_type = (raw[0]>>2)&0x0F and route_type = raw[0]&0x03.
// [version:2][payload_type:4][route_type:2] (bits 7..0)
// so payload_type = (raw[0]>>2)&0x0F and route_type = raw[0]&0x03. The 4
// transport-code bytes follow the header iff route_type is a TRANSPORT_* one
// (there is NO "hasXportCodes" bit at 0x80 — that's the top of the version field).
if (_ui && len > 0) {
const uint8_t ptype = (raw[0] >> 2) & 0x0F;
const uint8_t route = raw[0] & 0x03;
@@ -1390,7 +1392,8 @@ void MyMesh::logRxRaw(float snr, float rssi, const uint8_t raw[], int len) {
// Header is byte 0; transport codes (if present) are 1-4; path_len is
// next; then path bytes; then payload. We just want the first byte of
// the payload as dest_hash for TXT/RSP/ACK style packets.
const bool has_xport = (raw[0] & 0x80) != 0;
const uint8_t rt0 = raw[0] & 0x03;
const bool has_xport = (rt0 == ROUTE_TYPE_TRANSPORT_FLOOD || rt0 == ROUTE_TYPE_TRANSPORT_DIRECT);
int payload_start = 1 + (has_xport ? 4 : 0);
if (payload_start < len) {
uint8_t path_byte = raw[payload_start];
@@ -1421,7 +1424,9 @@ void MyMesh::logRxRaw(float snr, float rssi, const uint8_t raw[], int len) {
// and bump the matching sent message's count. The fp ring only holds our own
// recent sends, so other nodes' traffic can't false-match.
if (len > 0 && isMsgFloodType((raw[0] >> 2) & 0x0F)) {
const bool has_xp = (raw[0] & 0x80) != 0;
const uint8_t rt = raw[0] & 0x03; // route_type (PH_ROUTE_MASK)
const bool has_xp = (rt == ROUTE_TYPE_TRANSPORT_FLOOD || // 4 transport-code bytes follow the
rt == ROUTE_TYPE_TRANSPORT_DIRECT); // header iff route is a TRANSPORT_* one
const int ps = 1 + (has_xp ? 4 : 0);
if (ps < len) {
const uint8_t pb = raw[ps];