Skip to content

Show per-message routing info (hop count, multi-path, named repeaters) - #66

Closed
MrSurly wants to merge 4 commits into
tmacinc:devfrom
MrSurly:issue-65-message-routing-info
Closed

Show per-message routing info (hop count, multi-path, named repeaters)#66
MrSurly wants to merge 4 commits into
tmacinc:devfrom
MrSurly:issue-65-message-routing-info

Conversation

@MrSurly

@MrSurly MrSurly commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #65.

Firmware already sends per-message hop count/SNR (in the V3 message-receive responses) and, separately, full per-packet routing data (real per-hop path bytes, RSSI, SNR) in a raw PUSH_LOG_RX_DATA frame -- both were previously parsed and then discarded by this app entirely.

What's new

  • Chat bubbles show a hop-count badge next to the sender: (d) for direct, (N) for N relay hops, and (d/1)-style when a message was heard via multiple paths at once (e.g. both directly and via a relay).
  • Long-press/right-click a received message -> "Message path" opens a detail sheet showing a sender -> hop(s) -> you timeline. When richer data is available, each hop shows the resolved contact name (or the raw hex identifier if unknown, or all candidates if a short hash prefix is ambiguous between multiple known contacts), plus real SNR/RSSI per path.
  • Messages/MessagePaths schema: per-message hopCount/snr on Messages, and a new MessagePaths table (one row per distinct radio path a message was observed on).

How the richer data is obtained

The raw PUSH_LOG_RX_DATA frame has no ID linking it to the specific decoded message it belongs to -- a single push can precede a sync that returns several queued messages. To correlate them safely: since the app already knows a channel message's exact plaintext (firmware decoded it) and that channel's PSK, it re-encrypts the known plaintext (AES-128-ECB, matching firmware's Utils::encrypt) and looks for an exact ciphertext match against buffered raw frames -- unambiguous, no heuristics. Once matched, every other buffered frame sharing that packet's hash (payload type + ciphertext, independent of path) is a multi-path sibling of the same logical message.

This is channel-messages-only for now -- direct messages use different (asymmetric) crypto not yet implemented here, so DM bubbles/sheets still use the reliable single-value hopCount/snr summary firmware already provides, same as before this PR.

Verified end-to-end against live traffic, including a real multi-path case (a message heard both directly and via a specific named repeater).

MrSurly added 3 commits July 18, 2026 16:46
Persists path length and SNR from the existing V3 message-receive
responses (previously parsed then discarded) onto each Messages row.
Adds a (d)/(N) badge next to the sender name and a long-press
"Message path" sheet showing a simple sender -> hop count -> you
timeline.

Named per-hop routing and multi-path duplicate detection (richer
data from the raw PUSH_LOG_RX_DATA frame) are deferred -- correlating
that frame to a specific decoded message isn't safe with the current
sync loop, which can drain multiple queued messages per push.
Adds a message_paths table (one row per distinct radio path a channel
message was observed on) populated by correlating raw PUSH_LOG_RX_DATA
frames -- previously received but entirely discarded -- against
already-decoded channel messages.

Correlation works by re-encrypting a message's known plaintext (using
its channel's PSK) and finding an exact ciphertext match against
buffered raw frames, brute-forcing the 4 possible `attempt` retry
values since firmware's decoded response doesn't expose that field.
An exact match is unambiguous; no heuristics. Frames sharing the
matched packet's hash (payload type + ciphertext, independent of
path) are its multi-path siblings -- the same logical packet heard
via another route (e.g. direct and relayed at once).

Verified end-to-end against live traffic: correctly captured both a
direct reception and a relayed one (via a specific repeater hop) for
the same message, with real per-hop SNR/RSSI. A DB-level unique
constraint on (messageId, pathBytes) makes duplicate-delivery
correlation (the same message arriving via push then sync, an
existing pattern elsewhere in this file) safe without an
application-side race.

Also adds getContactsByPublicKeyPrefix (all-matches variant, for
later ambiguity display) alongside the existing first-match lookup.

UI display of this data is a follow-up; the badge/sheet from the
prior commit still uses the single-path Messages.hopCount/snr
summary and is unaffected if correlation never matches.
Wires the correlated MessagePaths data (from the previous commit)
into the chat UI:

- Message path sheet shows every distinct path a message was
  received on -- each with real SNR/RSSI and named hop(s) resolved
  against known contacts, falling back to the raw hex identifier
  when a hop isn't a known contact and to the message-level
  hopCount/snr summary when no raw-frame correlation exists at all
  (DMs, or a channel message that never matched).
- Ambiguous hops (a short hash prefix matching more than one known
  contact) show all candidates and are visually flagged.
- Chat bubbles now show a MessageHopBadge: the reliable single-value
  (d)/(N) summary immediately, swapping to a real multi-path summary
  like (d/1) once correlation data loads for that message -- this
  was the actual point of the whole effort, not just the detail
  sheet.
- getContactsByPublicKeyPrefix (all-matches) and
  MessageRepository.getMessagePaths added as plumbing.
@MrSurly
MrSurly marked this pull request as draft July 19, 2026 03:09
The sheet's content wasn't scrollable, so a path with several hops
(e.g. 8) overflowed the bottom of the screen. Caps the sheet at 80%
of screen height and wraps content in a scrollable view with a
visible scrollbar.
@MrSurly

MrSurly commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #73, which builds on this branch and rolls in #71 as well.

@MrSurly MrSurly closed this Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Show routing/hop info on messages

1 participant