@matter/protocol 0.13.0-alpha.0-20250322-f085fa576 → 0.13.0-alpha.0-20250324-d7b7d9731
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/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/AttributeClient.d.ts +14 -4
- package/dist/cjs/cluster/client/AttributeClient.d.ts.map +1 -1
- package/dist/cjs/cluster/client/AttributeClient.js +24 -14
- package/dist/cjs/cluster/client/AttributeClient.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/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.js +1 -1
- 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/InteractionClient.d.ts +2 -2
- package/dist/cjs/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionClient.js +18 -20
- package/dist/cjs/interaction/InteractionClient.js.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.js +2 -2
- package/dist/cjs/interaction/InteractionMessenger.js.map +1 -1
- package/dist/cjs/interaction/InteractionServer.js +5 -5
- 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.map +1 -1
- package/dist/cjs/peer/ControllerCommissioner.js +1 -1
- package/dist/cjs/peer/ControllerCommissioner.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.js +5 -5
- 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/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.js +1 -1
- 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/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/AttributeClient.d.ts +14 -4
- package/dist/esm/cluster/client/AttributeClient.d.ts.map +1 -1
- package/dist/esm/cluster/client/AttributeClient.js +24 -14
- package/dist/esm/cluster/client/AttributeClient.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/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.js +1 -1
- 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/InteractionClient.d.ts +2 -2
- package/dist/esm/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionClient.js +19 -20
- package/dist/esm/interaction/InteractionClient.js.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.js +2 -2
- package/dist/esm/interaction/InteractionMessenger.js.map +1 -1
- package/dist/esm/interaction/InteractionServer.js +5 -5
- 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.map +1 -1
- package/dist/esm/peer/ControllerCommissioner.js +2 -1
- package/dist/esm/peer/ControllerCommissioner.js.map +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.js +16 -6
- 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/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/esm/protocol/ExchangeManager.js +2 -1
- package/dist/esm/protocol/ExchangeManager.js.map +1 -1
- package/package.json +6 -6
- package/src/ble/BtpSessionHandler.ts +2 -2
- package/src/certificate/CertificateManager.ts +22 -19
- package/src/cluster/client/AttributeClient.ts +24 -14
- package/src/cluster/server/AttributeServer.ts +15 -6
- package/src/cluster/server/CommandServer.ts +3 -3
- package/src/endpoint/EndpointStructureLogger.ts +1 -1
- package/src/events/OccurrenceManager.ts +3 -2
- package/src/interaction/AttributeDataDecoder.ts +1 -1
- package/src/interaction/AttributeDataEncoder.ts +4 -4
- package/src/interaction/InteractionClient.ts +21 -22
- package/src/interaction/InteractionMessenger.ts +2 -2
- package/src/interaction/InteractionServer.ts +5 -5
- package/src/interaction/ServerSubscription.ts +2 -1
- package/src/mdns/MdnsScanner.ts +2 -2
- package/src/peer/ControllerCommissioner.ts +3 -2
- package/src/peer/ControllerCommissioningFlow.ts +16 -6
- package/src/peer/ControllerDiscovery.ts +5 -5
- package/src/protocol/ExchangeManager.ts +2 -1
|
@@ -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
|
|
|
@@ -106,37 +106,47 @@ export class AttributeClient<T = any> {
|
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
/**
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Get the value of the attribute. Fabric scoped reads are always done with the remote.
|
|
111
|
+
* The `requestFromRemote` parameter allowed to force or prevent remote reads:
|
|
112
|
+
* - `true` forces a remote read
|
|
113
|
+
* - `false` forces a local read, return undefined if no value is available
|
|
114
|
+
* - `undefined` returns local values if available or if the read is fabric filtered, otherwise remote read
|
|
115
|
+
*/
|
|
116
|
+
async get(requestFromRemote?: boolean, isFabricFiltered = true) {
|
|
117
|
+
if (requestFromRemote === undefined) {
|
|
118
|
+
requestFromRemote = this.#isFabricScoped || !this.#updatedBySubscriptions ? true : undefined;
|
|
119
|
+
} else if (!requestFromRemote && this.#isFabricScoped) {
|
|
120
|
+
requestFromRemote = true;
|
|
115
121
|
}
|
|
116
122
|
return await this.#interactionClient.getAttribute({
|
|
117
123
|
endpointId: this.endpointId,
|
|
118
124
|
clusterId: this.clusterId,
|
|
119
125
|
attribute: this.attribute,
|
|
120
126
|
isFabricFiltered,
|
|
121
|
-
|
|
127
|
+
requestFromRemote,
|
|
122
128
|
});
|
|
123
129
|
}
|
|
124
130
|
|
|
125
131
|
/**
|
|
126
132
|
* Get the value with version of the attribute. Fabric scoped reads are always done with the remote.
|
|
127
|
-
*
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
+
* The `requestFromRemote` parameter allowed to force or prevent remote reads:
|
|
134
|
+
* - `true` forces a remote read
|
|
135
|
+
* - `false` forces a local read, return undefined if no value is available
|
|
136
|
+
* - `undefined` returns local values if available or if the read is fabric filtered, otherwise remote read
|
|
137
|
+
*/
|
|
138
|
+
async getWithVersion(requestFromRemote?: boolean, isFabricFiltered = true) {
|
|
139
|
+
if (requestFromRemote === undefined) {
|
|
140
|
+
requestFromRemote = this.#isFabricScoped || !this.#updatedBySubscriptions ? true : undefined;
|
|
141
|
+
} else if (!requestFromRemote && this.#isFabricScoped) {
|
|
142
|
+
requestFromRemote = true;
|
|
133
143
|
}
|
|
134
144
|
return await this.#interactionClient.getAttributeWithVersion({
|
|
135
145
|
endpointId: this.endpointId,
|
|
136
146
|
clusterId: this.clusterId,
|
|
137
147
|
attribute: this.attribute,
|
|
138
148
|
isFabricFiltered,
|
|
139
|
-
|
|
149
|
+
requestFromRemote,
|
|
140
150
|
});
|
|
141
151
|
}
|
|
142
152
|
|
|
@@ -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) {
|
|
@@ -107,7 +107,7 @@ export function expandPathsInAttributeData(
|
|
|
107
107
|
dataVersion: value.dataVersion,
|
|
108
108
|
};
|
|
109
109
|
} else if (!acceptWildcardPaths) {
|
|
110
|
-
throw new UnexpectedDataError("Tag compression disabled, but path is incomplete: " +
|
|
110
|
+
throw new UnexpectedDataError("Tag compression disabled, but path is incomplete: " + Diagnostic.json(path));
|
|
111
111
|
}
|
|
112
112
|
});
|
|
113
113
|
return data;
|
|
@@ -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,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
|
+
Diagnostic,
|
|
8
9
|
Environment,
|
|
9
10
|
Environmental,
|
|
10
11
|
ImplementationError,
|
|
@@ -376,13 +377,13 @@ export class InteractionClient {
|
|
|
376
377
|
clusterId: ClusterId;
|
|
377
378
|
attribute: A;
|
|
378
379
|
isFabricFiltered?: boolean;
|
|
379
|
-
|
|
380
|
+
requestFromRemote?: boolean;
|
|
380
381
|
executeQueued?: boolean;
|
|
381
382
|
}): Promise<AttributeJsType<A> | undefined> {
|
|
382
|
-
const {
|
|
383
|
+
const { requestFromRemote } = options;
|
|
383
384
|
const response = await this.getAttributeWithVersion({
|
|
384
385
|
...options,
|
|
385
|
-
|
|
386
|
+
requestFromRemote,
|
|
386
387
|
});
|
|
387
388
|
return response?.value;
|
|
388
389
|
}
|
|
@@ -392,22 +393,20 @@ export class InteractionClient {
|
|
|
392
393
|
clusterId: ClusterId;
|
|
393
394
|
attribute: A;
|
|
394
395
|
isFabricFiltered?: boolean;
|
|
395
|
-
|
|
396
|
+
requestFromRemote?: boolean;
|
|
396
397
|
executeQueued?: boolean;
|
|
397
398
|
}): Promise<{ value: AttributeJsType<A>; version: number } | undefined> {
|
|
398
|
-
const {
|
|
399
|
-
endpointId,
|
|
400
|
-
clusterId,
|
|
401
|
-
attribute,
|
|
402
|
-
alwaysRequestFromRemote = false,
|
|
403
|
-
isFabricFiltered,
|
|
404
|
-
executeQueued,
|
|
405
|
-
} = options;
|
|
399
|
+
const { endpointId, clusterId, attribute, requestFromRemote, isFabricFiltered, executeQueued } = options;
|
|
406
400
|
const { id: attributeId } = attribute;
|
|
407
|
-
if (
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
401
|
+
if (this.#nodeStore !== undefined) {
|
|
402
|
+
if (!requestFromRemote) {
|
|
403
|
+
const { value, version } = this.#nodeStore.retrieveAttribute(endpointId, clusterId, attributeId) ?? {};
|
|
404
|
+
if (value !== undefined && version !== undefined) {
|
|
405
|
+
return { value, version } as { value: AttributeJsType<A>; version: number };
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
if (requestFromRemote === false) {
|
|
409
|
+
return undefined;
|
|
411
410
|
}
|
|
412
411
|
}
|
|
413
412
|
|
|
@@ -549,7 +548,7 @@ export class InteractionClient {
|
|
|
549
548
|
`Sending write request: ${attributes
|
|
550
549
|
.map(
|
|
551
550
|
({ endpointId, clusterId, attribute: { id }, value, dataVersion }) =>
|
|
552
|
-
`${resolveAttributeName({ endpointId, clusterId, attributeId: id })} = ${
|
|
551
|
+
`${resolveAttributeName({ endpointId, clusterId, attributeId: id })} = ${Diagnostic.json(
|
|
553
552
|
value,
|
|
554
553
|
)} (version=${dataVersion})`,
|
|
555
554
|
)
|
|
@@ -973,7 +972,7 @@ export class InteractionClient {
|
|
|
973
972
|
let maxEventNumber = this.#nodeStore?.maxEventNumber ?? eventReports[0].events[0].eventNumber;
|
|
974
973
|
eventReports.forEach(data => {
|
|
975
974
|
logger.debug(
|
|
976
|
-
`Received event update: ${resolveEventName(data.path)}: ${
|
|
975
|
+
`Received event update: ${resolveEventName(data.path)}: ${Diagnostic.json(data.events)}`,
|
|
977
976
|
);
|
|
978
977
|
const { events } = data;
|
|
979
978
|
|
|
@@ -1001,7 +1000,7 @@ export class InteractionClient {
|
|
|
1001
1000
|
endpointId,
|
|
1002
1001
|
clusterId,
|
|
1003
1002
|
attributeId,
|
|
1004
|
-
})} = ${
|
|
1003
|
+
})} = ${Diagnostic.json(value)} (version=${version})`,
|
|
1005
1004
|
);
|
|
1006
1005
|
if (value === undefined) throw new MatterFlowError("Received empty subscription result value.");
|
|
1007
1006
|
const { value: oldValue } =
|
|
@@ -1091,7 +1090,7 @@ export class InteractionClient {
|
|
|
1091
1090
|
endpointId,
|
|
1092
1091
|
clusterId,
|
|
1093
1092
|
commandId: requestId,
|
|
1094
|
-
})} with ${
|
|
1093
|
+
})} with ${Diagnostic.json(request)}`,
|
|
1095
1094
|
);
|
|
1096
1095
|
|
|
1097
1096
|
if (!skipValidation) {
|
|
@@ -1160,7 +1159,7 @@ export class InteractionClient {
|
|
|
1160
1159
|
endpointId,
|
|
1161
1160
|
clusterId,
|
|
1162
1161
|
commandId: requestId,
|
|
1163
|
-
})} with ${
|
|
1162
|
+
})} with ${Diagnostic.json(response)})}`,
|
|
1164
1163
|
);
|
|
1165
1164
|
return response;
|
|
1166
1165
|
}
|
|
@@ -1196,7 +1195,7 @@ export class InteractionClient {
|
|
|
1196
1195
|
endpointId,
|
|
1197
1196
|
clusterId,
|
|
1198
1197
|
commandId: requestId,
|
|
1199
|
-
})} with ${
|
|
1198
|
+
})} with ${Diagnostic.json(request)}`,
|
|
1200
1199
|
);
|
|
1201
1200
|
const commandFields = requestSchema.encodeTlv(request);
|
|
1202
1201
|
|
|
@@ -633,7 +633,7 @@ export class InteractionServerMessenger extends InteractionMessenger {
|
|
|
633
633
|
const encodedMessage = TlvDataReportForSend.encode(dataReportToSend);
|
|
634
634
|
if (encodedMessage.length > this.exchange.maxPayloadSize) {
|
|
635
635
|
throw new MatterFlowError(
|
|
636
|
-
`DataReport with ${encodedMessage.length}bytes is too long to fit in a single chunk (${this.exchange.maxPayloadSize}bytes), This should not happen! Data: ${
|
|
636
|
+
`DataReport with ${encodedMessage.length}bytes is too long to fit in a single chunk (${this.exchange.maxPayloadSize}bytes), This should not happen! Data: ${Diagnostic.json(
|
|
637
637
|
dataReportToSend,
|
|
638
638
|
)}`,
|
|
639
639
|
);
|
|
@@ -856,7 +856,7 @@ export class InteractionClientMessenger extends IncomingInteractionClientMesseng
|
|
|
856
856
|
});
|
|
857
857
|
if (requestWithoutDataVersionFilters.length > this.exchange.maxPayloadSize) {
|
|
858
858
|
throw new MatterFlowError(
|
|
859
|
-
`Request is too long to fit in a single chunk, This should not happen! Data: ${
|
|
859
|
+
`Request is too long to fit in a single chunk, This should not happen! Data: ${Diagnostic.json(request)}`,
|
|
860
860
|
);
|
|
861
861
|
}
|
|
862
862
|
|
|
@@ -365,7 +365,7 @@ export class InteractionServer implements ProtocolHandler, InteractionRecipient
|
|
|
365
365
|
logger.debug(
|
|
366
366
|
`Read event from ${exchange.channel.name}: ${this.#endpointStructure.resolveEventName(
|
|
367
367
|
path,
|
|
368
|
-
)}=${
|
|
368
|
+
)}=${Diagnostic.json(matchingEvents)}`,
|
|
369
369
|
);
|
|
370
370
|
const { schema } = event;
|
|
371
371
|
reportsForPath.push(
|
|
@@ -523,7 +523,7 @@ export class InteractionServer implements ProtocolHandler, InteractionRecipient
|
|
|
523
523
|
logger.debug(
|
|
524
524
|
`Read attribute from ${exchange.channel.name}: ${this.#endpointStructure.resolveAttributeName(
|
|
525
525
|
path,
|
|
526
|
-
)}=${
|
|
526
|
+
)}=${Diagnostic.json(value)} (version=${version}) ignored because of dataVersionFilter`,
|
|
527
527
|
);
|
|
528
528
|
continue;
|
|
529
529
|
}
|
|
@@ -531,7 +531,7 @@ export class InteractionServer implements ProtocolHandler, InteractionRecipient
|
|
|
531
531
|
logger.debug(
|
|
532
532
|
`Read attribute from ${exchange.channel.name}: ${this.#endpointStructure.resolveAttributeName(
|
|
533
533
|
path,
|
|
534
|
-
)}=${
|
|
534
|
+
)}=${Diagnostic.json(value)} (version=${version})`,
|
|
535
535
|
);
|
|
536
536
|
|
|
537
537
|
const { schema } = attribute;
|
|
@@ -878,7 +878,7 @@ export class InteractionServer implements ProtocolHandler, InteractionRecipient
|
|
|
878
878
|
logger.debug(
|
|
879
879
|
`Handle write request from ${
|
|
880
880
|
exchange.channel.name
|
|
881
|
-
} resolved to: ${this.#endpointStructure.resolveAttributeName(path)}=${
|
|
881
|
+
} resolved to: ${this.#endpointStructure.resolveAttributeName(path)}=${Diagnostic.json(
|
|
882
882
|
value,
|
|
883
883
|
)} (listIndex=${listIndex}, for-version=${dataVersion})`,
|
|
884
884
|
);
|
|
@@ -960,7 +960,7 @@ export class InteractionServer implements ProtocolHandler, InteractionRecipient
|
|
|
960
960
|
? `with following errors: ${errorResults
|
|
961
961
|
.map(
|
|
962
962
|
({ path, statusCode }) =>
|
|
963
|
-
`${this.#endpointStructure.resolveAttributeName(path)}=${
|
|
963
|
+
`${this.#endpointStructure.resolveAttributeName(path)}=${Diagnostic.json(statusCode)}`,
|
|
964
964
|
)
|
|
965
965
|
.join(", ")}`
|
|
966
966
|
: "without errors"
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import { NumberedOccurrence } from "#events/Occurrence.js";
|
|
8
8
|
import {
|
|
9
|
+
Diagnostic,
|
|
9
10
|
InternalError,
|
|
10
11
|
Logger,
|
|
11
12
|
MatterAggregateError,
|
|
@@ -989,7 +990,7 @@ export class ServerSubscription extends Subscription {
|
|
|
989
990
|
`Subscription attribute changes for ID ${this.id}: ${attributes
|
|
990
991
|
.map(
|
|
991
992
|
({ path, value, version }) =>
|
|
992
|
-
`${this.#structure.resolveAttributeName(path)}=${
|
|
993
|
+
`${this.#structure.resolveAttributeName(path)}=${Diagnostic.json(value)} (${version})`,
|
|
993
994
|
)
|
|
994
995
|
.join(", ")}`,
|
|
995
996
|
); // TODO Format path better using endpoint structure
|
package/src/mdns/MdnsScanner.ts
CHANGED
|
@@ -213,7 +213,7 @@ export class MdnsScanner implements Scanner {
|
|
|
213
213
|
if (dnsMessageDataToSend.answers.length === 0) {
|
|
214
214
|
// The first answer is already too big, log at least a warning
|
|
215
215
|
logger.warn(
|
|
216
|
-
`MDNS Query with ${
|
|
216
|
+
`MDNS Query with ${Diagnostic.json(
|
|
217
217
|
queries,
|
|
218
218
|
)} is too big to fit into a single MDNS message. Send anyway, but please report!`,
|
|
219
219
|
);
|
|
@@ -265,7 +265,7 @@ export class MdnsScanner implements Scanner {
|
|
|
265
265
|
answers = this.#combineStructuredAnswers(activeExistingQuery.answers, answers);
|
|
266
266
|
}
|
|
267
267
|
this.#activeAnnounceQueries.set(queryId, { queries, answers });
|
|
268
|
-
logger.debug(`Set ${queries.length} query records for query ${queryId}: ${
|
|
268
|
+
logger.debug(`Set ${queries.length} query records for query ${queryId}: ${Diagnostic.json(queries)}`);
|
|
269
269
|
this.#queryTimer?.stop();
|
|
270
270
|
this.#nextAnnounceIntervalSeconds = START_ANNOUNCE_INTERVAL_SECONDS; // Reset query interval
|
|
271
271
|
this.#queryTimer = Time.getTimer("MDNS discovery", 0, () => this.#sendQueries()).start();
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
Channel,
|
|
13
13
|
ChannelType,
|
|
14
14
|
ClassExtends,
|
|
15
|
+
Diagnostic,
|
|
15
16
|
Environment,
|
|
16
17
|
Environmental,
|
|
17
18
|
isIPv6,
|
|
@@ -220,9 +221,9 @@ export class ControllerCommissioner {
|
|
|
220
221
|
const scannersToUse = this.#context.scanners.select(discoveryCapabilities);
|
|
221
222
|
|
|
222
223
|
logger.info(
|
|
223
|
-
`Connecting to device with identifier ${
|
|
224
|
+
`Connecting to device with identifier ${Diagnostic.json(identifierData)} and ${
|
|
224
225
|
scannersToUse.length
|
|
225
|
-
} scanners and knownAddress ${
|
|
226
|
+
} scanners and knownAddress ${Diagnostic.json(knownAddress)}`,
|
|
226
227
|
);
|
|
227
228
|
|
|
228
229
|
// If we have a known address we try this first before we discover the device
|