Skip to content

fix(filter): always build the rate limiters from the active prefs - #24

Merged
Elektr0Vodka merged 1 commit into
dmc-devfrom
fix/dmc-dev-filter-limiter-init
Oct 19, 2026
Merged

Elektr0Vodka merged 1 commit into
dmc-devfrom
fix/dmc-dev-filter-limiter-init

Conversation

@Elektr0Vodka

Copy link
Copy Markdown

What was wrong

On a repeater that has never saved filter settings, filter on applied no rate limits at all. The defaults (5–20 packets per 60 s per type) only took effect after a save and a reboot. filter reset had the reverse problem: it restored the default prefs but kept enforcing the last filter rate setting, while filter rate already showed the defaults.

Cause: Filter::load() returned before setting up the per-type limiters when /filter_prefs did not exist, and resetPrefs() never touched them. A default Limiter has limit 0, which means unlimited.

Fix

The constructor, resetPrefs() and load() now all end in one initLimiters(), which builds the limiters from the active prefs.

Test

  • New test_filter_limits drives Filter through load → handleCommand → allowPacketForward. Both cases fail before the fix (6 of 6 packets forwarded, limit 5) and pass after it.
  • This is the first test that compiles Filter.cpp on the native env. It needed constrain in test/mocks/Arduino.h (Arduino's macro) and a stub for the Identity constructor in the test.
  • pio test -e native -e native_region_gating: 269/269 pass locally. On Windows test_kiss_modem exits with 0xC0000139 (a DLL entry-point error); the same happens without this change.

Notes

  • Found during the 2026-10-19 architecture review (side finding 3).
  • The observer runs the older Filter.cpp and has the same bug; it gets the fix with the next dmc-dev → observer merge.

🤖 Generated with Claude Code

Filter::load() returned before initialising the per-type limiters when
/filter_prefs did not exist yet, and `filter reset` restored the default
prefs without touching the limiters. A default Limiter has limit 0, which
means "no limit": on a fresh repeater `filter on` applied none of the
default rate limits (5-20 per 60 s) until the first reboot after a save,
and after `filter reset` the last `filter rate` kept being enforced while
`filter rate` reported the defaults.

All three paths (constructor, resetPrefs, load) now end in initLimiters().

Test: test_filter_limits drives Filter through load/handleCommand/
allowPacketForward on the native env. That is the first test that
compiles Filter.cpp natively; it needed `constrain` in the Arduino mock.
@Elektr0Vodka
Elektr0Vodka merged commit f942ee7 into dmc-dev Oct 19, 2026
1 check 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.

1 participant