Skip to content

Add configurable max hops filter for auto-add contacts - #1900

Merged
ripplebiz merged 4 commits into
meshcore-dev:devfrom
wbijen:feature/contact-filter-by-hops
Mar 3, 2026
Merged

Add configurable max hops filter for auto-add contacts#1900
ripplebiz merged 4 commits into
meshcore-dev:devfrom
wbijen:feature/contact-filter-by-hops

Conversation

@wbijen

@wbijen wbijen commented Mar 2, 2026

Copy link
Copy Markdown
Contributor

Add configurable max hops filter for auto-add contacts

Closes #1533, relates to #1546

Problem

Devices auto-add every contact they hear, regardless of distance. In dense or wide meshes this fills the contact list with far-away nodes that are unreliable to reach, pushing out closer, more useful contacts.

Solution

Add a autoadd_max_hops setting that filters auto-add by hop count. Only new contacts within the configured hop limit are auto-added. Value 0 means no limit (current behavior, the default).

  • Only new contacts are filtered — existing contacts continue to get updated regardless of hop count
  • Filtered contacts still appear in "recently heard"onDiscoveredContact() is called so the companion app UI can show them, they just aren't persisted to the contact list
  • Configurable from companion app — extends the existing CMD_SET/GET_AUTOADD_CONFIG protocol with an optional 3rd byte

Protocol change

CMD_SET_AUTOADD_CONFIG (0x3A):

  • Old: [cmd] [config_bitmask] (2 bytes)
  • New: [cmd] [config_bitmask] [max_hops] (3 bytes, 3rd byte optional)

CMD_GET_AUTOADD_CONFIG response:

  • Old: [resp_code] [config_bitmask] (2 bytes)
  • New: [resp_code] [config_bitmask] [max_hops] (3 bytes)

Backwards compatible — old companion apps send 2 bytes (max_hops stays 0), and ignore the extra response byte per the length-prefixed frame protocol.

Files changed

File Change
src/helpers/BaseChatMesh.h Add virtual getAutoAddMaxHops() (default 0)
src/helpers/BaseChatMesh.cpp Hop count check in onAdvertRecv() for new contacts
examples/companion_radio/NodePrefs.h Add autoadd_max_hops field
examples/companion_radio/DataStore.cpp Persist new field (offset 88)
examples/companion_radio/MyMesh.h Override declaration
examples/companion_radio/MyMesh.cpp Override impl + extended SET/GET handlers

Testing

  • Builds clean on heltec_v4_companion_radio_usb (ESP32-S3)
  • Default value 0 (no limit) preserves current behavior
  • Old prefs files without the new byte: file.read() fails silently, field stays 0 via memset in constructor

Filter auto-add of new contacts by hop count (issues meshcore-dev#1533, meshcore-dev#1546).
Setting is configurable from the companion app via extended
CMD_SET/GET_AUTOADD_CONFIG protocol (0 = no limit, 1-63 = max hops).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@liamcottle

Copy link
Copy Markdown
Member

Hey,

Thanks for the PR!

This looks pretty good to me, nice and simple.
Just wondering if we should allow for the use case of only allowing zero hop contacts to be added as well.

Currently, the PR uses zero to indicate no limit, since the preferences are always initialized to zero by default.

We could possibly fetch the value from prefs, and if it's 1 or higher, we know we have a limit set, but, subtract 1 from that value to indicate what the limit is.

This would allow for enforcing auto add of direct/zero hop contacts too, as well as any other hop limit is desired.

Options would be:

  • 0 (no limit)
  • 1 (0 hop / direct only)
  • 2 (1-hop limit)

Since it's a protocol/companion level thing, it's up to the clients/apps to know that it works this way.

Ideally, we would use something like -1 or 255 as no limit, and 0 as 0-hop and 1 as 1-hop, but this is just a limitation in the firmware where all values are zero by default.

Comment thread examples/companion_radio/MyMesh.cpp Outdated
Comment thread examples/companion_radio/MyMesh.cpp
wbijen and others added 2 commits March 3, 2026 08:37
- Change > to >= so stored value 1 means direct/0-hop only (liamcottle)
- Clamp max_hops to 63 on write since getPathHashCount() caps at 63 (robekl)
- Update comments to reflect encoding: 0=no limit, 1=direct only, N=up to N-1 hops

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@wbijen

wbijen commented Mar 3, 2026

Copy link
Copy Markdown
Contributor Author

Hey,

Thanks for the PR!

This looks pretty good to me, nice and simple. Just wondering if we should allow for the use case of only allowing zero hop contacts to be added as well.

Currently, the PR uses zero to indicate no limit, since the preferences are always initialized to zero by default.

We could possibly fetch the value from prefs, and if it's 1 or higher, we know we have a limit set, but, subtract 1 from that value to indicate what the limit is.

This would allow for enforcing auto add of direct/zero hop contacts too, as well as any other hop limit is desired.

Options would be:

  • 0 (no limit)
  • 1 (0 hop / direct only)
  • 2 (1-hop limit)

Since it's a protocol/companion level thing, it's up to the clients/apps to know that it works this way.

Ideally, we would use something like -1 or 255 as no limit, and 0 as 0-hop and 1 as 1-hop, but this is just a limitation in the firmware where all values are zero by default.

Thanks! Good call - implemented. The encoding is now:

0 = no limit
1 = direct only (0 hops)
N = up to N-1 hops
Also added a clamp to 64 on write per robekl's suggestion.

@wbijen
wbijen force-pushed the feature/contact-filter-by-hops branch from 65bbab9 to 1d190ad Compare March 3, 2026 08:06
@ripplebiz
ripplebiz merged commit 6431cd2 into meshcore-dev:dev Mar 3, 2026
9 checks passed
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.

4 participants