Skip to content

[WIP] ICD support --according to Claude - #46

Open
alexbarcelo wants to merge 2 commits into
sysgrok:masterfrom
alexbarcelo:icd-support
Open

[WIP] ICD support --according to Claude#46
alexbarcelo wants to merge 2 commits into
sysgrok:masterfrom
alexbarcelo:icd-support

Conversation

@alexbarcelo

Copy link
Copy Markdown

Just a quick&dirty test on how to add ICD support.

Unvetted by a human. I wanted to have something to test on real hardware, but I think that the PR is not quite maintainable (maybe).

Opening it after some discussion on Matrix.

alexbarcelo and others added 2 commits September 1, 2026 17:38
…ture

rs-matter already ships a complete ICD implementation (Icd, IcdMgmtHandler,
IcdModeConfig, Check-In sending, mDNS ICD-mode advertisement), but
rs-matter-stack had no wiring for it: no ICD Management cluster on the root
endpoint, nowhere for MatterStack to own the Icd state, and no persistence
of registrations/Check-In counter across reboots or factory reset.

This adds all of that, gated behind a new default-off `icd` feature so
existing builds are unaffected:

- MatterStack gains an `Icd` field, a `MatterStack::icd()` accessor, and
  startup_icd/reset_icd helpers that re-hydrate/persist registrations and
  the Check-In counter the same way Matter::startup/factory_reset already
  handle the rest of the stack's persisted state.
- Eth, Wifi, and Thread root endpoints each grow an icd-gated variant that
  appends the ICD Management cluster and chains IcdMgmtHandler onto the
  root handler, so all three backends get consistent coverage.
- The stack deliberately only owns the cluster and its persistence, not
  Check-In send timing - that stays app-owned, mirroring how other
  device-specific behavior (e.g. on/off logic) is already left to the app.
- New examples/light_icd.rs demonstrates the wiring end-to-end, including
  a naive periodic Check-In task showing the primitives-only boundary.
- light.rs/light_eth.rs get small cfg-splits so they keep building when
  `icd` is enabled alongside `examples` in the same build (Cargo features
  are additive across the whole compiled crate).

Verified with cargo check/clippy/test in both icd-on and icd-off
configurations, plus the combined --all-targets --features icd,examples
matrix and a full example build.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CdeDK16jkFNkUwXg9yA4qJ
…rossings

startup_icd() loaded the persisted counter boundary (or fell back to the
fresh icd_counter_seed on first boot) but never wrote it back, relying on
advance_counter() to persist only when a full ICD_COUNTER_EPOCH (1000)
increments is crossed. A device that sends only a handful of Check-Ins per
awake window - the common case - never reaches that boundary, so the
persisted value is never written. Since deep sleep is a full reboot for
many ICDs, the next startup falls back to a fresh random seed instead of
resuming past the previous session's counter values, breaking the
monotonicity the Check-In protocol's replay protection depends on:
clients correctly reject a counter that isn't strictly increasing.

Fixes this by persisting the boundary immediately after load_counter(),
matching the contract documented on CheckInCounter::new/persist_value.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017gksfjifBSTr356XkDxBE3
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