Files
meshcore-spec/versions/v0.1.0/10-payload-trace.md
T
swaitsandClaude Opus 4.7 44305a06db release: v0.1.0
First cut release. Snapshots ./src/ as ./versions/v0.1.0/ via
`just cut-version v0.1.0` (22 files: 21 chapter MDs + SUMMARY.md).
Deployed alongside `latest` at:

  https://swaits.github.io/meshcore-spec/v0.1.0/

Also:

- CHANGELOG.md adopts Keep a Changelog-style version sections.
  Future entries land under [Unreleased] and graduate to a version
  heading when cut. The existing date-stamped pass entries stay
  put as a historical record of the work captured in v0.1.0.
- README.md fixes a stale "per vX.Y.Z tag" mention left over from
  the tag-based versioning model, and links the current release
  explicitly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 10:04:40 -06:00

3.7 KiB
Raw Blame History

MeshCore Protocol Specification

Section 10: Payload — Trace

Overview

The TRACE payload enables path discovery with per-hop signal quality measurement. A trace packet travels along a specified direct path, and each intermediate node appends its received SNR value to the packet's path field. When the trace reaches its final hop, the accumulated SNR values and node hashes are delivered.

Payload Type

Header payload type field: 0x09 (TRACE)

Wire Format

The trace payload has a fixed 9-byte header followed by an optional path hashes section (appended when sent via direct routing):

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Tag (uint32_le)                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     Auth Code (uint32_le)                     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Flags     |          Path Hashes (variable)               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Fields

Field Offset Size Type Description
tag 0 4 bytes uint32_le Random tag set by the initiator for correlation
auth_code 4 4 bytes uint32_le Authentication code
flags 8 1 byte uint8 Flags (see below)
path_hashes 9 variable raw Node hashes for the path to trace (appended for direct send)

Flags Field

  Bit:  7   6   5   4   3   2   1   0
      +---+---+---+---+---+---+---+---+
      |      Reserved         | S1  S0|
      +---+---+---+---+---+---+---+---+
Bits Description
0-1 Path hash size for the trace path hashes (as a power of 2: 0=1 byte, 1=2 bytes, 2=4 bytes)
2-7 Reserved (must be zero)

Note: The flags field path hash size encoding (1 << (flags & 0x03)) differs from the packet path_len encoding ((code >> 6) + 1).

Direct Sending

When a TRACE packet is sent via direct routing, the path hashes are appended directly to the payload (after the 9-byte header), not placed in the packet's path field. The packet's path field is instead used to accumulate SNR values from intermediate nodes.

On creation:  payload = [tag(4)][auth_code(4)][flags(1)]  (9 bytes)
On sendDirect: payload += path_hashes                      (9 + N bytes)
               packet.path_len = 0                         (path used for SNR)

SNR Accumulation

As each intermediate node forwards a TRACE packet, it appends its received SNR value as a single signed byte to the packet's path field:

path[path_len++] = (int8_t)(SNR × 4)

The SNR value is stored as SNR × 4 for 0.25 dB precision, matching the format used in RxMeta frames.

Trace Completion

A TRACE is considered complete when the path_len counter (used as an offset into the path hashes in the payload) reaches or exceeds the remaining path hashes. At that point, onTraceRecv is called with:

  • The accumulated SNR values (in packet.path)
  • The path hashes (in packet.payload, after byte 9)
  • The path length (number of hops traversed)

Minimum Size

  • Minimum payload: 9 bytes (tag + auth_code + flags, no path hashes)

Cross-References

Reference Implementation

  • Mesh::createTrace() in src/Mesh.cpp — Creation (9-byte base)
  • Mesh::sendDirect() — Path appended to payload for TRACE type
  • Mesh::onRecvPacket(), TRACE handling — SNR accumulation and completion check