Conversation
... suited for SVE. The implementation is based on current matter.js and utilized overrides to implement the relevant changes. This needs to be revised later
# Conflicts: # packages/node/src/behaviors/access-control/AccessControlServer.ts # packages/protocol/src/groups/FabricGroups.ts # packages/types/src/clusters/access-control.ts # packages/types/src/clusters/group-key-management.ts
# Conflicts: # packages/node/src/behaviors/general-diagnostics/GeneralDiagnosticsServer.ts # packages/node/src/behaviors/group-key-management/GroupKeyManagementServer.ts # packages/node/src/behaviors/groups/GroupsServer.ts # packages/protocol/src/protocol/MessageExchange.ts # packages/testing/src/chip/matter-js-pics.properties # packages/types/src/clusters/access-control.d.ts # packages/types/src/clusters/basic-information.ts # packages/types/src/clusters/general-diagnostics.ts # packages/types/src/clusters/group-key-management.ts # packages/types/src/clusters/groups.ts
The Groupcast cluster PICS code in the CHIP test harness changed from GCAST to GC. Rename the test file, update describe/chip() labels, and drop the stale GCAST.S=1 PICS entry (GC.S=1 is authoritative). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Post-merge codegen output:
- New: types/clusters/groupcast.{d.ts,js} cluster definition
- Schema additions driven by groupcast overrides: AccessControl (AUX feature +
AuxiliaryACL), BasicInformation + GeneralDiagnostics (DeviceLoadStatus),
GroupKeyManagement (GCAST feature + GroupcastAdoption), Groups
- Behavior codegen drift: GroupcastBehavior, GroupcastClient, groupcast index
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Apollon77
force-pushed
the
groupcast
branch
3 times, most recently
from
April 16, 2026 10:20
6374936 to
d286eee
Compare
Align with Matter 1.6.0 certification scope: - GKM: comment out GroupcastAdoption struct + attribute (provisional) - Groups: revert to revision 4, comment out INVALID_IN_STATE adoption checks (provisional per spec PR #12893) - ACL: add quality "C" to AuxiliaryAcl attribute - Groupcast JoinGroup/UpdateGroupKey: reject KeySetID 0 (IPK), require Admin privilege when key or useAuxiliaryACL fields are present - Groupcast: reconcile unmapped keys (KeySetId=0xFFFF) at startup and on GKM groupKeyMap changes - Groupcast model: add constraint "min 1" on command KeySetId fields - Update tests for new validations and removed adoption state Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When the AccessControl Auxiliary feature is active, Group auth mode ACL entries with wildcard targets (empty) must not grant access to endpoint 0 (root endpoint). Groupcast commands shall not interact with clusters on the root endpoint. Adds auxiliaryFeatureEnabled flag to FabricAccessControl, set by AccessControlServer during initialization and fabric updates. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Groupcast cluster's membership mappings are mirrored into GKM's GroupKeyMap attribute so the attribute reflects the Groupcast data dependency (fixes TC_SC_5_1). - SessionManager exposes an onGroupMessage observable + emitGroupMessage() helper. Observable is a no-op when no listener is attached. - New typed errors GroupSessionNoKeyError and GroupSessionDecodeError replace generic MatterFlowError in GroupSession.decode; SessionManager emits NoAvailableKey / FailedAuth events using causedBy() checks. - ExchangeManager emits MessageReplay on DuplicateMessageError in group sessions. InteractionServer emits Success with accessAllowed per dispatched group command. - GroupcastServer dynamically attaches/detaches a listener on the SessionManager observable based on fabricUnderTest state, emits the cluster event only for the fabric under test. - Magic number 0xFFFF factored into UNMAPPED_KEYSET_ID constant. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CHIP's PeerAddress::Groupcast() wraps the spec-defined IANA address ff05::fa through MakeIPv6PrefixMulticast(scope=5, prefixLen=64, prefix=0xff05000000000000, groupId=0xfa), producing the unicast-prefix-based form ff35:40:ff05::fa. The spec text just says "FF05::FA" without specifying this wrapping, so this looks like CHIP using its existing helper rather than emitting the literal address. Bind to the CHIP-emitted form so TC_SC_5_2 and other Groupcast tests pass. Marked all touched sites with TODO(IANA-WRAP) for easy reversion when upstream is clarified. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… correctly Several related fixes to make Groupcast Listener+Sender work end-to-end with GroupKeyManagement, FabricGroups runtime dispatch, and GroupcastTesting events: GroupcastServer: - #syncFabricGroups: set per-group multicast policy BEFORE assigning groupKeyIdMap, since the latter triggers ServerGroupNetworking to bind via multicastAddressFor — which reads the policy. Old order fell back to PerGroupId-derived addresses for IanaAddr-policy groups. - #syncFabricGroups: also mirror Membership endpoints into gkm.state.groupTable (spec attribute) and fabric.groups.endpoints (runtime lookup used by InteractionServer for wildcard group dispatch). Without this, group msgs hit "No endpoints mapped to group N, skipping wildcard invoke". - Lower maxMembershipCount/maxMcastAddrCount defaults from 254 to 44 so the per-fabric quota floor(44/2)=22 aligns exactly with GKM's per-fabric cap. Even alignment avoids spillover semantics; mirror writes never exceed the GKM validator. - Wrap onGroupMessage listener with this.callback so it has a fresh action context when invoked after the dispatching transaction has committed (otherwise this.state/this.events references are expired). GroupKeyManagementServer: - Bump maxGroupsPerFabric default from 21 to 22 (matches Groupcast quota=22). InteractionServer: - For group invokes that produce no dispatched commands (wildcard expansion filtered out by ACL or no endpoint mappings), emit one fallback GroupcastTesting event per requested invoke path with result=FailedAuth and accessAllowed=false. TC_ACE_1_6 step 13 expects this signal. ClientNodeTest: update expected maxGroupsPerFabric attribute to 0x16. Tests added: endpoint mirror propagation/cleanup, two-fabric quota fill-to- M_max scenario, GKM mirror behavior, multicast policy ordering guarantee. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ddress" This reverts commit 51ac431.
Matching the CHIP SDK, only key sets referenced by GroupKeyMap count as available for decryption: with none the result is NoAvailableKey, even when a message fails to authenticate against an unmapped key set. Unmapped key sets only recover the authenticated group id for Groupcast testing reporting. Mapped candidates that all fail to decrypt remain FailedAuth. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts: # CHANGELOG.md # packages/node/src/behaviors/group-key-management/GroupKeyManagementServer.ts
TC_ACE_1_6 now defines three runs testing distinct device configs: - run1: all-clusters (groupcast on root) -> groupcast path - run2: all-clusters-no-groupcast -> legacy Groups path - run3: all-devices on-off-light --groupcast -> groupcast path Gate the root Groupcast cluster (and the Auxiliary ACL it needs) on a flag in the AllClusters and AllDevices roots, add the no-groupcast AllClusters variant + subject, and include run1/run2/run3 in the test. The groupcast-on branch is unchanged, so the default all-clusters subject used by every other test is unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tatus The GroupcastTesting event's AccessAllowed conflated command-execution status with the access-control outcome: a group command that passed ACL but returned a non-Success status (e.g. InvalidCommand, Busy) was reported AccessAllowed=false. Per Groupcast spec §11.27.7.6.3 AccessAllowed indicates only whether Access Control permitted the invoke. Access-denied wildcard paths are dropped before dispatch (handled by the no-dispatch branch), so any emitted response/status means access was allowed. Surfaced by TC_ACE_1_6 run3 (all-devices on-off-light) targeting ScenesManagement.ViewScene, which returns InvalidCommand for groupId 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Membership is now rebuilt by #deriveMembership from groupProperties + GKM groupTable/groupKeyMap; commands write GKM directly and re-derive. Removes the membership->GKM mirror and its reconcile reactors (#syncFabricGroups, #reconcileUnmappedKeys, #reconcileMembershipEndpoints, #migrate). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…reate-path configureAuxiliaryAcl on a legacy-only group must not flip its multicast address. Shared #defaultMcastAddrPolicy() so create-path and derive agree. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…upIfEmpty) Legacy/external groupTable emptying fully deletes a group from Membership; groupcast leaveGroup on a Sender-feature device keeps it sender-only. A non-persistent mark set distinguishes the intentional sender-only keeps from external removals so the offline groupTable$Changed prune deletes only the latter. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…view Add an IanaAddr survivor group so the reload address check can actually distinguish real policy re-application from a no-op (PerGroup and "no policy" compute the same address); drop a masking ?? false fallback on a field that is always defined; note why two legacy-only-group tests aren't duplicates. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…-independent) ServerGroupNetworking now rebinds a group's multicast membership when its address policy changes, so reload/fabric-replace bind the correct address regardless of whether GKM restores endpoints before or after Groupcast applies policy. #groupMulticastPolicy is a BasicMap so the change is observable. Also mark retainedSenderOnly only at command commit (no leak on rollback). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Shorten the rebind/policy comments to the load-bearing WHY; drop BasicMap base-behavior narration. Correct the join ordering comment: policy-before- endpoints is now an optimization (rebind makes it correctness-independent). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ServerGroupNetworking.close() left the joined multicast groups on the shared UDP socket; a Node dgram socket with active memberships can hang on close(), blocking runtime shutdown (observed only after groupcast use, needing a second CTRL-C). Drop all memberships before teardown; make close() async and awaited. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ion conflict Removing a fabric with a surviving second fabric clears the departing fabric's GKM groupTable and groupKeyMap in one commit, firing both GroupcastServer offline reactors against groupcast.state in a single cascade. The first held the state lock across its async commit while the second wrote synchronously, throwing SynchronousTransactionConflictError. Reactors now record pruning intent into pending sets and derive through #deriveNow, which takes the lock synchronously and derives inline when it is free (preserving same-tick timing) but hands off to an async-locked, debounced derive the moment the lock is contended, so no two writers ever contend synchronously. Commands keep their synchronous derive. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A legacy Groups.RemoveAllGroups that empties a groupcast listener group triggers the auxiliary-ACL update only through groupcast's offline groupTable/groupKeyMap reactors, which previously derived membership with their own actor-less context. The resulting AuxiliaryAccessUpdated event carried adminNodeId=null instead of the administering node. Thread the writer's online context (delivered as the state-change event's context argument) through the derive to #emitAuxAcl, used only to name the admin; state writes keep using the reactor's own locked transaction. The deferred derive (fabric-removal cascade) still emits with no admin. Register the AccessControlServer auxiliary-ACL provider reactor offline so the auxiliaryAcl state write uses its own transaction rather than re-opening the provider's already-committed one during postCommit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
... suited for SVE.
The implementation is based on current matter.js and utilizes overrides to implement the relevant changes. This will be replaced by generated classes later, but works for now.
This Draft PR will stay a bit until we move to Matter 1.6 officially