Skip to content

Companion RX-log (0x88) silently drops overheard packets larger than 173 bytes (MAX_FRAME_SIZE-3), losing long/many-hop packets #3022

Description

@MarekWo

Summary

The companion firmware's RX-log serial hook (MyMesh::logRxRaw, PUSH_CODE_LOG_RX_DATA = 0x88) silently drops any overheard packet whose raw length exceeds MAX_FRAME_SIZE - 3 (173 bytes). The radio itself receives and repeats packets up to MAX_TRANS_UNIT (255 bytes), so packets in the 174–255 byte range are handled normally on-air but never reach a host application over the serial/BLE companion link. There is no truncation and no error frame — the packet just never appears in the RX log.

Where

examples/companion_radio/MyMesh.cpp:

void MyMesh::logRxRaw(float snr, float rssi, const uint8_t raw[], int len) {
  if (_serial->isConnected() && len + 3 <= MAX_FRAME_SIZE) {   // <-- 3-byte header: code + snr + rssi
    int i = 0;
    out_frame[i++] = PUSH_CODE_LOG_RX_DATA;
    out_frame[i++] = (int8_t)(snr * 4);
    out_frame[i++] = (int8_t)(rssi);
    memcpy(&out_frame[i], raw, len);
    i += len;
    _serial->writeFrame(out_frame, i);
  }
  // else: packet silently discarded
}

Relevant constants (src/MeshCore.h, src/helpers/BaseSerialInterface.h):

Constant Value Meaning
MAX_TRANS_UNIT 255 max on-air packet the radio receives/repeats
MAX_PACKET_PAYLOAD 184 max packet payload
MAX_PATH_SIZE 64 max accumulated path bytes
MAX_FRAME_SIZE 176 companion serial frame size

So the RX-log frame can carry a raw packet of at most 176 - 3 = 173 bytes, well below the 255-byte packet the node otherwise processes.

Why it bites in practice

A packet's path grows as it floods through the mesh — every repeater appends its hash (1–3 bytes per hop depending on path_hash_mode, up to MAX_PATH_SIZE = 64). A group/channel text message that fits comfortably when first transmitted can therefore cross the 173-byte threshold after enough hops, at which point every downstream node that overhears it stops reporting it in the RX log even though it still receives and repeats it.

Concretely, for a GRP_TXT packet the raw length is 6 (header + transport codes + path_len) + path_len + pkt_payload. With a ~160–180 byte payload (long bot/status messages are common on busy channels) the packet exceeds 173 bytes after only a handful of hops, and beyond ~10–17 hops it is essentially never logged.

Impact

Any host-side tooling that relies on the RX log (e.g. packet observers, MQTT bridges, routing/path analyzers) sees a systematic blind spot: exactly the long, many-hop packets — the most interesting ones for route analysis — are the ones missing. This looks like "some messages have no path/echo information" to the user, with no indication anything was dropped.

Observed downstream in a companion host app (mc-webui): long channel messages relayed over 8–17 hops consistently produce zero RX-log echoes, while short messages on the same channel are logged normally. Reconstructing the packet host-side confirms the packet hash matches — the packet was real and on-air — but the firmware never emitted a 0x88 frame for it.

Suggested fixes (any one)

  1. Truncate instead of drop — forward the first MAX_FRAME_SIZE - 3 bytes and signal truncation (e.g. a flag byte or a length field), so hosts at least see the header + path even if the tail of the payload is clipped. For path/route analysis the header and path bytes are what matter most, and those live at the front of the packet.
  2. Raise MAX_FRAME_SIZE for the companion link to accommodate MAX_TRANS_UNIT + header (i.e. ≥ 258), so any legitimately-received packet can always be forwarded. This is the cleanest fix if serial/BLE buffer sizes allow it.
  3. At minimum, document the limitation and/or emit a lightweight "packet too large for RX log (len=N)" notice so hosts can surface it rather than silently losing data.

Happy to test a patch on ESP32 (WiFi companion) hardware.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions