Skip to content

Feature: Repeated sending for DIRECT-route packets with echo-cancellation (improves delivery, reduces floods)#2670

Open
usrflo wants to merge 8 commits into
meshcore-dev:devfrom
usrflo:feature/repeated-sending-2
Open

Feature: Repeated sending for DIRECT-route packets with echo-cancellation (improves delivery, reduces floods)#2670
usrflo wants to merge 8 commits into
meshcore-dev:devfrom
usrflo:feature/repeated-sending-2

Conversation

@usrflo

@usrflo usrflo commented Jun 2, 2026

Copy link
Copy Markdown

Relates to #1342.

Motivation

Direct messages over multi-hop paths fail silently when a single hop misses a packet due to temporary radio interference or channel congestion. The sending node then falls back to a flood — which is both unreliable under load and consumes significant airtime. In my tests most incoming paths with a length of 3 hops couldn't be reused in back traces: a far too low number that should be increased by an error correction.

What this PR does

This branch adds conditional repeated sending for DIRECT-route packets at the repeater level:

  • After forwarding a DIRECT packet, a repeater schedules up to max_resend_attempts re-transmissions (default: 2, configurable 0–3 via set max.resend).
  • Each pending retransmit is cancelled immediately when the repeater overhears the downstream relay successfully forwarding the same packet (echo-detection via hash comparison in the outbound queue).
  • The RX loop was changed to drain all pending packets per loop() call, minimising the race window between echo detection and retransmit timer expiry.
  • ACK packets use a dedicated deduplication table (_acks[] in SimpleMeshTables) to keep deduplication cheap (4-byte compare, no SHA-256) and to prevent ACK entries from evicting long-lived flood-packet hashes.

Comparison with PR #2367 (HALO)

This implementation shares the same goal as #2367 — improve direct-path reliability — but uses a different strategy. Both branches were applied to mcsim (including fixes to make the simulator timing-accurate for retransmit scenarios, see simulator commits) and run against the same standardised test scenario.

Test topology: 3 repeaters between Alice and Bob, all links of marginal/bad quality
Test: 10 random seeds × 20 DMs each = 200 deliveries total

Branch Avg delivered Avg TX (direct) Avg collisions
halo-direct-path-retries (#2367) ~15.9 / 20 ~420 ~15
repeated-sending-2 (this PR) ~19.4 / 20 ~187 ~3

Key advantages of this approach:

  • Higher delivery rate (~97 % vs ~80 % in the test scenario)
  • 55 % fewer TX packets — echo-cancellation prevents unnecessary retransmits before they fire
  • ~80 % fewer collisions — significantly less channel saturation
  • Simpler and more resource-efficient — no SNR-gated retry logic, no neighbor-table lookup; just overhear and cancel

Delivery rate vs. resend attempts (mcsim, retry_showcase topology)

max_resend_attempts Delivery rate
0 (stock MeshCore) 71 %
1 91 %
2 (default) 95.5 %
3 97 %

A value of 2–3 is a good compromise between reliable delivery and channel efficiency.

CLI

No new commands are needed — max_resend_attempts is already exposed:

get max.resend # current value (default: 2)
set max.resend <0–3> # 0 = disabled

@usrflo

usrflo commented Jun 2, 2026

Copy link
Copy Markdown
Author

Some information about the 3 commits:

  1. the first commit MESHCORE_SIMULATOR patch contains common changes to use "mcsim" (see https://github.com/Brent-A/mcsim and https://github.com/usrflo/mcsim) or any other simulation that requires simulation hooks. This commit is not required for this feature but is a requirement to run simulated comparisons.
  2. the second commit Implemented repeated sending for error correction contains changes to the MeshCore implementation (dev branch)
  3. the third commit Added comments to explain changes related to the repeated-sending feature is meant for the code review. This commit might be removed if this pull request is accepted.

@cwichura

cwichura commented Jun 3, 2026

Copy link
Copy Markdown

This seems very similar to #2367.

@usrflo

usrflo commented Jun 12, 2026

Copy link
Copy Markdown
Author

After mcsim-simulation runs and internal tests on real hardware I released firmware packages named "ufo_0.1" for repeaters, companions and room-servers at https://github.com/usrflo/MeshCore/releases. This firmware is based on MeshCore-dev v1.16.0 with application of this pull request.

It would be great to get some feedback on this feature.

usrflo added 4 commits June 18, 2026 13:16
…c to isRetryMatch method for packet retransmission handling
Resolved conflicts:
- CommonCLI.h/cpp: kept both max_resend_attempts (feature) and
  cad_enabled/radio_fem_rxgain (upstream dev), appending
  max_resend_attempts at the end of the pref blob.
- Dispatcher.cpp: kept noise-floor calibration at end of loop()
  (to avoid disrupting repeated-sending retransmissions) and added
  upstream's setCADEnabled() call inside the idle guard.
@usrflo

usrflo commented Jun 19, 2026

Copy link
Copy Markdown
Author

To recognize propagated TRACE packages a special detection was required as TRACE packages differ in using path and body fields. In the simulation with a relatively stable chain of repeaters (TOPOLOGY, BEHAVIOR) I got the following results:

Without repeated sending (max.resend 0)
averages over 10 seeds:
sent per run: 8.0
received total per run: 6.2
collisions per run: 0.0
overall delivery rate: 77.5%

With repeated sending (max.resend 2)
averages over 10 seeds:
sent per run: 8.0
received total per run: 8.0
collisions per run: 3.6
overall delivery rate: 100.0%

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.

2 participants