@matter/node 0.14.0 → 0.14.1-alpha.0-20250606-a9bcd03f9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/behavior/Behavior.d.ts +2 -1
- package/dist/cjs/behavior/Behavior.d.ts.map +1 -1
- package/dist/cjs/behavior/Behavior.js +1 -1
- package/dist/cjs/behavior/Behavior.js.map +1 -1
- package/dist/cjs/behavior/Transitions.js +2 -2
- package/dist/cjs/behavior/Transitions.js.map +1 -1
- package/dist/cjs/behavior/context/server/OnlineContext.d.ts +3 -3
- package/dist/cjs/behavior/context/server/OnlineContext.d.ts.map +1 -1
- package/dist/cjs/behavior/context/server/OnlineContext.js +12 -9
- package/dist/cjs/behavior/context/server/OnlineContext.js.map +1 -1
- package/dist/cjs/behavior/internal/ClientBehaviorBacking.d.ts +2 -1
- package/dist/cjs/behavior/internal/ClientBehaviorBacking.d.ts.map +1 -1
- package/dist/cjs/behavior/internal/ClientBehaviorBacking.js.map +1 -1
- package/dist/cjs/behavior/system/network/NetworkBehavior.d.ts.map +1 -1
- package/dist/cjs/behavior/system/network/NetworkBehavior.js +2 -1
- package/dist/cjs/behavior/system/network/NetworkBehavior.js.map +1 -1
- package/dist/cjs/behavior/system/network/ServerGroupNetworking.d.ts +18 -0
- package/dist/cjs/behavior/system/network/ServerGroupNetworking.d.ts.map +1 -0
- package/dist/cjs/behavior/system/network/ServerGroupNetworking.js +150 -0
- package/dist/cjs/behavior/system/network/ServerGroupNetworking.js.map +6 -0
- package/dist/cjs/behavior/system/network/ServerNetworkRuntime.d.ts.map +1 -1
- package/dist/cjs/behavior/system/network/ServerNetworkRuntime.js +25 -7
- package/dist/cjs/behavior/system/network/ServerNetworkRuntime.js.map +1 -1
- package/dist/cjs/behavior/system/sessions/SessionsBehavior.d.ts.map +1 -1
- package/dist/cjs/behavior/system/sessions/SessionsBehavior.js.map +1 -1
- package/dist/cjs/behaviors/access-control/AccessControlServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/access-control/AccessControlServer.js +18 -12
- package/dist/cjs/behaviors/access-control/AccessControlServer.js.map +1 -1
- package/dist/cjs/behaviors/color-control/ColorControlServer.d.ts +4 -4
- package/dist/cjs/behaviors/color-control/ColorControlServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/color-control/ColorControlServer.js +3 -3
- package/dist/cjs/behaviors/color-control/ColorControlServer.js.map +1 -1
- package/dist/cjs/behaviors/general-commissioning/GeneralCommissioningServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/general-commissioning/GeneralCommissioningServer.js +5 -4
- package/dist/cjs/behaviors/general-commissioning/GeneralCommissioningServer.js.map +1 -1
- package/dist/cjs/behaviors/general-commissioning/ServerNodeFailsafeContext.d.ts +1 -1
- package/dist/cjs/behaviors/general-commissioning/ServerNodeFailsafeContext.d.ts.map +1 -1
- package/dist/cjs/behaviors/group-key-management/GroupKeyManagementServer.d.ts +27 -4
- package/dist/cjs/behaviors/group-key-management/GroupKeyManagementServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/group-key-management/GroupKeyManagementServer.js +340 -21
- package/dist/cjs/behaviors/group-key-management/GroupKeyManagementServer.js.map +2 -2
- package/dist/cjs/behaviors/groups/GroupsServer.d.ts +19 -3
- package/dist/cjs/behaviors/groups/GroupsServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/groups/GroupsServer.js +138 -1
- package/dist/cjs/behaviors/groups/GroupsServer.js.map +2 -2
- package/dist/cjs/behaviors/level-control/LevelControlServer.d.ts +5 -5
- package/dist/cjs/behaviors/level-control/LevelControlServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/level-control/LevelControlServer.js +3 -3
- package/dist/cjs/behaviors/level-control/LevelControlServer.js.map +1 -1
- package/dist/cjs/behaviors/mode-select/ModeSelectServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/mode-select/ModeSelectServer.js +3 -3
- package/dist/cjs/behaviors/mode-select/ModeSelectServer.js.map +1 -1
- package/dist/cjs/behaviors/on-off/OnOffServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/on-off/OnOffServer.js +3 -3
- package/dist/cjs/behaviors/on-off/OnOffServer.js.map +1 -1
- package/dist/cjs/behaviors/operational-credentials/OperationalCredentialsServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/operational-credentials/OperationalCredentialsServer.js +14 -8
- package/dist/cjs/behaviors/operational-credentials/OperationalCredentialsServer.js.map +1 -1
- package/dist/cjs/endpoint/Endpoint.js +1 -1
- package/dist/cjs/endpoint/Endpoint.js.map +1 -1
- package/dist/cjs/node/Node.d.ts +1 -1
- package/dist/cjs/node/Node.d.ts.map +1 -1
- package/dist/cjs/node/Node.js +2 -2
- package/dist/cjs/node/Node.js.map +1 -1
- package/dist/cjs/node/ServerNode.d.ts +1 -1
- package/dist/cjs/node/ServerNode.d.ts.map +1 -1
- package/dist/cjs/node/ServerNode.js +2 -2
- package/dist/cjs/node/ServerNode.js.map +1 -1
- package/dist/cjs/node/client/NodePeerAddressStore.d.ts +1 -1
- package/dist/cjs/node/client/NodePeerAddressStore.d.ts.map +1 -1
- package/dist/cjs/node/server/InteractionServer.d.ts +2 -2
- package/dist/cjs/node/server/InteractionServer.d.ts.map +1 -1
- package/dist/cjs/node/server/InteractionServer.js +1 -1
- package/dist/cjs/node/server/InteractionServer.js.map +1 -1
- package/dist/cjs/node/server/ServerSubscription.d.ts +4 -4
- package/dist/cjs/node/server/ServerSubscription.d.ts.map +1 -1
- package/dist/cjs/node/server/ServerSubscription.js.map +1 -1
- package/dist/esm/behavior/Behavior.d.ts +2 -1
- package/dist/esm/behavior/Behavior.d.ts.map +1 -1
- package/dist/esm/behavior/Behavior.js +2 -2
- package/dist/esm/behavior/Behavior.js.map +1 -1
- package/dist/esm/behavior/Transitions.js +1 -1
- package/dist/esm/behavior/context/server/OnlineContext.d.ts +3 -3
- package/dist/esm/behavior/context/server/OnlineContext.d.ts.map +1 -1
- package/dist/esm/behavior/context/server/OnlineContext.js +13 -10
- package/dist/esm/behavior/context/server/OnlineContext.js.map +1 -1
- package/dist/esm/behavior/internal/ClientBehaviorBacking.d.ts +2 -1
- package/dist/esm/behavior/internal/ClientBehaviorBacking.d.ts.map +1 -1
- package/dist/esm/behavior/internal/ClientBehaviorBacking.js.map +1 -1
- package/dist/esm/behavior/system/network/NetworkBehavior.d.ts.map +1 -1
- package/dist/esm/behavior/system/network/NetworkBehavior.js +2 -1
- package/dist/esm/behavior/system/network/NetworkBehavior.js.map +1 -1
- package/dist/esm/behavior/system/network/ServerGroupNetworking.d.ts +18 -0
- package/dist/esm/behavior/system/network/ServerGroupNetworking.d.ts.map +1 -0
- package/dist/esm/behavior/system/network/ServerGroupNetworking.js +130 -0
- package/dist/esm/behavior/system/network/ServerGroupNetworking.js.map +6 -0
- package/dist/esm/behavior/system/network/ServerNetworkRuntime.d.ts.map +1 -1
- package/dist/esm/behavior/system/network/ServerNetworkRuntime.js +23 -5
- package/dist/esm/behavior/system/network/ServerNetworkRuntime.js.map +1 -1
- package/dist/esm/behavior/system/sessions/SessionsBehavior.d.ts.map +1 -1
- package/dist/esm/behavior/system/sessions/SessionsBehavior.js.map +1 -1
- package/dist/esm/behaviors/access-control/AccessControlServer.d.ts.map +1 -1
- package/dist/esm/behaviors/access-control/AccessControlServer.js +20 -13
- package/dist/esm/behaviors/access-control/AccessControlServer.js.map +1 -1
- package/dist/esm/behaviors/color-control/ColorControlServer.d.ts +4 -4
- package/dist/esm/behaviors/color-control/ColorControlServer.d.ts.map +1 -1
- package/dist/esm/behaviors/color-control/ColorControlServer.js +3 -3
- package/dist/esm/behaviors/color-control/ColorControlServer.js.map +1 -1
- package/dist/esm/behaviors/general-commissioning/GeneralCommissioningServer.d.ts.map +1 -1
- package/dist/esm/behaviors/general-commissioning/GeneralCommissioningServer.js +6 -5
- package/dist/esm/behaviors/general-commissioning/GeneralCommissioningServer.js.map +1 -1
- package/dist/esm/behaviors/general-commissioning/ServerNodeFailsafeContext.d.ts +1 -1
- package/dist/esm/behaviors/general-commissioning/ServerNodeFailsafeContext.d.ts.map +1 -1
- package/dist/esm/behaviors/group-key-management/GroupKeyManagementServer.d.ts +27 -4
- package/dist/esm/behaviors/group-key-management/GroupKeyManagementServer.d.ts.map +1 -1
- package/dist/esm/behaviors/group-key-management/GroupKeyManagementServer.js +342 -23
- package/dist/esm/behaviors/group-key-management/GroupKeyManagementServer.js.map +2 -2
- package/dist/esm/behaviors/groups/GroupsServer.d.ts +19 -3
- package/dist/esm/behaviors/groups/GroupsServer.d.ts.map +1 -1
- package/dist/esm/behaviors/groups/GroupsServer.js +147 -1
- package/dist/esm/behaviors/groups/GroupsServer.js.map +1 -1
- package/dist/esm/behaviors/level-control/LevelControlServer.d.ts +5 -5
- package/dist/esm/behaviors/level-control/LevelControlServer.d.ts.map +1 -1
- package/dist/esm/behaviors/level-control/LevelControlServer.js +3 -3
- package/dist/esm/behaviors/level-control/LevelControlServer.js.map +1 -1
- package/dist/esm/behaviors/mode-select/ModeSelectServer.d.ts.map +1 -1
- package/dist/esm/behaviors/mode-select/ModeSelectServer.js +3 -3
- package/dist/esm/behaviors/mode-select/ModeSelectServer.js.map +1 -1
- package/dist/esm/behaviors/on-off/OnOffServer.d.ts.map +1 -1
- package/dist/esm/behaviors/on-off/OnOffServer.js +3 -3
- package/dist/esm/behaviors/on-off/OnOffServer.js.map +1 -1
- package/dist/esm/behaviors/operational-credentials/OperationalCredentialsServer.d.ts.map +1 -1
- package/dist/esm/behaviors/operational-credentials/OperationalCredentialsServer.js +15 -9
- package/dist/esm/behaviors/operational-credentials/OperationalCredentialsServer.js.map +1 -1
- package/dist/esm/endpoint/Endpoint.js +1 -1
- package/dist/esm/endpoint/Endpoint.js.map +1 -1
- package/dist/esm/node/Node.d.ts +1 -1
- package/dist/esm/node/Node.d.ts.map +1 -1
- package/dist/esm/node/Node.js +1 -1
- package/dist/esm/node/Node.js.map +1 -1
- package/dist/esm/node/ServerNode.d.ts +1 -1
- package/dist/esm/node/ServerNode.d.ts.map +1 -1
- package/dist/esm/node/ServerNode.js +1 -1
- package/dist/esm/node/client/NodePeerAddressStore.d.ts +1 -1
- package/dist/esm/node/client/NodePeerAddressStore.d.ts.map +1 -1
- package/dist/esm/node/server/InteractionServer.d.ts +2 -2
- package/dist/esm/node/server/InteractionServer.d.ts.map +1 -1
- package/dist/esm/node/server/InteractionServer.js +2 -2
- package/dist/esm/node/server/InteractionServer.js.map +1 -1
- package/dist/esm/node/server/ServerSubscription.d.ts +4 -4
- package/dist/esm/node/server/ServerSubscription.d.ts.map +1 -1
- package/dist/esm/node/server/ServerSubscription.js.map +1 -1
- package/package.json +7 -7
- package/src/behavior/Behavior.ts +2 -2
- package/src/behavior/Transitions.ts +1 -1
- package/src/behavior/context/server/OnlineContext.ts +21 -19
- package/src/behavior/internal/ClientBehaviorBacking.ts +2 -1
- package/src/behavior/system/commissioning/CommissioningClient.ts +1 -1
- package/src/behavior/system/network/NetworkBehavior.ts +2 -1
- package/src/behavior/system/network/ServerGroupNetworking.ts +150 -0
- package/src/behavior/system/network/ServerNetworkRuntime.ts +27 -5
- package/src/behavior/system/sessions/SessionsBehavior.ts +5 -5
- package/src/behaviors/access-control/AccessControlServer.ts +21 -14
- package/src/behaviors/color-control/ColorControlServer.ts +4 -4
- package/src/behaviors/general-commissioning/GeneralCommissioningServer.ts +8 -7
- package/src/behaviors/general-commissioning/ServerNodeFailsafeContext.ts +1 -1
- package/src/behaviors/group-key-management/GroupKeyManagementServer.ts +441 -26
- package/src/behaviors/groups/GroupsServer.ts +181 -3
- package/src/behaviors/level-control/LevelControlServer.ts +5 -5
- package/src/behaviors/mode-select/ModeSelectServer.ts +3 -3
- package/src/behaviors/on-off/OnOffServer.ts +3 -3
- package/src/behaviors/operational-credentials/OperationalCredentialsServer.ts +17 -9
- package/src/endpoint/Endpoint.ts +1 -1
- package/src/node/Node.ts +1 -1
- package/src/node/ServerNode.ts +1 -1
- package/src/node/client/NodePeerAddressStore.ts +1 -1
- package/src/node/server/InteractionServer.ts +5 -6
- package/src/node/server/ServerSubscription.ts +3 -4
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { Construction, Environment, InternalError, Logger, ObserverGroup, UdpInterface } from "#general";
|
|
7
|
+
import { Fabric, FabricManager } from "#protocol";
|
|
8
|
+
import { FabricIndex, GroupId } from "#types";
|
|
9
|
+
|
|
10
|
+
const logger = Logger.get("ServerGroupNetworking");
|
|
11
|
+
|
|
12
|
+
export class ServerGroupNetworking {
|
|
13
|
+
#construction: Construction<ServerGroupNetworking>;
|
|
14
|
+
#udpInterface: UdpInterface;
|
|
15
|
+
#activeGroupMemberships = new Map<FabricIndex, Map<GroupId, string>>();
|
|
16
|
+
#fabricObservers = new Map<FabricIndex, ObserverGroup>();
|
|
17
|
+
#observers = new ObserverGroup(this);
|
|
18
|
+
|
|
19
|
+
get construction() {
|
|
20
|
+
return this.#construction;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The server group networking is not implemented in the Node.js environment.
|
|
25
|
+
* This class is a placeholder to maintain compatibility with the Matter.js architecture.
|
|
26
|
+
*/
|
|
27
|
+
constructor(env: Environment, udpInterface: UdpInterface) {
|
|
28
|
+
this.#udpInterface = udpInterface;
|
|
29
|
+
this.#construction = Construction(this);
|
|
30
|
+
this.#construction.start(env);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async [Construction.construct](env: Environment) {
|
|
34
|
+
const fabrics = env.get(FabricManager);
|
|
35
|
+
|
|
36
|
+
for (const fabric of fabrics) {
|
|
37
|
+
if (this.#activeGroupMemberships.has(fabric.fabricIndex)) {
|
|
38
|
+
throw new InternalError("Group transport interfaces already initialized for this fabric.");
|
|
39
|
+
}
|
|
40
|
+
for (const groupId of fabric.groups.groupKeyIdMap.keys()) {
|
|
41
|
+
await this.#addGroupMembership(groupId, fabric);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
this.#registerFabricGroupObserver(fabric);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// When new fabric is added we register for group changes - new fabrics cannot have groups already configured
|
|
48
|
+
this.#observers.on(fabrics.events.added, async fabric => this.#registerFabricGroupObserver(fabric));
|
|
49
|
+
|
|
50
|
+
// When fabric is deleted, we remove the group memberships
|
|
51
|
+
this.#observers.on(fabrics.events.deleted, async fabric => {
|
|
52
|
+
const fabricIndex = fabric.fabricIndex;
|
|
53
|
+
this.#observersForFabric(fabricIndex).close();
|
|
54
|
+
this.#fabricObservers.delete(fabricIndex);
|
|
55
|
+
|
|
56
|
+
const memberships = this.#activeGroupMemberships.get(fabricIndex);
|
|
57
|
+
if (memberships === undefined || memberships.size === 0) {
|
|
58
|
+
this.#activeGroupMemberships.delete(fabricIndex);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
for (const groupId of memberships.keys()) {
|
|
62
|
+
await this.#dropGroupMembership(groupId, fabric);
|
|
63
|
+
}
|
|
64
|
+
this.#activeGroupMemberships.delete(fabricIndex);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
this.#observers.on(fabrics.events.updated, async fabric => {
|
|
68
|
+
const fabricIndex = fabric.fabricIndex;
|
|
69
|
+
|
|
70
|
+
this.#observersForFabric(fabricIndex).close();
|
|
71
|
+
this.#fabricObservers.delete(fabricIndex);
|
|
72
|
+
this.#registerFabricGroupObserver(fabric);
|
|
73
|
+
|
|
74
|
+
// Sync (add or remove as needed) by new group configuration
|
|
75
|
+
const { groupKeyIdMap } = fabric.groups;
|
|
76
|
+
for (const groupId of groupKeyIdMap.keys()) {
|
|
77
|
+
await this.#addGroupMembership(groupId, fabric);
|
|
78
|
+
}
|
|
79
|
+
const memberships = this.#activeGroupMemberships.get(fabricIndex) ?? new Map<GroupId, string>();
|
|
80
|
+
if (memberships.size !== 0) {
|
|
81
|
+
for (const groupId of memberships.keys()) {
|
|
82
|
+
if (!groupKeyIdMap.has(groupId)) {
|
|
83
|
+
await this.#dropGroupMembership(groupId, fabric);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async #addGroupMembership(groupId: GroupId, fabric: Fabric) {
|
|
91
|
+
const fabricIndex = fabric.fabricIndex;
|
|
92
|
+
const memberships = this.#activeGroupMemberships.get(fabricIndex) ?? new Map<GroupId, string>();
|
|
93
|
+
if (memberships.has(groupId)) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const address = fabric.groups.multicastAddressFor(groupId);
|
|
97
|
+
logger.debug(
|
|
98
|
+
`Adding membership for group ${groupId} on fabric ${fabric.fabricId} (index ${fabricIndex}) with address ${address}`,
|
|
99
|
+
);
|
|
100
|
+
await this.#udpInterface.addMembership(address);
|
|
101
|
+
memberships.set(groupId, address);
|
|
102
|
+
this.#activeGroupMemberships.set(fabricIndex, memberships);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async #dropGroupMembership(groupId: GroupId, fabric: Fabric) {
|
|
106
|
+
const fabricIndex = fabric.fabricIndex;
|
|
107
|
+
const memberships = this.#activeGroupMemberships.get(fabricIndex);
|
|
108
|
+
if (memberships === undefined || memberships.size === 0) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const address = fabric.groups.multicastAddressFor(groupId);
|
|
112
|
+
logger.debug(
|
|
113
|
+
`Dropping membership for group ${groupId} on fabric ${fabric.fabricId} (index ${fabricIndex}) with address ${address}`,
|
|
114
|
+
);
|
|
115
|
+
await this.#udpInterface.dropMembership(address);
|
|
116
|
+
memberships.delete(groupId);
|
|
117
|
+
if (!memberships.size) {
|
|
118
|
+
this.#activeGroupMemberships.delete(fabricIndex);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
#observersForFabric(fabricIndex: FabricIndex) {
|
|
123
|
+
let observers = this.#fabricObservers.get(fabricIndex);
|
|
124
|
+
if (observers === undefined) {
|
|
125
|
+
observers = new ObserverGroup(this);
|
|
126
|
+
this.#fabricObservers.set(fabricIndex, observers);
|
|
127
|
+
}
|
|
128
|
+
return observers;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
#registerFabricGroupObserver(fabric: Fabric) {
|
|
132
|
+
const fabricIndex = fabric.fabricIndex;
|
|
133
|
+
|
|
134
|
+
const observers = this.#observersForFabric(fabricIndex);
|
|
135
|
+
observers.on(
|
|
136
|
+
fabric.groups.groupKeyIdMap.added,
|
|
137
|
+
async groupId => await this.#addGroupMembership(groupId, fabric),
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
observers.on(fabric.groups.groupKeyIdMap.deleted, async groupId => this.#dropGroupMembership(groupId, fabric));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
close() {
|
|
144
|
+
this.#construction.close();
|
|
145
|
+
this.#observers.close();
|
|
146
|
+
this.#fabricObservers.forEach(observer => observer.close());
|
|
147
|
+
this.#activeGroupMemberships.clear();
|
|
148
|
+
this.#fabricObservers.clear();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { SubscriptionBehavior } from "#behavior/system/subscription/
|
|
7
|
+
import { SubscriptionBehavior } from "#behavior/system/subscription/SubscriptionBehavior.js";
|
|
8
8
|
import {
|
|
9
9
|
Construction,
|
|
10
10
|
InterfaceType,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
UdpInterface,
|
|
21
21
|
} from "#general";
|
|
22
22
|
import type { ServerNode } from "#node/ServerNode.js";
|
|
23
|
-
import { NodePeerAddressStore } from "#node/
|
|
23
|
+
import { NodePeerAddressStore } from "#node/client/NodePeerAddressStore.js";
|
|
24
24
|
import { InteractionServer } from "#node/server/InteractionServer.js";
|
|
25
25
|
import {
|
|
26
26
|
Ble,
|
|
@@ -43,6 +43,7 @@ import { CommissioningServer } from "../commissioning/CommissioningServer.js";
|
|
|
43
43
|
import { ProductDescriptionServer } from "../product-description/ProductDescriptionServer.js";
|
|
44
44
|
import { SessionsBehavior } from "../sessions/SessionsBehavior.js";
|
|
45
45
|
import { NetworkRuntime } from "./NetworkRuntime.js";
|
|
46
|
+
import { ServerGroupNetworking } from "./ServerGroupNetworking.js";
|
|
46
47
|
|
|
47
48
|
const logger = Logger.get("ServerNetworkRuntime");
|
|
48
49
|
|
|
@@ -62,8 +63,10 @@ export class ServerNetworkRuntime extends NetworkRuntime {
|
|
|
62
63
|
#mdnsBroadcaster?: MdnsInstanceBroadcaster;
|
|
63
64
|
#bleBroadcaster?: InstanceBroadcaster;
|
|
64
65
|
#bleTransport?: TransportInterface;
|
|
66
|
+
#ipv6UdpInterface?: UdpInterface;
|
|
65
67
|
#observers = new ObserverGroup(this);
|
|
66
68
|
#formerSubscriptionsHandled = false;
|
|
69
|
+
#groupNetworking?: ServerGroupNetworking;
|
|
67
70
|
|
|
68
71
|
override get owner() {
|
|
69
72
|
return super.owner as ServerNode;
|
|
@@ -148,15 +151,15 @@ export class ServerNetworkRuntime extends NetworkRuntime {
|
|
|
148
151
|
|
|
149
152
|
const port = this.owner.state.network.port;
|
|
150
153
|
try {
|
|
151
|
-
|
|
154
|
+
this.#ipv6UdpInterface = await UdpInterface.create(
|
|
152
155
|
this.owner.env.get(Network),
|
|
153
156
|
"udp6",
|
|
154
157
|
port ? port : undefined,
|
|
155
158
|
netconf.listeningAddressIpv6,
|
|
156
159
|
);
|
|
157
|
-
interfaces.add(
|
|
160
|
+
interfaces.add(this.#ipv6UdpInterface);
|
|
158
161
|
|
|
159
|
-
await this.owner.set({ network: { operationalPort:
|
|
162
|
+
await this.owner.set({ network: { operationalPort: this.#ipv6UdpInterface.port } });
|
|
160
163
|
} catch (error) {
|
|
161
164
|
NoAddressAvailableError.accept(error);
|
|
162
165
|
logger.info(`IPv6 UDP interface not created because IPv6 is not available, but required my Matter.`);
|
|
@@ -285,6 +288,8 @@ export class ServerNetworkRuntime extends NetworkRuntime {
|
|
|
285
288
|
maxPathsPerInvoke: this.owner.state.basicInformation.maxPathsPerInvoke,
|
|
286
289
|
};
|
|
287
290
|
|
|
291
|
+
await this.#initializeGroupNetworking();
|
|
292
|
+
|
|
288
293
|
// Install our interaction server
|
|
289
294
|
const interactionServer = new InteractionServer(this.owner, env.get(SessionManager));
|
|
290
295
|
env.set(InteractionServer, interactionServer);
|
|
@@ -359,6 +364,9 @@ export class ServerNetworkRuntime extends NetworkRuntime {
|
|
|
359
364
|
|
|
360
365
|
await this.owner.prepareRuntimeShutdown();
|
|
361
366
|
|
|
367
|
+
this.#groupNetworking?.close();
|
|
368
|
+
this.#groupNetworking = undefined;
|
|
369
|
+
|
|
362
370
|
// Now all sessions are closed, so we wait for Advertiser to be gone
|
|
363
371
|
await advertisementShutdown;
|
|
364
372
|
|
|
@@ -393,4 +401,18 @@ export class ServerNetworkRuntime extends NetworkRuntime {
|
|
|
393
401
|
agent.get(SubscriptionBehavior).reestablishFormerSubscriptions(env.get(InteractionServer)),
|
|
394
402
|
);
|
|
395
403
|
}
|
|
404
|
+
|
|
405
|
+
async #initializeGroupNetworking() {
|
|
406
|
+
if (this.#groupNetworking) {
|
|
407
|
+
logger.warn("Group networking already initialized, skipping.");
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
if (this.#ipv6UdpInterface === undefined) {
|
|
411
|
+
logger.warn("No IPv6 UDP interface available, skipping group networking initialization.");
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
this.#groupNetworking = new ServerGroupNetworking(this.owner.env, this.#ipv6UdpInterface);
|
|
416
|
+
await this.#groupNetworking.construction;
|
|
417
|
+
}
|
|
396
418
|
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import { EventEmitter, Observable } from "#general";
|
|
8
8
|
import type { ServerNode } from "#node/ServerNode.js";
|
|
9
|
-
import { ExposedFabricInformation,
|
|
9
|
+
import { ExposedFabricInformation, NodeSession, SessionManager, Subscription } from "#protocol";
|
|
10
10
|
import { NodeId } from "#types";
|
|
11
11
|
import { NodeLifecycle } from "../../../node/NodeLifecycle.js";
|
|
12
12
|
import { Behavior } from "../../Behavior.js";
|
|
@@ -28,7 +28,7 @@ export class SessionsBehavior extends Behavior {
|
|
|
28
28
|
this.reactTo((this.endpoint.lifecycle as NodeLifecycle).offline, this.#enterOfflineMode);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
#convertToExposedSession(session:
|
|
31
|
+
#convertToExposedSession(session: NodeSession): SessionsBehavior.Session {
|
|
32
32
|
return {
|
|
33
33
|
name: session.name,
|
|
34
34
|
nodeId: session.nodeId,
|
|
@@ -49,7 +49,7 @@ export class SessionsBehavior extends Behavior {
|
|
|
49
49
|
this.reactTo(sessions.subscriptionsChanged, this.#subscriptionsChanged, { lock: true });
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
#sessionOpened(session:
|
|
52
|
+
#sessionOpened(session: NodeSession) {
|
|
53
53
|
if (session.isPase) {
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
@@ -58,7 +58,7 @@ export class SessionsBehavior extends Behavior {
|
|
|
58
58
|
this.events.opened.emit(exposedSession);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
#sessionClosed(session:
|
|
61
|
+
#sessionClosed(session: NodeSession) {
|
|
62
62
|
if (!(session.id in this.state.sessions)) {
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
@@ -67,7 +67,7 @@ export class SessionsBehavior extends Behavior {
|
|
|
67
67
|
this.events.closed.emit(this.#convertToExposedSession(session));
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
#subscriptionsChanged(session:
|
|
70
|
+
#subscriptionsChanged(session: NodeSession, subscription: Subscription) {
|
|
71
71
|
if (session.isPase) {
|
|
72
72
|
return;
|
|
73
73
|
}
|
|
@@ -15,6 +15,8 @@ import {
|
|
|
15
15
|
AclEndpointContext,
|
|
16
16
|
FabricManager,
|
|
17
17
|
IncomingSubjectDescriptor,
|
|
18
|
+
NodeSession,
|
|
19
|
+
SecureSession,
|
|
18
20
|
} from "#protocol";
|
|
19
21
|
import {
|
|
20
22
|
CaseAuthenticatedTag,
|
|
@@ -159,7 +161,7 @@ export class AccessControlServer extends AccessControlBehavior.with("Extension")
|
|
|
159
161
|
|
|
160
162
|
if (subjects !== null) {
|
|
161
163
|
for (const subject of subjects) {
|
|
162
|
-
if (GroupId(subject) === GroupId.
|
|
164
|
+
if (GroupId(Number(subject)) === GroupId.NO_GROUP_ID) {
|
|
163
165
|
throw new StatusResponseError(
|
|
164
166
|
"Subject must be a valid GroupId for Group ACLs",
|
|
165
167
|
StatusCode.ConstraintError,
|
|
@@ -202,6 +204,21 @@ export class AccessControlServer extends AccessControlBehavior.with("Extension")
|
|
|
202
204
|
}
|
|
203
205
|
}
|
|
204
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Determine and return the adminPassCodeId and adminNodeId from the node that initiated the ACL change.
|
|
209
|
+
* it is either the root node of the fabric or 0 if the session is undefined or a PASE session.
|
|
210
|
+
*/
|
|
211
|
+
#adminDataFromSession(session: SecureSession | undefined) {
|
|
212
|
+
if (session === undefined || (NodeSession.is(session) && session.isPase)) {
|
|
213
|
+
return { adminPasscodeId: 0, adminNodeId: null };
|
|
214
|
+
}
|
|
215
|
+
const adminNodeId = session?.associatedFabric.rootNodeId;
|
|
216
|
+
if (adminNodeId === undefined) {
|
|
217
|
+
throw new InternalError("Admin Node ID is undefined, should never happen");
|
|
218
|
+
}
|
|
219
|
+
return { adminPasscodeId: null, adminNodeId };
|
|
220
|
+
}
|
|
221
|
+
|
|
205
222
|
#handleAccessControlListChange(
|
|
206
223
|
value: AccessControlTypes.AccessControlEntry[],
|
|
207
224
|
oldValue: AccessControlTypes.AccessControlEntry[],
|
|
@@ -218,12 +235,7 @@ export class AccessControlServer extends AccessControlBehavior.with("Extension")
|
|
|
218
235
|
if (relevantFabricIndex === undefined || this.events.accessControlEntryChanged === undefined) {
|
|
219
236
|
return;
|
|
220
237
|
}
|
|
221
|
-
const adminPasscodeId
|
|
222
|
-
const adminNodeId = adminPasscodeId === null ? session?.associatedFabric.rootNodeId : null;
|
|
223
|
-
if (adminNodeId === undefined) {
|
|
224
|
-
// Should never happen
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
238
|
+
const { adminPasscodeId, adminNodeId } = this.#adminDataFromSession(session);
|
|
227
239
|
const fabricAcls = value.filter(entry => entry.fabricIndex === relevantFabricIndex);
|
|
228
240
|
const oldFabricAcls = oldValue.filter(entry => entry.fabricIndex === relevantFabricIndex);
|
|
229
241
|
|
|
@@ -302,12 +314,7 @@ export class AccessControlServer extends AccessControlBehavior.with("Extension")
|
|
|
302
314
|
if (relevantFabricIndex === undefined || this.events.accessControlExtensionChanged === undefined) {
|
|
303
315
|
return;
|
|
304
316
|
}
|
|
305
|
-
const adminPasscodeId
|
|
306
|
-
const adminNodeId = adminPasscodeId === null ? session?.associatedFabric.rootNodeId : null;
|
|
307
|
-
if (adminNodeId === undefined) {
|
|
308
|
-
// Should never happen
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
317
|
+
const { adminPasscodeId, adminNodeId } = this.#adminDataFromSession(session);
|
|
311
318
|
|
|
312
319
|
const fabricExtensions = value.filter(entry => entry.fabricIndex === relevantFabricIndex);
|
|
313
320
|
const oldFabricExtensions = oldValue.filter(entry => entry.fabricIndex === relevantFabricIndex);
|
|
@@ -360,7 +367,7 @@ export class AccessControlServer extends AccessControlBehavior.with("Extension")
|
|
|
360
367
|
return [AccessLevel.View];
|
|
361
368
|
}
|
|
362
369
|
|
|
363
|
-
return this.aclManager.getGrantedPrivileges(context
|
|
370
|
+
return this.aclManager.getGrantedPrivileges(context, endpoint, location.cluster);
|
|
364
371
|
}
|
|
365
372
|
|
|
366
373
|
/**
|
|
@@ -4,15 +4,14 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { Behavior } from "#behavior/Behavior.js";
|
|
7
8
|
import { ActionContext } from "#behavior/context/ActionContext.js";
|
|
8
|
-
import { Behavior } from "#behavior/index.js";
|
|
9
9
|
import { Transitions } from "#behavior/Transitions.js";
|
|
10
10
|
import { GeneralDiagnosticsBehavior } from "#behaviors/general-diagnostics";
|
|
11
11
|
import { OnOffServer } from "#behaviors/on-off";
|
|
12
12
|
import { ColorControl } from "#clusters/color-control";
|
|
13
13
|
import { GeneralDiagnostics } from "#clusters/general-diagnostics";
|
|
14
14
|
import { Endpoint } from "#endpoint/Endpoint.js";
|
|
15
|
-
import { RootEndpoint } from "#endpoints/root";
|
|
16
15
|
import {
|
|
17
16
|
addValueWithOverflow,
|
|
18
17
|
AsyncObservable,
|
|
@@ -21,6 +20,7 @@ import {
|
|
|
21
20
|
Logger,
|
|
22
21
|
MaybePromise,
|
|
23
22
|
} from "#general";
|
|
23
|
+
import { ServerNode } from "#node/ServerNode.js";
|
|
24
24
|
import { Val } from "#protocol";
|
|
25
25
|
import { ClusterType, StatusCode, StatusResponseError, TypeFromPartialBitSchema } from "#types";
|
|
26
26
|
import { ColorControlBehavior } from "./ColorControlBehavior.js";
|
|
@@ -1726,8 +1726,8 @@ export class ColorControlBaseServer extends ColorControlBase {
|
|
|
1726
1726
|
}
|
|
1727
1727
|
|
|
1728
1728
|
#getBootReason() {
|
|
1729
|
-
const rootEndpoint = this.
|
|
1730
|
-
if (rootEndpoint
|
|
1729
|
+
const rootEndpoint = this.env.get(ServerNode);
|
|
1730
|
+
if (rootEndpoint.behaviors.has(GeneralDiagnosticsBehavior)) {
|
|
1731
1731
|
return rootEndpoint.stateOf(GeneralDiagnosticsBehavior).bootReason;
|
|
1732
1732
|
}
|
|
1733
1733
|
}
|
|
@@ -9,8 +9,8 @@ import { BasicInformationServer } from "#behaviors/basic-information";
|
|
|
9
9
|
import { AdministratorCommissioning } from "#clusters/administrator-commissioning";
|
|
10
10
|
import { GeneralCommissioning } from "#clusters/general-commissioning";
|
|
11
11
|
import { Logger, MatterFlowError, MaybePromise } from "#general";
|
|
12
|
-
import { ServerNode } from "#node/ServerNode.js";
|
|
13
|
-
import {
|
|
12
|
+
import type { ServerNode } from "#node/ServerNode.js";
|
|
13
|
+
import { DeviceCommissioner, FabricManager, GroupSession, NodeSession, SecureSession, SessionManager } from "#protocol";
|
|
14
14
|
import { GeneralCommissioningBehavior } from "./GeneralCommissioningBehavior.js";
|
|
15
15
|
import { ServerNodeFailsafeContext } from "./ServerNodeFailsafeContext.js";
|
|
16
16
|
|
|
@@ -45,7 +45,7 @@ export class GeneralCommissioningServer extends GeneralCommissioningBehavior {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/** As required by Commissioning Flows any new PASE session needs to arm the failsafe for 60s. */
|
|
48
|
-
async #handleAddedPaseSessions(session:
|
|
48
|
+
async #handleAddedPaseSessions(session: NodeSession) {
|
|
49
49
|
if (
|
|
50
50
|
!session.isPase || // Only PASE sessions
|
|
51
51
|
session.fabric !== undefined // That does not have an assigned fabric (can never happen in real usecases)
|
|
@@ -60,7 +60,7 @@ export class GeneralCommissioningServer extends GeneralCommissioningBehavior {
|
|
|
60
60
|
{ breadcrumb, expiryLengthSeconds }: GeneralCommissioning.ArmFailSafeRequest,
|
|
61
61
|
session: SecureSession,
|
|
62
62
|
) {
|
|
63
|
-
|
|
63
|
+
NodeSession.assert(session, "armFailSafe can only be called on a secure session");
|
|
64
64
|
const commissioner = this.env.get(DeviceCommissioner);
|
|
65
65
|
|
|
66
66
|
try {
|
|
@@ -195,10 +195,11 @@ export class GeneralCommissioningServer extends GeneralCommissioningBehavior {
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
override async commissioningComplete() {
|
|
198
|
-
|
|
198
|
+
const session = this.session;
|
|
199
|
+
if ((NodeSession.is(session) && session.isPase) || GroupSession.is(session)) {
|
|
199
200
|
return {
|
|
200
201
|
errorCode: GeneralCommissioning.CommissioningError.InvalidAuthentication,
|
|
201
|
-
debugText: "Command
|
|
202
|
+
debugText: "Command must be executed over CASE session.",
|
|
202
203
|
};
|
|
203
204
|
}
|
|
204
205
|
|
|
@@ -211,7 +212,7 @@ export class GeneralCommissioningServer extends GeneralCommissioningBehavior {
|
|
|
211
212
|
}
|
|
212
213
|
const failsafeContext = commissioner.failsafeContext;
|
|
213
214
|
|
|
214
|
-
|
|
215
|
+
SecureSession.assert(session, "commissioningComplete can only be called on a secure session");
|
|
215
216
|
|
|
216
217
|
const timedFabric = failsafeContext.associatedFabric?.fabricIndex;
|
|
217
218
|
if (fabric.fabricIndex !== timedFabric) {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { NetworkCommissioningBehavior } from "#behaviors/network-commissioning";
|
|
8
8
|
import { Endpoint } from "#endpoint/Endpoint.js";
|
|
9
9
|
import { Immutable, Lifecycle, UnsupportedDependencyError } from "#general";
|
|
10
|
-
import { ServerNode } from "#node/ServerNode.js";
|
|
10
|
+
import type { ServerNode } from "#node/ServerNode.js";
|
|
11
11
|
import { Fabric, FabricManager, FailsafeContext } from "#protocol";
|
|
12
12
|
|
|
13
13
|
/**
|