@matter/protocol 0.13.0-alpha.0-20250318-c1aa38b08 → 0.13.0-alpha.0-20250323-770919c6a
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/ble/BtpSessionHandler.js +2 -2
- package/dist/cjs/ble/BtpSessionHandler.js.map +1 -1
- package/dist/cjs/certificate/CertificateAuthority.d.ts +1 -0
- package/dist/cjs/certificate/CertificateAuthority.d.ts.map +1 -1
- package/dist/cjs/certificate/CertificateAuthority.js.map +1 -1
- package/dist/cjs/certificate/CertificateManager.d.ts.map +1 -1
- package/dist/cjs/certificate/CertificateManager.js +21 -19
- package/dist/cjs/certificate/CertificateManager.js.map +1 -1
- package/dist/cjs/cluster/client/ClusterClient.d.ts.map +1 -1
- package/dist/cjs/cluster/client/ClusterClient.js +3 -0
- package/dist/cjs/cluster/client/ClusterClient.js.map +1 -1
- package/dist/cjs/cluster/server/AttributeServer.d.ts.map +1 -1
- package/dist/cjs/cluster/server/AttributeServer.js +5 -5
- package/dist/cjs/cluster/server/AttributeServer.js.map +1 -1
- package/dist/cjs/cluster/server/CommandServer.js +2 -2
- package/dist/cjs/cluster/server/CommandServer.js.map +1 -1
- package/dist/cjs/common/FailsafeContext.js +1 -1
- package/dist/cjs/common/FailsafeContext.js.map +1 -1
- package/dist/cjs/endpoint/EndpointStructureLogger.js +1 -1
- package/dist/cjs/endpoint/EndpointStructureLogger.js.map +1 -1
- package/dist/cjs/events/OccurrenceManager.d.ts.map +1 -1
- package/dist/cjs/events/OccurrenceManager.js +2 -2
- package/dist/cjs/events/OccurrenceManager.js.map +1 -1
- package/dist/cjs/interaction/AttributeDataDecoder.d.ts +21 -4
- package/dist/cjs/interaction/AttributeDataDecoder.d.ts.map +1 -1
- package/dist/cjs/interaction/AttributeDataDecoder.js +41 -2
- package/dist/cjs/interaction/AttributeDataDecoder.js.map +1 -1
- package/dist/cjs/interaction/AttributeDataEncoder.d.ts.map +1 -1
- package/dist/cjs/interaction/AttributeDataEncoder.js +3 -3
- package/dist/cjs/interaction/AttributeDataEncoder.js.map +1 -1
- package/dist/cjs/interaction/DecodedDataReport.d.ts +4 -2
- package/dist/cjs/interaction/DecodedDataReport.d.ts.map +1 -1
- package/dist/cjs/interaction/DecodedDataReport.js +6 -2
- package/dist/cjs/interaction/DecodedDataReport.js.map +1 -1
- package/dist/cjs/interaction/EventDataDecoder.d.ts +15 -3
- package/dist/cjs/interaction/EventDataDecoder.d.ts.map +1 -1
- package/dist/cjs/interaction/EventDataDecoder.js +39 -2
- package/dist/cjs/interaction/EventDataDecoder.js.map +1 -1
- package/dist/cjs/interaction/InteractionClient.d.ts +44 -4
- package/dist/cjs/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionClient.js +71 -18
- package/dist/cjs/interaction/InteractionClient.js.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.js +7 -4
- package/dist/cjs/interaction/InteractionMessenger.js.map +1 -1
- package/dist/cjs/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionServer.js +7 -7
- package/dist/cjs/interaction/InteractionServer.js.map +1 -1
- package/dist/cjs/interaction/ServerSubscription.d.ts.map +1 -1
- package/dist/cjs/interaction/ServerSubscription.js +1 -1
- package/dist/cjs/interaction/ServerSubscription.js.map +1 -1
- package/dist/cjs/mdns/MdnsScanner.js +2 -2
- package/dist/cjs/mdns/MdnsScanner.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioner.d.ts +15 -3
- package/dist/cjs/peer/ControllerCommissioner.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerCommissioner.js +17 -6
- package/dist/cjs/peer/ControllerCommissioner.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.d.ts +47 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.js +136 -136
- package/dist/cjs/peer/ControllerCommissioningFlow.js.map +1 -1
- package/dist/cjs/peer/ControllerDiscovery.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerDiscovery.js +4 -4
- package/dist/cjs/peer/ControllerDiscovery.js.map +1 -1
- package/dist/cjs/peer/PeerSet.d.ts +2 -2
- package/dist/cjs/peer/PeerSet.d.ts.map +1 -1
- package/dist/cjs/peer/PeerSet.js +6 -1
- package/dist/cjs/peer/PeerSet.js.map +1 -1
- package/dist/cjs/protocol/ChannelManager.d.ts.map +1 -1
- package/dist/cjs/protocol/ChannelManager.js +11 -4
- package/dist/cjs/protocol/ChannelManager.js.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.js +1 -2
- package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
- package/dist/esm/ble/BtpSessionHandler.js +2 -2
- package/dist/esm/ble/BtpSessionHandler.js.map +1 -1
- package/dist/esm/certificate/CertificateAuthority.d.ts +1 -0
- package/dist/esm/certificate/CertificateAuthority.d.ts.map +1 -1
- package/dist/esm/certificate/CertificateAuthority.js.map +1 -1
- package/dist/esm/certificate/CertificateManager.d.ts.map +1 -1
- package/dist/esm/certificate/CertificateManager.js +22 -19
- package/dist/esm/certificate/CertificateManager.js.map +1 -1
- package/dist/esm/cluster/client/ClusterClient.d.ts.map +1 -1
- package/dist/esm/cluster/client/ClusterClient.js +3 -0
- package/dist/esm/cluster/client/ClusterClient.js.map +1 -1
- package/dist/esm/cluster/server/AttributeServer.d.ts.map +1 -1
- package/dist/esm/cluster/server/AttributeServer.js +15 -6
- package/dist/esm/cluster/server/AttributeServer.js.map +1 -1
- package/dist/esm/cluster/server/CommandServer.js +3 -3
- package/dist/esm/cluster/server/CommandServer.js.map +1 -1
- package/dist/esm/common/FailsafeContext.js +1 -1
- package/dist/esm/common/FailsafeContext.js.map +1 -1
- package/dist/esm/endpoint/EndpointStructureLogger.js +1 -1
- package/dist/esm/endpoint/EndpointStructureLogger.js.map +1 -1
- package/dist/esm/events/OccurrenceManager.d.ts.map +1 -1
- package/dist/esm/events/OccurrenceManager.js +3 -2
- package/dist/esm/events/OccurrenceManager.js.map +1 -1
- package/dist/esm/interaction/AttributeDataDecoder.d.ts +21 -4
- package/dist/esm/interaction/AttributeDataDecoder.d.ts.map +1 -1
- package/dist/esm/interaction/AttributeDataDecoder.js +41 -2
- package/dist/esm/interaction/AttributeDataDecoder.js.map +1 -1
- package/dist/esm/interaction/AttributeDataEncoder.d.ts.map +1 -1
- package/dist/esm/interaction/AttributeDataEncoder.js +4 -4
- package/dist/esm/interaction/AttributeDataEncoder.js.map +1 -1
- package/dist/esm/interaction/DecodedDataReport.d.ts +4 -2
- package/dist/esm/interaction/DecodedDataReport.d.ts.map +1 -1
- package/dist/esm/interaction/DecodedDataReport.js +12 -4
- package/dist/esm/interaction/DecodedDataReport.js.map +1 -1
- package/dist/esm/interaction/EventDataDecoder.d.ts +15 -3
- package/dist/esm/interaction/EventDataDecoder.d.ts.map +1 -1
- package/dist/esm/interaction/EventDataDecoder.js +39 -2
- package/dist/esm/interaction/EventDataDecoder.js.map +1 -1
- package/dist/esm/interaction/InteractionClient.d.ts +44 -4
- package/dist/esm/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionClient.js +74 -18
- package/dist/esm/interaction/InteractionClient.js.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.js +8 -4
- package/dist/esm/interaction/InteractionMessenger.js.map +1 -1
- package/dist/esm/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionServer.js +17 -8
- package/dist/esm/interaction/InteractionServer.js.map +1 -1
- package/dist/esm/interaction/ServerSubscription.d.ts.map +1 -1
- package/dist/esm/interaction/ServerSubscription.js +2 -1
- package/dist/esm/interaction/ServerSubscription.js.map +1 -1
- package/dist/esm/mdns/MdnsScanner.js +2 -2
- package/dist/esm/mdns/MdnsScanner.js.map +1 -1
- package/dist/esm/peer/ControllerCommissioner.d.ts +15 -3
- package/dist/esm/peer/ControllerCommissioner.d.ts.map +1 -1
- package/dist/esm/peer/ControllerCommissioner.js +18 -6
- package/dist/esm/peer/ControllerCommissioner.js.map +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.d.ts +47 -1
- package/dist/esm/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.js +147 -137
- package/dist/esm/peer/ControllerCommissioningFlow.js.map +1 -1
- package/dist/esm/peer/ControllerDiscovery.d.ts.map +1 -1
- package/dist/esm/peer/ControllerDiscovery.js +5 -5
- package/dist/esm/peer/ControllerDiscovery.js.map +1 -1
- package/dist/esm/peer/PeerSet.d.ts +2 -2
- package/dist/esm/peer/PeerSet.d.ts.map +1 -1
- package/dist/esm/peer/PeerSet.js +7 -2
- package/dist/esm/peer/PeerSet.js.map +1 -1
- package/dist/esm/protocol/ChannelManager.d.ts.map +1 -1
- package/dist/esm/protocol/ChannelManager.js +11 -4
- package/dist/esm/protocol/ChannelManager.js.map +1 -1
- package/dist/esm/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/esm/protocol/ExchangeManager.js +2 -2
- package/dist/esm/protocol/ExchangeManager.js.map +1 -1
- package/package.json +6 -6
- package/src/ble/BtpSessionHandler.ts +2 -2
- package/src/certificate/CertificateAuthority.ts +1 -0
- package/src/certificate/CertificateManager.ts +22 -19
- package/src/cluster/client/ClusterClient.ts +3 -0
- package/src/cluster/server/AttributeServer.ts +15 -6
- package/src/cluster/server/CommandServer.ts +3 -3
- package/src/common/FailsafeContext.ts +1 -1
- package/src/endpoint/EndpointStructureLogger.ts +1 -1
- package/src/events/OccurrenceManager.ts +3 -2
- package/src/interaction/AttributeDataDecoder.ts +67 -7
- package/src/interaction/AttributeDataEncoder.ts +4 -4
- package/src/interaction/DecodedDataReport.ts +24 -5
- package/src/interaction/EventDataDecoder.ts +57 -5
- package/src/interaction/InteractionClient.ts +112 -18
- package/src/interaction/InteractionMessenger.ts +8 -4
- package/src/interaction/InteractionServer.ts +19 -9
- package/src/interaction/ServerSubscription.ts +2 -1
- package/src/mdns/MdnsScanner.ts +2 -2
- package/src/peer/ControllerCommissioner.ts +32 -7
- package/src/peer/ControllerCommissioningFlow.ts +160 -146
- package/src/peer/ControllerDiscovery.ts +5 -5
- package/src/peer/PeerSet.ts +7 -2
- package/src/protocol/ChannelManager.ts +11 -4
- package/src/protocol/ExchangeManager.ts +2 -2
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
DerKey,
|
|
16
16
|
DerObject,
|
|
17
17
|
DerType,
|
|
18
|
+
Diagnostic,
|
|
18
19
|
ImplementationError,
|
|
19
20
|
Key,
|
|
20
21
|
Logger,
|
|
@@ -788,13 +789,13 @@ export namespace CertificateManager {
|
|
|
788
789
|
if (rootCert.subject.fabricId !== undefined) {
|
|
789
790
|
if (Array.isArray(rootCert.subject.fabricId)) {
|
|
790
791
|
throw new CertificateError(
|
|
791
|
-
`Invalid fabricId in NoC certificate: ${
|
|
792
|
+
`Invalid fabricId in NoC certificate: ${Diagnostic.json(rootCert.subject.fabricId)}`,
|
|
792
793
|
);
|
|
793
794
|
}
|
|
794
795
|
// If present, the matter-fabric-id attribute’s value SHALL NOT be 0
|
|
795
796
|
if (rootCert.subject.fabricId === FabricId(0)) {
|
|
796
797
|
throw new CertificateError(
|
|
797
|
-
`Invalid fabricId in NoC certificate: ${
|
|
798
|
+
`Invalid fabricId in NoC certificate: ${Diagnostic.json(rootCert.subject.fabricId)}`,
|
|
798
799
|
);
|
|
799
800
|
}
|
|
800
801
|
}
|
|
@@ -806,7 +807,9 @@ export namespace CertificateManager {
|
|
|
806
807
|
|
|
807
808
|
// The subject DN SHALL encode exactly one matter-rcac-id attribute.
|
|
808
809
|
if (rootCert.subject.rcacId === undefined || Array.isArray(rootCert.subject.rcacId)) {
|
|
809
|
-
throw new CertificateError(
|
|
810
|
+
throw new CertificateError(
|
|
811
|
+
`Invalid rcacId in Root certificate: ${Diagnostic.json(rootCert.subject.rcacId)}`,
|
|
812
|
+
);
|
|
810
813
|
}
|
|
811
814
|
|
|
812
815
|
// The subject DN SHALL NOT encode any matter-noc-cat attribute.
|
|
@@ -874,23 +877,23 @@ export namespace CertificateManager {
|
|
|
874
877
|
|
|
875
878
|
// The subject DN SHALL encode exactly one matter-node-id attribute.
|
|
876
879
|
if (nocCert.subject.nodeId === undefined || Array.isArray(nocCert.subject.nodeId)) {
|
|
877
|
-
throw new CertificateError(`Invalid nodeId in NoC certificate: ${
|
|
880
|
+
throw new CertificateError(`Invalid nodeId in NoC certificate: ${Diagnostic.json(nocCert.subject.nodeId)}`);
|
|
878
881
|
}
|
|
879
882
|
// The matter-node-id attribute’s value SHALL be in the Operational Node ID
|
|
880
883
|
if (!NodeId.isOperationalNodeId(nocCert.subject.nodeId)) {
|
|
881
|
-
throw new CertificateError(`Invalid nodeId in NoC certificate: ${
|
|
884
|
+
throw new CertificateError(`Invalid nodeId in NoC certificate: ${Diagnostic.json(nocCert.subject.nodeId)}`);
|
|
882
885
|
}
|
|
883
886
|
|
|
884
887
|
// The subject DN SHALL encode exactly one matter-fabric-id attribute.
|
|
885
888
|
if (nocCert.subject.fabricId === undefined || Array.isArray(nocCert.subject.fabricId)) {
|
|
886
889
|
throw new CertificateError(
|
|
887
|
-
`Invalid fabricId in NoC certificate: ${
|
|
890
|
+
`Invalid fabricId in NoC certificate: ${Diagnostic.json(nocCert.subject.fabricId)}`,
|
|
888
891
|
);
|
|
889
892
|
}
|
|
890
893
|
// The matter-fabric-id attribute’s value SHALL NOT be 0
|
|
891
894
|
if (nocCert.subject.fabricId === FabricId(0)) {
|
|
892
895
|
throw new CertificateError(
|
|
893
|
-
`Invalid fabricId in NoC certificate: ${
|
|
896
|
+
`Invalid fabricId in NoC certificate: ${Diagnostic.json(nocCert.subject.fabricId)}`,
|
|
894
897
|
);
|
|
895
898
|
}
|
|
896
899
|
|
|
@@ -914,9 +917,9 @@ export namespace CertificateManager {
|
|
|
914
917
|
// the same certificate chain.
|
|
915
918
|
if (rootCert.subject.fabricId !== undefined && rootCert.subject.fabricId !== nocCert.subject.fabricId) {
|
|
916
919
|
throw new CertificateError(
|
|
917
|
-
`FabricId in NoC certificate does not match the fabricId in the parent certificate. ${
|
|
920
|
+
`FabricId in NoC certificate does not match the fabricId in the parent certificate. ${Diagnostic.json(
|
|
918
921
|
rootCert.subject.fabricId,
|
|
919
|
-
)} !== ${
|
|
922
|
+
)} !== ${Diagnostic.json(nocCert.subject.fabricId)}`,
|
|
920
923
|
);
|
|
921
924
|
}
|
|
922
925
|
if (
|
|
@@ -925,9 +928,9 @@ export namespace CertificateManager {
|
|
|
925
928
|
icaCert.subject.fabricId !== nocCert.subject.fabricId
|
|
926
929
|
) {
|
|
927
930
|
throw new CertificateError(
|
|
928
|
-
`FabricId in NoC certificate does not match the fabricId in the parent certificate. ${
|
|
931
|
+
`FabricId in NoC certificate does not match the fabricId in the parent certificate. ${Diagnostic.json(
|
|
929
932
|
icaCert.subject.fabricId,
|
|
930
|
-
)} !== ${
|
|
933
|
+
)} !== ${Diagnostic.json(nocCert.subject.fabricId)}`,
|
|
931
934
|
);
|
|
932
935
|
}
|
|
933
936
|
|
|
@@ -950,7 +953,7 @@ export namespace CertificateManager {
|
|
|
950
953
|
(!nocCert.extensions.extendedKeyUsage.includes(1) && !nocCert.extensions.extendedKeyUsage.includes(2))
|
|
951
954
|
) {
|
|
952
955
|
throw new CertificateError(
|
|
953
|
-
`Noc certificate must have extendedKeyUsage with serverAuth and clientAuth: ${
|
|
956
|
+
`Noc certificate must have extendedKeyUsage with serverAuth and clientAuth: ${Diagnostic.json(nocCert.extensions.extendedKeyUsage)}`,
|
|
954
957
|
);
|
|
955
958
|
}
|
|
956
959
|
|
|
@@ -1005,20 +1008,20 @@ export namespace CertificateManager {
|
|
|
1005
1008
|
if (icaCert.subject.fabricId !== undefined) {
|
|
1006
1009
|
if (Array.isArray(icaCert.subject.fabricId)) {
|
|
1007
1010
|
throw new CertificateError(
|
|
1008
|
-
`Invalid fabricId in NoC certificate: ${
|
|
1011
|
+
`Invalid fabricId in NoC certificate: ${Diagnostic.json(icaCert.subject.fabricId)}`,
|
|
1009
1012
|
);
|
|
1010
1013
|
}
|
|
1011
1014
|
// If present, the matter-fabric-id attribute’s value SHALL NOT be 0
|
|
1012
1015
|
if (icaCert.subject.fabricId === FabricId(0)) {
|
|
1013
1016
|
throw new CertificateError(
|
|
1014
|
-
`Invalid fabricId in NoC certificate: ${
|
|
1017
|
+
`Invalid fabricId in NoC certificate: ${Diagnostic.json(icaCert.subject.fabricId)}`,
|
|
1015
1018
|
);
|
|
1016
1019
|
}
|
|
1017
1020
|
}
|
|
1018
1021
|
|
|
1019
1022
|
// The subject DN SHALL encode exactly one matter-icac-id attribute.
|
|
1020
1023
|
if (icaCert.subject.icacId === undefined || Array.isArray(icaCert.subject.icacId)) {
|
|
1021
|
-
throw new CertificateError(`Invalid icacId in Ica certificate: ${
|
|
1024
|
+
throw new CertificateError(`Invalid icacId in Ica certificate: ${Diagnostic.json(icaCert.subject.icacId)}`);
|
|
1022
1025
|
}
|
|
1023
1026
|
|
|
1024
1027
|
// The subject DN SHALL NOT encode any matter-rcac-id attribute.
|
|
@@ -1041,18 +1044,18 @@ export namespace CertificateManager {
|
|
|
1041
1044
|
rootCert.subject.fabricId !== icaCert.subject.fabricId
|
|
1042
1045
|
) {
|
|
1043
1046
|
throw new CertificateError(
|
|
1044
|
-
`FabricId in Ica certificate does not match the fabricId in the parent certificate. ${
|
|
1047
|
+
`FabricId in Ica certificate does not match the fabricId in the parent certificate. ${Diagnostic.json(
|
|
1045
1048
|
rootCert.subject.fabricId,
|
|
1046
|
-
)} !== ${
|
|
1049
|
+
)} !== ${Diagnostic.json(icaCert.subject.fabricId)}`,
|
|
1047
1050
|
);
|
|
1048
1051
|
}
|
|
1049
1052
|
|
|
1050
1053
|
// Verify the certificate chain by checking rcac ids in subject and issuer
|
|
1051
1054
|
if (rootCert.subject.rcacId !== icaCert.issuer.rcacId) {
|
|
1052
1055
|
throw new CertificateError(
|
|
1053
|
-
`RcacId in Ica certificate does not match the rcacId in the parent certificate. ${
|
|
1056
|
+
`RcacId in Ica certificate does not match the rcacId in the parent certificate. ${Diagnostic.json(
|
|
1054
1057
|
rootCert.subject.rcacId,
|
|
1055
|
-
)} !== ${
|
|
1058
|
+
)} !== ${Diagnostic.json(icaCert.issuer.rcacId)}`,
|
|
1056
1059
|
);
|
|
1057
1060
|
}
|
|
1058
1061
|
|
|
@@ -52,6 +52,7 @@ export function ClusterClient<const T extends ClusterType>(
|
|
|
52
52
|
interactionClient,
|
|
53
53
|
!!globalAttributeValues?.attributeList?.includes(attribute.id),
|
|
54
54
|
);
|
|
55
|
+
(attributes as any)[attribute.id] = (attributes as any)[attributeName];
|
|
55
56
|
attributeToId[attribute.id] = attributeName;
|
|
56
57
|
const capitalizedAttributeName = capitalize(attributeName);
|
|
57
58
|
result[`get${capitalizedAttributeName}Attribute`] = async (
|
|
@@ -94,6 +95,7 @@ export function ClusterClient<const T extends ClusterType>(
|
|
|
94
95
|
|
|
95
96
|
function addEventToResult(event: Event<any, any>, eventName: string) {
|
|
96
97
|
(events as any)[eventName] = createEventClient(event, eventName, endpointId, clusterId, interactionClient);
|
|
98
|
+
(events as any)[event.id] = (events as any)[eventName];
|
|
97
99
|
eventToId[event.id] = eventName;
|
|
98
100
|
const capitalizedEventName = capitalize(eventName);
|
|
99
101
|
result[`get${capitalizedEventName}Event`] = async (
|
|
@@ -316,6 +318,7 @@ export function ClusterClient<const T extends ClusterType>(
|
|
|
316
318
|
useExtendedFailSafeMessageResponseTimeout,
|
|
317
319
|
});
|
|
318
320
|
};
|
|
321
|
+
commands[requestId as unknown as keyof T["commands"]] = commands[commandName as keyof T["commands"]];
|
|
319
322
|
result[commandName] = result.commands[commandName];
|
|
320
323
|
}
|
|
321
324
|
if (globalAttributeValues?.acceptedCommandList !== undefined) {
|
|
@@ -4,7 +4,16 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
Diagnostic,
|
|
9
|
+
ImplementationError,
|
|
10
|
+
InternalError,
|
|
11
|
+
Logger,
|
|
12
|
+
MatterError,
|
|
13
|
+
MaybePromise,
|
|
14
|
+
camelize,
|
|
15
|
+
isDeepEqual,
|
|
16
|
+
} from "#general";
|
|
8
17
|
import { AccessLevel, AttributeModel, ClusterModel, DatatypeModel, FabricIndex, MatterModel } from "#model";
|
|
9
18
|
import {
|
|
10
19
|
Attribute,
|
|
@@ -165,9 +174,9 @@ export abstract class BaseAttributeServer<T> {
|
|
|
165
174
|
this.value = initValue;
|
|
166
175
|
} catch (error) {
|
|
167
176
|
logger.warn(
|
|
168
|
-
`Attribute value to initialize for ${name} has an invalid value ${
|
|
177
|
+
`Attribute value to initialize for ${name} has an invalid value ${Diagnostic.json(
|
|
169
178
|
initValue,
|
|
170
|
-
)}. Restore to default ${
|
|
179
|
+
)}. Restore to default ${Diagnostic.json(defaultValue)}`,
|
|
171
180
|
);
|
|
172
181
|
if (defaultValue === undefined) {
|
|
173
182
|
throw new ImplementationError(`Attribute value to initialize for ${name} cannot be undefined.`);
|
|
@@ -524,7 +533,7 @@ export class AttributeServer<T> extends FixedAttributeServer<T> {
|
|
|
524
533
|
newValue: value,
|
|
525
534
|
changed: !!this.delayedChangeData?.changed || valueChanged, // We combine the changed flag
|
|
526
535
|
};
|
|
527
|
-
logger.info(`Delay change for attribute "${this.name}" with value ${
|
|
536
|
+
logger.info(`Delay change for attribute "${this.name}" with value ${Diagnostic.json(value)}`);
|
|
528
537
|
} else {
|
|
529
538
|
this.handleVersionAndTriggerListeners(value, oldValue, valueChanged);
|
|
530
539
|
}
|
|
@@ -534,7 +543,7 @@ export class AttributeServer<T> extends FixedAttributeServer<T> {
|
|
|
534
543
|
if (this.delayedChangeData !== undefined) {
|
|
535
544
|
const { oldValue, newValue, changed } = this.delayedChangeData;
|
|
536
545
|
this.delayedChangeData = undefined;
|
|
537
|
-
logger.info(`Trigger delayed change for attribute "${this.name}" with value ${
|
|
546
|
+
logger.info(`Trigger delayed change for attribute "${this.name}" with value ${Diagnostic.json(newValue)}`);
|
|
538
547
|
this.handleVersionAndTriggerListeners(newValue, oldValue, changed);
|
|
539
548
|
}
|
|
540
549
|
}
|
|
@@ -909,7 +918,7 @@ export class FabricScopedAttributeServer<T> extends AttributeServer<T> {
|
|
|
909
918
|
() => !preserveFabricIndex, // No one should send any index and if we simply SHALL ignore it, but internally we might need it
|
|
910
919
|
);
|
|
911
920
|
logger.info(
|
|
912
|
-
`Set remote value for fabric scoped attribute "${this.name}" to ${
|
|
921
|
+
`Set remote value for fabric scoped attribute "${this.name}" to ${Diagnostic.json(value)} (delayed=${delayChangeEvents})`,
|
|
913
922
|
);
|
|
914
923
|
|
|
915
924
|
super.setRemote(value, session, message, delayChangeEvents);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { Logger } from "#general";
|
|
7
|
+
import { Diagnostic, Logger } from "#general";
|
|
8
8
|
import { AccessLevel, FabricIndex } from "#model";
|
|
9
9
|
import { CommandId, StatusCode, TlvSchema, TlvStream } from "#types";
|
|
10
10
|
import { Message } from "../../codec/MessageCodec.js";
|
|
@@ -69,9 +69,9 @@ export class CommandServer<RequestT = any, ResponseT = any> {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
this.requestSchema.validate(request);
|
|
72
|
-
this.debug(`Invoke ${this.name} with data ${
|
|
72
|
+
this.debug(`Invoke ${this.name} with data ${Diagnostic.json(request)}`);
|
|
73
73
|
const response = await this.handler(request, session, message, endpoint);
|
|
74
|
-
this.debug(`Invoke ${this.name} response : ${
|
|
74
|
+
this.debug(`Invoke ${this.name} response : ${Diagnostic.json(response)}`);
|
|
75
75
|
return {
|
|
76
76
|
code: StatusCode.Success,
|
|
77
77
|
responseId: this.responseId,
|
|
@@ -52,7 +52,7 @@ function getAttributeServerValue(attribute: AnyAttributeServer<any>, options: En
|
|
|
52
52
|
attributeValue !== null &&
|
|
53
53
|
options.logAttributeObjectValues !== false
|
|
54
54
|
) {
|
|
55
|
-
value =
|
|
55
|
+
value = Diagnostic.json(attributeValue);
|
|
56
56
|
}
|
|
57
57
|
} catch (error) {
|
|
58
58
|
if (error instanceof FabricScopeError) {
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import {
|
|
8
8
|
asyncNew,
|
|
9
9
|
Construction,
|
|
10
|
+
Diagnostic,
|
|
10
11
|
ImplementationError,
|
|
11
12
|
isObject,
|
|
12
13
|
Logger,
|
|
@@ -151,7 +152,7 @@ export class OccurrenceManager {
|
|
|
151
152
|
|
|
152
153
|
// TODO - log after fabric filtering and include fabric filter in log message?
|
|
153
154
|
logger.debug(
|
|
154
|
-
`Got ${occurrences.length} events for ${resolveEventName(eventPath)} with filters: ${
|
|
155
|
+
`Got ${occurrences.length} events for ${resolveEventName(eventPath)} with filters: ${Diagnostic.json(filters)}`,
|
|
155
156
|
);
|
|
156
157
|
|
|
157
158
|
// Convert from MaybePromise[] to MaybePromise<[]>
|
|
@@ -210,7 +211,7 @@ export class OccurrenceManager {
|
|
|
210
211
|
|
|
211
212
|
add(occurrence: Occurrence): MaybePromise<NumberedOccurrence> {
|
|
212
213
|
return MaybePromise.then(this.#store.add(occurrence), entry => {
|
|
213
|
-
logger.debug(`Recorded event #${entry.number}: ${
|
|
214
|
+
logger.debug(`Recorded event #${entry.number}: ${Diagnostic.json(occurrence)}`);
|
|
214
215
|
this.#occurrences[occurrence.priority].push(entry);
|
|
215
216
|
this.#storedEventCount++;
|
|
216
217
|
if (this.#storedEventCount > this.#bufferConfig.maxEventAllowance) {
|
|
@@ -16,17 +16,18 @@ import {
|
|
|
16
16
|
getClusterAttributeById,
|
|
17
17
|
getClusterById,
|
|
18
18
|
NodeId,
|
|
19
|
+
Status,
|
|
19
20
|
TlvAny,
|
|
20
21
|
TlvAttributeData,
|
|
21
22
|
TlvAttributeReport,
|
|
23
|
+
TlvAttributeStatus,
|
|
22
24
|
TlvSchema,
|
|
23
25
|
TypeFromSchema,
|
|
24
26
|
} from "#types";
|
|
25
27
|
|
|
26
28
|
const logger = Logger.get("AttributeDataDecoder");
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
export type DecodedAttributeReportValue<T> = {
|
|
30
|
+
type DecodedAttributeReportEntry = {
|
|
30
31
|
path: {
|
|
31
32
|
nodeId?: NodeId;
|
|
32
33
|
endpointId: EndpointNumber;
|
|
@@ -34,10 +35,20 @@ export type DecodedAttributeReportValue<T> = {
|
|
|
34
35
|
attributeId: AttributeId;
|
|
35
36
|
attributeName: string;
|
|
36
37
|
};
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/** Represents a fully qualified and decoded attribute value from a received DataReport */
|
|
41
|
+
export type DecodedAttributeReportValue<T> = DecodedAttributeReportEntry & {
|
|
37
42
|
version: number;
|
|
38
43
|
value: T;
|
|
39
44
|
};
|
|
40
45
|
|
|
46
|
+
/** Represents a fully qualified and decoded attribute status from a received DataReport */
|
|
47
|
+
export type DecodedAttributeReportStatus = DecodedAttributeReportEntry & {
|
|
48
|
+
status?: Status;
|
|
49
|
+
clusterStatus?: number;
|
|
50
|
+
};
|
|
51
|
+
|
|
41
52
|
/** Represents a decoded attribute value from a received DataReport where data version could be optional. */
|
|
42
53
|
export type DecodedAttributeValue<T> = Omit<DecodedAttributeReportValue<T>, "version"> & {
|
|
43
54
|
version?: number;
|
|
@@ -46,14 +57,20 @@ export type DecodedAttributeValue<T> = Omit<DecodedAttributeReportValue<T>, "ver
|
|
|
46
57
|
/**
|
|
47
58
|
* Parses, normalizes (e.g. un-chunk arrays and resolve Tag compression if used) and decodes the attribute data from
|
|
48
59
|
* a received DataReport.
|
|
60
|
+
* TODO: Convert into a Generator function once we migrate Reading Data for controller to also be streaming
|
|
49
61
|
*/
|
|
50
|
-
export function normalizeAndDecodeReadAttributeReport(
|
|
51
|
-
|
|
52
|
-
|
|
62
|
+
export function normalizeAndDecodeReadAttributeReport(data: TypeFromSchema<typeof TlvAttributeReport>[]): {
|
|
63
|
+
attributeData: DecodedAttributeReportValue<any>[];
|
|
64
|
+
attributeStatus: DecodedAttributeReportStatus[];
|
|
65
|
+
} {
|
|
53
66
|
// TODO Decide how to handle the attribute report status field, right now we ignore it
|
|
54
67
|
const dataValues = data.flatMap(({ attributeData }) => (attributeData !== undefined ? attributeData : []));
|
|
68
|
+
const dataStatus = data.flatMap(({ attributeStatus }) => (attributeStatus !== undefined ? attributeStatus : []));
|
|
55
69
|
|
|
56
|
-
return
|
|
70
|
+
return {
|
|
71
|
+
attributeData: normalizeAndDecodeAttributeData(dataValues) as DecodedAttributeReportValue<any>[],
|
|
72
|
+
attributeStatus: normalizeAttributeStatus(dataStatus),
|
|
73
|
+
};
|
|
57
74
|
}
|
|
58
75
|
|
|
59
76
|
export function expandPathsInAttributeData(
|
|
@@ -90,7 +107,7 @@ export function expandPathsInAttributeData(
|
|
|
90
107
|
dataVersion: value.dataVersion,
|
|
91
108
|
};
|
|
92
109
|
} else if (!acceptWildcardPaths) {
|
|
93
|
-
throw new UnexpectedDataError("Tag compression disabled, but path is incomplete: " +
|
|
110
|
+
throw new UnexpectedDataError("Tag compression disabled, but path is incomplete: " + Diagnostic.json(path));
|
|
94
111
|
}
|
|
95
112
|
});
|
|
96
113
|
return data;
|
|
@@ -121,6 +138,49 @@ export function normalizeAttributeData(
|
|
|
121
138
|
return Array.from(responseList.values());
|
|
122
139
|
}
|
|
123
140
|
|
|
141
|
+
/**
|
|
142
|
+
* Normalizes (e.g. un-chunk arrays and resolve Tag compression if used) and decodes the attribute data from a received
|
|
143
|
+
* DataReport.
|
|
144
|
+
*/
|
|
145
|
+
export function normalizeAttributeStatus(
|
|
146
|
+
data: TypeFromSchema<typeof TlvAttributeStatus>[],
|
|
147
|
+
): DecodedAttributeReportStatus[] {
|
|
148
|
+
const result = new Array<DecodedAttributeReportStatus>();
|
|
149
|
+
data.forEach(entry => {
|
|
150
|
+
const {
|
|
151
|
+
path: { nodeId, endpointId, clusterId, attributeId },
|
|
152
|
+
status,
|
|
153
|
+
} = entry;
|
|
154
|
+
|
|
155
|
+
if (endpointId === undefined || clusterId === undefined || attributeId === undefined) {
|
|
156
|
+
throw new UnexpectedDataError(`Invalid attribute path ${endpointId}/${clusterId}/${attributeId}`);
|
|
157
|
+
}
|
|
158
|
+
const cluster = getClusterById(clusterId);
|
|
159
|
+
const attributeDetail = getClusterAttributeById(cluster, attributeId);
|
|
160
|
+
if (attributeDetail === undefined) {
|
|
161
|
+
result.push({
|
|
162
|
+
path: {
|
|
163
|
+
nodeId,
|
|
164
|
+
endpointId,
|
|
165
|
+
clusterId,
|
|
166
|
+
attributeId,
|
|
167
|
+
attributeName: `Unknown (${Diagnostic.hex(attributeId)})`,
|
|
168
|
+
},
|
|
169
|
+
status: status.status,
|
|
170
|
+
clusterStatus: status.clusterStatus,
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
result.push({
|
|
176
|
+
path: { nodeId, endpointId, clusterId, attributeId, attributeName: attributeDetail.name },
|
|
177
|
+
status: status.status,
|
|
178
|
+
clusterStatus: status.clusterStatus,
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
|
|
124
184
|
/**
|
|
125
185
|
* Normalizes (e.g. un-chunk arrays and resolve Tag compression if used) and decodes the attribute data from a received
|
|
126
186
|
* DataReport.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Copyright 2022-2025 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import { Diagnostic, MatterFlowError } from "#general";
|
|
7
7
|
import {
|
|
8
8
|
ArraySchema,
|
|
9
9
|
AttributeId,
|
|
@@ -77,7 +77,7 @@ export function encodeAttributePayloadData(
|
|
|
77
77
|
const { attributeData } = attributePayload;
|
|
78
78
|
if (attributeData === undefined) {
|
|
79
79
|
throw new MatterFlowError(
|
|
80
|
-
`Cannot encode Attribute Payload data with just a attributeStatus: ${
|
|
80
|
+
`Cannot encode Attribute Payload data with just a attributeStatus: ${Diagnostic.json(attributePayload)}`,
|
|
81
81
|
);
|
|
82
82
|
}
|
|
83
83
|
|
|
@@ -152,13 +152,13 @@ export function chunkAttributePayload(attributePayload: AttributeReportPayload):
|
|
|
152
152
|
const { hasFabricSensitiveData, attributeData } = attributePayload;
|
|
153
153
|
if (attributeData === undefined) {
|
|
154
154
|
throw new MatterFlowError(
|
|
155
|
-
`Cannot chunk an AttributePayload with just a attributeStatus: ${
|
|
155
|
+
`Cannot chunk an AttributePayload with just a attributeStatus: ${Diagnostic.json(attributePayload)}`,
|
|
156
156
|
);
|
|
157
157
|
}
|
|
158
158
|
const { schema, path, dataVersion, payload } = attributeData;
|
|
159
159
|
if (!(schema instanceof ArraySchema) || !Array.isArray(payload)) {
|
|
160
160
|
throw new MatterFlowError(
|
|
161
|
-
`Cannot chunk an AttributePayload with attributeData that is not an array: ${
|
|
161
|
+
`Cannot chunk an AttributePayload with attributeData that is not an array: ${Diagnostic.json(
|
|
162
162
|
attributePayload,
|
|
163
163
|
)}`,
|
|
164
164
|
);
|
|
@@ -5,13 +5,23 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { DataReport } from "#types";
|
|
8
|
-
import {
|
|
9
|
-
|
|
8
|
+
import {
|
|
9
|
+
DecodedAttributeReportStatus,
|
|
10
|
+
DecodedAttributeReportValue,
|
|
11
|
+
normalizeAndDecodeReadAttributeReport,
|
|
12
|
+
} from "./AttributeDataDecoder.js";
|
|
13
|
+
import {
|
|
14
|
+
DecodedEventReportStatus,
|
|
15
|
+
DecodedEventReportValue,
|
|
16
|
+
normalizeAndDecodeReadEventReport,
|
|
17
|
+
} from "./EventDataDecoder.js";
|
|
10
18
|
|
|
11
19
|
export interface DecodedDataReport extends DataReport {
|
|
12
20
|
isNormalized: true;
|
|
13
21
|
attributeReports: DecodedAttributeReportValue<any>[];
|
|
22
|
+
attributeStatus?: DecodedAttributeReportStatus[];
|
|
14
23
|
eventReports: DecodedEventReportValue<any>[];
|
|
24
|
+
eventStatus?: DecodedEventReportStatus[];
|
|
15
25
|
}
|
|
16
26
|
|
|
17
27
|
export function DecodedDataReport(report: DataReport): DecodedDataReport {
|
|
@@ -19,11 +29,20 @@ export function DecodedDataReport(report: DataReport): DecodedDataReport {
|
|
|
19
29
|
return report as DecodedDataReport;
|
|
20
30
|
}
|
|
21
31
|
|
|
32
|
+
const { attributeData: attributeReports, attributeStatus } =
|
|
33
|
+
report.attributeReports === undefined
|
|
34
|
+
? { attributeData: [] }
|
|
35
|
+
: normalizeAndDecodeReadAttributeReport(report.attributeReports);
|
|
36
|
+
|
|
37
|
+
const { eventData: eventReports, eventStatus } =
|
|
38
|
+
report.eventReports === undefined ? { eventData: [] } : normalizeAndDecodeReadEventReport(report.eventReports);
|
|
39
|
+
|
|
22
40
|
return {
|
|
23
41
|
...report,
|
|
24
42
|
isNormalized: true,
|
|
25
|
-
attributeReports
|
|
26
|
-
|
|
27
|
-
eventReports
|
|
43
|
+
attributeReports,
|
|
44
|
+
attributeStatus,
|
|
45
|
+
eventReports,
|
|
46
|
+
eventStatus,
|
|
28
47
|
};
|
|
29
48
|
}
|
|
@@ -14,9 +14,11 @@ import {
|
|
|
14
14
|
getClusterById,
|
|
15
15
|
getClusterEventById,
|
|
16
16
|
NodeId,
|
|
17
|
+
Status,
|
|
17
18
|
TlvAny,
|
|
18
19
|
TlvEventData,
|
|
19
20
|
TlvEventReport,
|
|
21
|
+
TlvEventStatus,
|
|
20
22
|
TlvStream,
|
|
21
23
|
TypeFromSchema,
|
|
22
24
|
} from "#types";
|
|
@@ -33,7 +35,7 @@ export type DecodedEventData<T> = {
|
|
|
33
35
|
data?: T;
|
|
34
36
|
};
|
|
35
37
|
|
|
36
|
-
export type
|
|
38
|
+
export type DecodedEventReportEntry = {
|
|
37
39
|
path: {
|
|
38
40
|
nodeId?: NodeId;
|
|
39
41
|
endpointId: EndpointNumber;
|
|
@@ -41,16 +43,32 @@ export type DecodedEventReportValue<T> = {
|
|
|
41
43
|
eventId: EventId;
|
|
42
44
|
eventName: string;
|
|
43
45
|
};
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/** Represents a fully qualified and decoded attribute value from a received DataReport */
|
|
49
|
+
export type DecodedEventReportValue<T> = DecodedEventReportEntry & {
|
|
44
50
|
events: DecodedEventData<T>[];
|
|
45
51
|
};
|
|
46
52
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
53
|
+
/** Represents a fully qualified and decoded attribute status from a received DataReport */
|
|
54
|
+
export type DecodedEventReportStatus = DecodedEventReportEntry & {
|
|
55
|
+
status?: Status;
|
|
56
|
+
clusterStatus?: number;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// TODO: Convert into a Generator function once we migrate Reading Data for controller to also be streaming
|
|
60
|
+
export function normalizeAndDecodeReadEventReport(data: TypeFromSchema<typeof TlvEventReport>[]): {
|
|
61
|
+
eventData: DecodedEventReportValue<any>[];
|
|
62
|
+
eventStatus: DecodedEventReportStatus[];
|
|
63
|
+
} {
|
|
50
64
|
// TODO Decide how to handle the attribute report status field, right now we ignore it
|
|
51
65
|
const dataValues = data.flatMap(({ eventData }) => (eventData !== undefined ? eventData : []));
|
|
66
|
+
const dataStatus = data.flatMap(({ eventStatus }) => (eventStatus !== undefined ? eventStatus : []));
|
|
52
67
|
|
|
53
|
-
return
|
|
68
|
+
return {
|
|
69
|
+
eventData: normalizeAndDecodeEventData(dataValues),
|
|
70
|
+
eventStatus: normalizeEventStatus(dataStatus),
|
|
71
|
+
};
|
|
54
72
|
}
|
|
55
73
|
|
|
56
74
|
export function normalizeEventData(
|
|
@@ -121,6 +139,40 @@ export function normalizeAndDecodeEventData(
|
|
|
121
139
|
return result;
|
|
122
140
|
}
|
|
123
141
|
|
|
142
|
+
export function normalizeEventStatus(data: TypeFromSchema<typeof TlvEventStatus>[]): DecodedEventReportStatus[] {
|
|
143
|
+
const result = new Array<DecodedEventReportStatus>();
|
|
144
|
+
data.forEach(entry => {
|
|
145
|
+
const {
|
|
146
|
+
path: { nodeId, endpointId, clusterId, eventId },
|
|
147
|
+
status,
|
|
148
|
+
} = entry;
|
|
149
|
+
|
|
150
|
+
if (endpointId === undefined || clusterId === undefined || eventId === undefined) {
|
|
151
|
+
throw new UnexpectedDataError(`Invalid event path ${endpointId}/${clusterId}/${eventId}`);
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
const cluster = getClusterById(clusterId);
|
|
155
|
+
const eventDetail = getClusterEventById(cluster, eventId);
|
|
156
|
+
if (eventDetail === undefined) {
|
|
157
|
+
result.push({
|
|
158
|
+
path: { nodeId, endpointId, clusterId, eventId, eventName: `Unknown (${Diagnostic.hex(eventId)})` },
|
|
159
|
+
status: status.status,
|
|
160
|
+
clusterStatus: status.clusterStatus,
|
|
161
|
+
});
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
result.push({
|
|
165
|
+
path: { nodeId, endpointId, clusterId, eventId, eventName: eventDetail.name },
|
|
166
|
+
status: status.status,
|
|
167
|
+
clusterStatus: status.clusterStatus,
|
|
168
|
+
});
|
|
169
|
+
} catch (error: any) {
|
|
170
|
+
logger.error(`Error decoding event ${endpointId}/${clusterId}/${eventId}: ${error.message}`);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
|
|
124
176
|
export function decodeUnknownEventValue(data: TlvStream): any {
|
|
125
177
|
const schema = TlvAny;
|
|
126
178
|
|