@project-chip/matter.js 0.1.0 → 0.2.1

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.
Files changed (37) hide show
  1. package/dist/cjs/cluster/DescriptorCluster.js +2 -2
  2. package/dist/cjs/cluster/OperationalCredentialsCluster.js +44 -55
  3. package/dist/cjs/schema/Schema.js +4 -2
  4. package/dist/cjs/tlv/TlvAny.js +10 -0
  5. package/dist/cjs/tlv/TlvArray.js +8 -6
  6. package/dist/cjs/tlv/TlvBoolean.js +4 -0
  7. package/dist/cjs/tlv/TlvNullable.js +4 -0
  8. package/dist/cjs/tlv/TlvNumber.js +10 -2
  9. package/dist/cjs/tlv/TlvObject.js +23 -4
  10. package/dist/cjs/tlv/TlvString.js +10 -5
  11. package/dist/cjs/tlv/TlvVoid.js +4 -0
  12. package/dist/dts/cluster/AccessControlCluster.d.ts +2 -2
  13. package/dist/dts/cluster/BasicInformationCluster.d.ts +2 -2
  14. package/dist/dts/cluster/BridgedDeviceBasicInformationCluster.d.ts +2 -2
  15. package/dist/dts/cluster/Cluster.d.ts +1 -1
  16. package/dist/dts/cluster/OperationalCredentialsCluster.d.ts +12 -20
  17. package/dist/dts/schema/Schema.d.ts +1 -1
  18. package/dist/dts/tlv/TlvAny.d.ts +1 -0
  19. package/dist/dts/tlv/TlvArray.d.ts +2 -2
  20. package/dist/dts/tlv/TlvBoolean.d.ts +1 -0
  21. package/dist/dts/tlv/TlvNullable.d.ts +1 -0
  22. package/dist/dts/tlv/TlvNumber.d.ts +2 -0
  23. package/dist/dts/tlv/TlvObject.d.ts +7 -2
  24. package/dist/dts/tlv/TlvString.d.ts +1 -1
  25. package/dist/dts/tlv/TlvVoid.d.ts +1 -0
  26. package/dist/es/cluster/DescriptorCluster.js +2 -2
  27. package/dist/es/cluster/OperationalCredentialsCluster.js +44 -55
  28. package/dist/es/schema/Schema.js +4 -2
  29. package/dist/es/tlv/TlvAny.js +10 -0
  30. package/dist/es/tlv/TlvArray.js +8 -6
  31. package/dist/es/tlv/TlvBoolean.js +4 -0
  32. package/dist/es/tlv/TlvNullable.js +4 -0
  33. package/dist/es/tlv/TlvNumber.js +10 -2
  34. package/dist/es/tlv/TlvObject.js +23 -4
  35. package/dist/es/tlv/TlvString.js +10 -5
  36. package/dist/es/tlv/TlvVoid.js +4 -0
  37. package/package.json +2 -2
@@ -43,11 +43,11 @@ exports.DescriptorCluster = (0, Cluster_js_1.Cluster)({
43
43
  /** List containing each cluster ID for the server clusters present on the endpoint instance. */
44
44
  serverList: (0, Cluster_js_1.Attribute)(1, (0, TlvArray_js_1.TlvArray)(ClusterId_js_1.TlvClusterId), { default: [] }),
45
45
  /** List containing each cluster ID for the client clusters present on the endpoint instance. */
46
- clientList: (0, Cluster_js_1.Attribute)(3, (0, TlvArray_js_1.TlvArray)(ClusterId_js_1.TlvClusterId), { default: [] }),
46
+ clientList: (0, Cluster_js_1.Attribute)(2, (0, TlvArray_js_1.TlvArray)(ClusterId_js_1.TlvClusterId), { default: [] }),
47
47
  /**
48
48
  * This indicates composition of the device type instance. Device type instance composition SHALL
49
49
  * include the endpoints in this list.
50
50
  */
51
- partsList: (0, Cluster_js_1.Attribute)(4, (0, TlvArray_js_1.TlvArray)(EndpointNumber_js_1.TlvEndpointNumber), { default: [] }),
51
+ partsList: (0, Cluster_js_1.Attribute)(3, (0, TlvArray_js_1.TlvArray)(EndpointNumber_js_1.TlvEndpointNumber), { default: [] }),
52
52
  },
53
53
  });
@@ -26,15 +26,15 @@ exports.RESP_MAX = 900;
26
26
  * @see {@link MatterCoreSpecificationV1_0} § 11.17.5.3
27
27
  */
28
28
  const TlvFabricDescriptor = (0, TlvObject_js_1.TlvObject)({
29
- /** Contains the public key for the trusted root that scopes the fabric referenced by FabricIndex and its associated operational credential. */
29
+ /** The public key for the trusted root that scopes the fabric referenced by FabricIndex and its associated operational credential. */
30
30
  rootPublicKey: (0, TlvObject_js_1.TlvField)(1, TlvString_js_1.TlvByteString.bound({ length: 65 })),
31
- /** Contains the value of AdminVendorID provided in the AddNOC command that led to the creation of this FabricDescriptorStruct. */
31
+ /** The value of AdminVendorID provided in the AddNOC command that led to the creation of this FabricDescriptorStruct. */
32
32
  vendorId: (0, TlvObject_js_1.TlvField)(2, VendorId_js_1.TlvVendorId),
33
- /** Contains the FabricID allocated to the fabric referenced by FabricIndex. */
34
- fabricID: (0, TlvObject_js_1.TlvField)(3, FabricId_js_1.TlvFabricId),
35
- /** Contain the NodeID in use within the fabric referenced by FabricIndex. */
36
- nodeID: (0, TlvObject_js_1.TlvField)(4, NodeId_js_1.TlvNodeId),
37
- /** Contains a commissioner-set label for the fabric referenced by FabricIndex. */
33
+ /** The FabricID allocated to the fabric referenced by FabricIndex. */
34
+ fabricId: (0, TlvObject_js_1.TlvField)(3, FabricId_js_1.TlvFabricId),
35
+ /** The NodeID in use within the fabric referenced by FabricIndex. */
36
+ nodeId: (0, TlvObject_js_1.TlvField)(4, NodeId_js_1.TlvNodeId),
37
+ /** A commissioner-set label for the fabric referenced by FabricIndex. */
38
38
  label: (0, TlvObject_js_1.TlvField)(5, TlvString_js_1.TlvString.bound({ maxLength: 32 })), /* default: "" */
39
39
  });
40
40
  /**
@@ -43,86 +43,83 @@ const TlvFabricDescriptor = (0, TlvObject_js_1.TlvObject)({
43
43
  * @see {@link MatterCoreSpecificationV1_0} § 11.17.5.2
44
44
  */
45
45
  const TlvNoc = (0, TlvObject_js_1.TlvObject)({
46
- /** Contains the NOC for the structs associated fabric. */
46
+ /** The NOC for the struct's associated fabric. */
47
47
  noc: (0, TlvObject_js_1.TlvField)(1, TlvString_js_1.TlvByteString.bound({ maxLength: 400 })),
48
- /** Contain the ICAC or the structs associated fabric. */
48
+ /** The ICAC or the struct's associated fabric. */
49
49
  icac: (0, TlvObject_js_1.TlvField)(2, (0, TlvNullable_js_1.TlvNullable)(TlvString_js_1.TlvByteString.bound({ maxLength: 400 }))), /* default(not present): null */
50
50
  });
51
51
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.1 */
52
52
  const TlvAttestationRequest = (0, TlvObject_js_1.TlvObject)({
53
- /** Contains the attestation nonce to be used in the computation of the Attestation Information. */
53
+ /** The attestation nonce to be used in the computation of the Attestation Information. */
54
54
  attestationNonce: (0, TlvObject_js_1.TlvField)(0, TlvString_js_1.TlvByteString.bound({ length: 32 })),
55
55
  });
56
56
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.2 */
57
57
  const TlvAttestationResponse = (0, TlvObject_js_1.TlvObject)({
58
- /** Contains the octet string of the serialized attestation_elements_message. */
58
+ /** The octet string of the serialized attestation_elements_message. */
59
59
  elements: (0, TlvObject_js_1.TlvField)(0, TlvString_js_1.TlvByteString.bound({ maxLength: exports.RESP_MAX })),
60
- /** Contain the octet string of the necessary attestation_signature. */
60
+ /** The octet string of the necessary attestation_signature. */
61
61
  signature: (0, TlvObject_js_1.TlvField)(1, TlvString_js_1.TlvByteString.bound({ length: 64 })),
62
62
  });
63
63
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.5 */
64
64
  const TlvCertSigningRequestRequest = (0, TlvObject_js_1.TlvObject)({
65
- /** Contains the CSRNonce to be used in the computation of the NOCSR information. */
65
+ /** The CSRNonce to be used in the computation of the NOCSR information. */
66
66
  certSigningRequestNonce: (0, TlvObject_js_1.TlvField)(0, TlvString_js_1.TlvByteString.bound({ length: 32 })),
67
67
  /**
68
68
  * If set to true, the internal state of the CSR associated keypair SHALL be tagged as being for
69
69
  * a subsequent UpdateNOC, otherwise the internal state of the CSR SHALL be tagged as being for a
70
- * subsequent AddNOC
70
+ * subsequent AddNOC.
71
71
  * */
72
72
  isForUpdateNOC: (0, TlvObject_js_1.TlvOptionalField)(1, TlvBoolean_js_1.TlvBoolean), /* default: false */
73
73
  });
74
74
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.6 */
75
75
  const TlvCertSigningRequestResponse = (0, TlvObject_js_1.TlvObject)({
76
- /** Contains the octet string of the serialized nocsr_elements_message. */
76
+ /** The octet string of the serialized nocsr_elements_message. */
77
77
  elements: (0, TlvObject_js_1.TlvField)(0, TlvString_js_1.TlvByteString.bound({ maxLength: exports.RESP_MAX })),
78
- /** Contain the octet string of the necessary attestation_signature. */
78
+ /** The octet string of the necessary attestation_signature. */
79
79
  signature: (0, TlvObject_js_1.TlvField)(1, TlvString_js_1.TlvByteString.bound({ length: 64 })),
80
80
  });
81
81
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.3 */
82
82
  const TlvCertChainRequest = (0, TlvObject_js_1.TlvObject)({
83
- /** Contains the type of certificate to be requested. */
83
+ /** The type of certificate to be requested. */
84
84
  type: (0, TlvObject_js_1.TlvField)(0, (0, TlvNumber_js_1.TlvEnum)()),
85
85
  });
86
86
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.4 */
87
87
  const TlvCertChainResponse = (0, TlvObject_js_1.TlvObject)({
88
- /** Contains the octet string of the requested certificate. */
88
+ /** The octet string of the requested certificate. */
89
89
  certificate: (0, TlvObject_js_1.TlvField)(0, TlvString_js_1.TlvByteString.bound({ maxLength: 600 })),
90
90
  });
91
91
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.8 */
92
92
  const TlvAddNocRequest = (0, TlvObject_js_1.TlvObject)({
93
- /** Contains the Node Operational Certificate (NOC) to be added. */
93
+ /** The Node Operational Certificate (NOC) to be added. */
94
94
  operationalCert: (0, TlvObject_js_1.TlvField)(0, TlvString_js_1.TlvByteString.bound({ maxLength: 400 })),
95
- /** Contains the Intermediate CA Certificate (ICAC). */
95
+ /** The Intermediate CA Certificate (ICAC). */
96
96
  intermediateCaCert: (0, TlvObject_js_1.TlvOptionalField)(1, TlvString_js_1.TlvByteString.bound({ maxLength: 400 })),
97
- /** Contains the value of the Epoch Key for the Identity Protection Key (IPK) to set for the Fabric which is to be added. */
97
+ /** The value of the Epoch Key for the Identity Protection Key (IPK). */
98
98
  identityProtectionKey: (0, TlvObject_js_1.TlvField)(2, TlvString_js_1.TlvByteString.bound({ length: 16 })),
99
- /**
100
- * Used to atomically add an Access Control Entry enabling that Subject to subsequently administer
101
- * the Node whose operational identity is being added by this command.
102
- */
99
+ /** That Subject will have administration access on this node. */
103
100
  caseAdminNode: (0, TlvObject_js_1.TlvField)(3, SubjectId_js_1.TlvSubjectId),
104
- /** Contains the Vendor ID of the entity issuing the AddNOC command. */
101
+ /** The Vendor ID of the entity issuing the AddNOC command. */
105
102
  adminVendorId: (0, TlvObject_js_1.TlvField)(4, VendorId_js_1.TlvVendorId),
106
103
  });
107
104
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.9 */
108
105
  const TlvUpdateNocRequest = (0, TlvObject_js_1.TlvObject)({
109
- /** Contains the Node Operational Certificate (NOC). */
106
+ /** The Node Operational Certificate (NOC). */
110
107
  operationalCert: (0, TlvObject_js_1.TlvField)(0, TlvString_js_1.TlvByteString.bound({ maxLength: 400 })),
111
- /** Contains the Intermediate CA Certificate (ICAC). */
108
+ /** The Intermediate CA Certificate (ICAC). */
112
109
  intermediateCaCert: (0, TlvObject_js_1.TlvOptionalField)(1, TlvString_js_1.TlvByteString.bound({ maxLength: 400 })),
113
110
  });
114
111
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.13 */
115
112
  const TlvAddTrustedRootCertificateRequest = (0, TlvObject_js_1.TlvObject)({
116
- /** Contains the Trusted Root Certificate (TRC) to be added. */
113
+ /** The Trusted Root Certificate (TRC) to be added. */
117
114
  certificate: (0, TlvObject_js_1.TlvField)(0, TlvString_js_1.TlvByteString.bound({ maxLength: 400 })),
118
115
  });
119
116
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.10 */
120
117
  const TlvOperationalCertificateStatusResponse = (0, TlvObject_js_1.TlvObject)({
121
- /** Contains a NOCStatus value representing the status of an operation involving a NOC. */
118
+ /** A NOCStatus value representing the status of an operation involving a NOC. */
122
119
  status: (0, TlvObject_js_1.TlvField)(0, (0, TlvNumber_js_1.TlvEnum)()),
123
120
  /** When action was successful, contains the Fabric Index of the Fabric last added, removed or updated. */
124
121
  fabricIndex: (0, TlvObject_js_1.TlvOptionalField)(1, FabricIndex_js_1.TlvFabricIndex),
125
- /** Optionally contains debugging textual information from the cluster implementation and should be visible in logs, not User UI */
122
+ /** Optional debugging textual information from the cluster implementation and should be visible in logs, not User UI */
126
123
  debugText: (0, TlvObject_js_1.TlvOptionalField)(2, TlvString_js_1.TlvString.bound({ maxLength: 128 })),
127
124
  });
128
125
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.5.4 */
@@ -142,12 +139,12 @@ exports.TlvCertSigningRequest = (0, TlvObject_js_1.TlvObject)({
142
139
  });
143
140
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.11 */
144
141
  const TlvUpdateFabricLabelRequest = (0, TlvObject_js_1.TlvObject)({
145
- /** Contains the label to set for the fabric associated with the current secure session. */
142
+ /** The label to set for the fabric associated with the current secure session. */
146
143
  label: (0, TlvObject_js_1.TlvField)(0, TlvString_js_1.TlvString32max),
147
144
  });
148
145
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.12 */
149
146
  const TlvRemoveFabricRequest = (0, TlvObject_js_1.TlvObject)({
150
- /** Contains the Fabric Index reference associated with the Fabric which is to be removed from the device. */
147
+ /** The Fabric Index reference associated with the Fabric which is to be removed from the device. */
151
148
  fabricIndex: (0, TlvObject_js_1.TlvField)(0, FabricIndex_js_1.TlvFabricIndex),
152
149
  });
153
150
  /**
@@ -162,44 +159,36 @@ exports.OperationalCredentialsCluster = (0, Cluster_js_1.Cluster)({
162
159
  revision: 1,
163
160
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.6 */
164
161
  attributes: {
165
- /** Contains all NOCs applicable to this Node. */
162
+ /** All NOCs applicable to this Node. */
166
163
  nocs: (0, Cluster_js_1.Attribute)(0, (0, TlvArray_js_1.TlvArray)(TlvNoc), { readAcl: 2 /* AccessLevel.Administer */ }),
167
- /** Describes all fabrics to which this Node is commissioned. */
164
+ /** Lists all fabrics to which this Node is commissioned. */
168
165
  fabrics: (0, Cluster_js_1.Attribute)(1, (0, TlvArray_js_1.TlvArray)(TlvFabricDescriptor)),
169
- /** Contains the number of Fabrics that are supported by the device. */
166
+ /** The number of Fabrics that are supported by the device. */
170
167
  supportedFabrics: (0, Cluster_js_1.Attribute)(2, TlvNumber_js_1.TlvUInt8.bound({ min: 5, max: 254 })),
171
- /** Contains the number of Fabrics to which the device is currently commissioned. */
168
+ /** The number of Fabrics to which the device is currently commissioned. */
172
169
  commissionedFabrics: (0, Cluster_js_1.Attribute)(3, TlvNumber_js_1.TlvUInt8),
173
- /** Contains a read-only list of Trusted Root CA Certificates installed on the Node. */
170
+ /** A read-only list of Trusted Root CA Certificates installed on the Node. */
174
171
  trustedRootCertificates: (0, Cluster_js_1.Attribute)(4, (0, TlvArray_js_1.TlvArray)(TlvString_js_1.TlvByteString, { maxLength: 400 })),
175
- /** Contain accessing fabric index. */
172
+ /** Accessing fabric index. */
176
173
  currentFabricIndex: (0, Cluster_js_1.Attribute)(5, TlvNumber_js_1.TlvUInt8),
177
174
  },
178
175
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7 */
179
176
  commands: {
180
- /** Sender is requesting attestation information from the receiver. */
177
+ /** Requests attestation information. */
181
178
  requestAttestation: (0, Cluster_js_1.Command)(0, TlvAttestationRequest, 1, TlvAttestationResponse),
182
- /** Sender is requesting a device attestation certificate from the receiver. */
179
+ /** Requests a device attestation certificate. */
183
180
  requestCertChain: (0, Cluster_js_1.Command)(2, TlvCertChainRequest, 3, TlvCertChainResponse),
184
- /** Sender is requesting a certificate signing request (CSR) from the receiver. */
181
+ /** Requests a certificate signing request (CSR). */
185
182
  requestCertSigning: (0, Cluster_js_1.Command)(4, TlvCertSigningRequestRequest, 5, TlvCertSigningRequestResponse),
186
- /** Sender is requesting to add the new node operational certificates. */
183
+ /** Adds new node operational certificates. */
187
184
  addOperationalCert: (0, Cluster_js_1.Command)(6, TlvAddNocRequest, 8, TlvOperationalCertificateStatusResponse),
188
- /** Sender is requesting to update the node operational certificates. */
185
+ /** Updates the node operational certificates. */
189
186
  updateOperationalCert: (0, Cluster_js_1.Command)(7, TlvUpdateNocRequest, 8, TlvOperationalCertificateStatusResponse),
190
- /**
191
- * This command SHALL be used by an Administrative Node to set the user-visible Label field for a given
192
- * Fabric, as reflected by entries in the Fabrics attribute.
193
- */
187
+ /** Sets the user-visible Label field for a given Fabric. */
194
188
  updateFabricLabel: (0, Cluster_js_1.Command)(9, TlvUpdateFabricLabelRequest, 8, TlvOperationalCertificateStatusResponse),
195
- /**
196
- * This command is used by Administrative Nodes to remove a given fabric index and delete all associated
197
- * fabric-scoped data.
198
- */
189
+ /** Removes a given fabric index and delete all associated fabric-scoped data. */
199
190
  removeFabric: (0, Cluster_js_1.Command)(10, TlvRemoveFabricRequest, 8, TlvOperationalCertificateStatusResponse),
200
- /**
201
- * This command SHALL add a Trusted Root CA Certificate, provided as its CHIP Certificate representation.
202
- */
191
+ /** Adds a Trusted Root CA Certificate, provided as its CHIP Certificate representation. */
203
192
  addRootCert: (0, Cluster_js_1.Command)(11, TlvAddTrustedRootCertificateRequest, 11, Cluster_js_1.TlvNoResponse),
204
193
  },
205
194
  });
@@ -14,9 +14,11 @@ class Schema {
14
14
  return this.encodeInternal(value);
15
15
  }
16
16
  /** Decodes the encoded data using the schema. */
17
- decode(encoded) {
17
+ decode(encoded, validate = true) {
18
18
  const result = this.decodeInternal(encoded);
19
- this.validate(result);
19
+ if (validate) {
20
+ this.validate(result);
21
+ }
20
22
  return result;
21
23
  }
22
24
  /** Optional validator that can be used to enforce constraints on the data before encoding / after decoding. */
@@ -66,6 +66,16 @@ class AnySchema extends TlvSchema_js_1.TlvSchema {
66
66
  }
67
67
  return tlvStream;
68
68
  }
69
+ validate(tlvStream) {
70
+ if (!Array.isArray(tlvStream))
71
+ throw new Error(`Expected TlvStream, got ${typeof tlvStream}.`);
72
+ tlvStream.forEach(({ typeLength }) => {
73
+ if (!typeLength || typeof typeLength !== "object")
74
+ throw new Error(`Expected typeLength properties in TlvStream, got ${typeof typeLength}.`);
75
+ if (typeof typeLength.type !== "number")
76
+ throw new Error(`Expected typeLength.type as number in TlvStream, got ${typeof typeLength.type}.`);
77
+ });
78
+ }
69
79
  }
70
80
  exports.AnySchema = AnySchema;
71
81
  exports.TlvAny = new AnySchema();
@@ -36,14 +36,16 @@ class ArraySchema extends TlvSchema_js_1.TlvSchema {
36
36
  break;
37
37
  result.push(this.elementSchema.decodeTlvInternalValue(reader, elementTypeLength));
38
38
  }
39
- this.validate(result);
40
39
  return result;
41
40
  }
42
- validate({ length }) {
43
- if (length > this.maxLength)
44
- throw new Error(`Array is too long: ${length}, max ${this.maxLength}.`);
45
- if (length < this.minLength)
46
- throw new Error(`Array is too short: ${length}, min ${this.minLength}.`);
41
+ validate(data) {
42
+ if (!Array.isArray(data))
43
+ throw new Error(`Expected array, got ${typeof data}.`);
44
+ if (data.length > this.maxLength)
45
+ throw new Error(`Array is too long: ${data.length}, max ${this.maxLength}.`);
46
+ if (data.length < this.minLength)
47
+ throw new Error(`Array is too short: ${data.length}, min ${this.minLength}.`);
48
+ data.forEach(element => this.elementSchema.validate(element));
47
49
  }
48
50
  }
49
51
  exports.ArraySchema = ArraySchema;
@@ -21,6 +21,10 @@ class BooleanSchema extends TlvSchema_js_1.TlvSchema {
21
21
  throw new Error(`Unexpected type ${typeLength.type}.`);
22
22
  return typeLength.value;
23
23
  }
24
+ validate(value) {
25
+ if (typeof value !== "boolean")
26
+ throw new Error(`Expected boolean, got ${typeof value}.`);
27
+ }
24
28
  }
25
29
  exports.BooleanSchema = BooleanSchema;
26
30
  /** Boolean TLV schema. */
@@ -30,6 +30,10 @@ class NullableSchema extends TlvSchema_js_1.TlvSchema {
30
30
  return null;
31
31
  return this.schema.decodeTlvInternalValue(reader, typeLength);
32
32
  }
33
+ validate(value) {
34
+ if (value !== null)
35
+ this.schema.validate(value);
36
+ }
33
37
  }
34
38
  exports.NullableSchema = NullableSchema;
35
39
  /** Nullable TLV schema. */
@@ -33,11 +33,14 @@ class TlvNumericSchema extends TlvSchema_js_1.TlvSchema {
33
33
  if (typeLength.type !== this.type)
34
34
  throw new Error(`Unexpected type ${typeLength.type}, was expecting ${this.type}.`);
35
35
  const value = reader.readPrimitive(typeLength);
36
- this.validate(value);
37
36
  return value;
38
37
  }
39
38
  validate(value) {
40
- super.validate(value);
39
+ if (typeof value !== "number" && typeof value !== 'bigint')
40
+ throw new Error(`Expected number, got ${typeof value}.`);
41
+ this.validateBoundaries(value);
42
+ }
43
+ validateBoundaries(value) {
41
44
  if (this.min !== undefined && value < this.min)
42
45
  throw new Error(`Invalid value: ${value} is below the minimum, ${this.min}.`);
43
46
  if (this.max !== undefined && value > this.max)
@@ -60,6 +63,11 @@ class TlvNumberSchema extends TlvNumericSchema {
60
63
  bound({ min, max }) {
61
64
  return new TlvNumberSchema(this.type, this.lengthProvider, (0, Number_js_1.maxValue)(min, this.min), (0, Number_js_1.minValue)(max, this.max));
62
65
  }
66
+ validate(value) {
67
+ if (typeof value !== "number")
68
+ throw new Error(`Expected number, got ${typeof value}.`);
69
+ this.validateBoundaries(value);
70
+ }
63
71
  }
64
72
  exports.TlvNumberSchema = TlvNumberSchema;
65
73
  exports.TlvLongNumberSchema = (TlvNumericSchema);
@@ -60,13 +60,28 @@ class ObjectSchema extends TlvSchema_js_1.TlvSchema {
60
60
  const { field, name } = fieldName;
61
61
  result[name] = field.schema.decodeTlvInternalValue(reader, elementTypeLength);
62
62
  }
63
- this.validate(result);
63
+ // Check mandatory fields and, if missing, populate with fallback value if defined.
64
+ for (const name in this.fieldDefinitions) {
65
+ const { optional, fallback } = this.fieldDefinitions[name];
66
+ if (optional)
67
+ continue;
68
+ const value = result[name];
69
+ if (value !== undefined)
70
+ continue;
71
+ if (fallback === undefined)
72
+ throw new Error(`Missing mandatory field ${name}`);
73
+ result[name] = fallback;
74
+ }
64
75
  return result;
65
76
  }
66
77
  validate(value) {
67
78
  for (const name in this.fieldDefinitions) {
68
- if (!this.fieldDefinitions[name].optional && value[name] === undefined)
79
+ const { optional, schema } = this.fieldDefinitions[name];
80
+ if (optional && value[name] === undefined)
81
+ continue;
82
+ if (!optional && value[name] === undefined)
69
83
  throw new Error(`Missing mandatory field ${name}`);
84
+ schema.validate(value[name]);
70
85
  }
71
86
  }
72
87
  }
@@ -77,8 +92,12 @@ exports.TlvObject = TlvObject;
77
92
  /** List TLV schema. */
78
93
  const TlvList = (fields) => new ObjectSchema(fields, 23 /* TlvType.List */);
79
94
  exports.TlvList = TlvList;
80
- /** Object TLV mandatory field. */
81
- const TlvField = (id, schema) => ({ id, schema, optional: false });
95
+ /**
96
+ * Object TLV mandatory field. Optionally provide a fallback value to initialize the field value when devices omit
97
+ * providing a value against the specifications or in special usecases. Make sure to use a value that is an equivalent
98
+ * to the value being empty.
99
+ */
100
+ const TlvField = (id, schema, fallback) => ({ id, schema, fallback, optional: false });
82
101
  exports.TlvField = TlvField;
83
102
  /** Object TLV optional field. */
84
103
  const TlvOptionalField = (id, schema) => ({ id, schema, optional: true });
@@ -9,6 +9,7 @@ exports.TlvString256max = exports.TlvString64max = exports.TlvString32max = expo
9
9
  const TlvCodec_js_1 = require("./TlvCodec.js");
10
10
  const TlvSchema_js_1 = require("./TlvSchema.js");
11
11
  const Number_js_1 = require("../util/Number.js");
12
+ const ByteArray_1 = require("../util/ByteArray");
12
13
  /**
13
14
  * Schema to encode an byte string or an Utf8 string in TLV.
14
15
  *
@@ -33,11 +34,15 @@ class StringSchema extends TlvSchema_js_1.TlvSchema {
33
34
  throw new Error(`Unexpected type ${typeLength.type}.`);
34
35
  return reader.readPrimitive(typeLength);
35
36
  }
36
- validate({ length }) {
37
- if (length > this.maxLength)
38
- throw new Error(`Array is too long: ${length}, max ${this.maxLength}.`);
39
- if (length < this.minLength)
40
- throw new Error(`Array is too short: ${length}, min ${this.minLength}.`);
37
+ validate(value) {
38
+ if (this.type === 12 /* TlvType.Utf8String */ && typeof value !== "string")
39
+ throw new Error(`Expected string, got ${typeof value}.`);
40
+ if (this.type === 16 /* TlvType.ByteString */ && !(value instanceof ByteArray_1.ByteArray))
41
+ throw new Error(`Expected ByteArray, got ${typeof value}.`);
42
+ if (value.length > this.maxLength)
43
+ throw new Error(`String is too long: ${value.length}, max ${this.maxLength}.`);
44
+ if (value.length < this.minLength)
45
+ throw new Error(`String is too short: ${value.length}, min ${this.minLength}.`);
41
46
  }
42
47
  bound({ minLength, maxLength, length }) {
43
48
  return new StringSchema(this.type, length !== null && length !== void 0 ? length : (0, Number_js_1.maxValue)(this.minLength, minLength), length !== null && length !== void 0 ? length : (0, Number_js_1.minValue)(this.maxLength, maxLength));
@@ -20,6 +20,10 @@ class VoidSchema extends TlvSchema_js_1.TlvSchema {
20
20
  decodeTlvInternalValue(_reader, _typeLength) {
21
21
  throw new Error("decodeTlvInternalValue should never be called");
22
22
  }
23
+ validate(data) {
24
+ if (data !== undefined)
25
+ throw new Error(`Expected void, got ${typeof data}.`);
26
+ }
23
27
  }
24
28
  exports.VoidSchema = VoidSchema;
25
29
  /** Void TLV schema. */
@@ -3,7 +3,7 @@
3
3
  * Copyright 2022 Project CHIP Authors
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { Cluster, WritableAttribute, Attribute, Event } from "./Cluster.js";
6
+ import { Cluster, WritableAttribute, Attribute, Event, OptionalWritableAttribute } from "./Cluster.js";
7
7
  /**
8
8
  * List of privileges that can be granted to a subject.
9
9
  *
@@ -65,7 +65,7 @@ export declare const AccessControlCluster: Cluster<import("../matter.js").BitSch
65
65
  deviceType: import("../common/DeviceTypeId.js").DeviceTypeId | null;
66
66
  }[] | null;
67
67
  }[]>;
68
- extension: WritableAttribute<{
68
+ extension: OptionalWritableAttribute<{
69
69
  data: Uint8Array;
70
70
  }[]>;
71
71
  subjectsPerAccessControlEntry: Attribute<number>;
@@ -3,7 +3,7 @@
3
3
  * Copyright 2022 Project CHIP Authors
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { Attribute, Cluster, Event, OptionalAttribute, WritableAttribute } from "./Cluster.js";
6
+ import { Attribute, Cluster, Event, OptionalAttribute, OptionalWritableAttribute, WritableAttribute } from "./Cluster.js";
7
7
  /**
8
8
  * This cluster provides attributes and events for determining basic information about Nodes, which supports both
9
9
  * commissioning and operational determination of Node characteristics, such as Vendor ID, Product ID and serial number,
@@ -28,7 +28,7 @@ export declare const BasicInformationCluster: Cluster<import("../matter.js").Bit
28
28
  productURL: OptionalAttribute<string>;
29
29
  productLabel: OptionalAttribute<string>;
30
30
  serialNumber: OptionalAttribute<string>;
31
- localConfigDisabled: WritableAttribute<boolean>;
31
+ localConfigDisabled: OptionalWritableAttribute<boolean>;
32
32
  reachable: OptionalAttribute<boolean>;
33
33
  uniqueId: OptionalAttribute<string>;
34
34
  capabilityMinima: Attribute<{
@@ -3,7 +3,7 @@
3
3
  * Copyright 2022 Project CHIP Authors
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { Attribute, Cluster, Event, OptionalAttribute } from "./Cluster.js";
6
+ import { Attribute, Cluster, Event, OptionalAttribute, OptionalWritableAttribute } from "./Cluster.js";
7
7
  /**
8
8
  * This Cluster serves two purposes towards a Node communicating with a Bridge:
9
9
  * * indicate that the functionality on the Endpoint where it is placed (and its Parts) is bridged from a
@@ -19,7 +19,7 @@ export declare const BridgedDeviceBasicInformationCluster: Cluster<import("../ma
19
19
  vendorName: OptionalAttribute<string>;
20
20
  vendorId: OptionalAttribute<import("../common/VendorId.js").VendorId>;
21
21
  productName: OptionalAttribute<string>;
22
- nodeLabel: import("./Cluster.js").WritableAttribute<string>;
22
+ nodeLabel: OptionalWritableAttribute<string>;
23
23
  hardwareVersion: OptionalAttribute<number>;
24
24
  hardwareVersionString: OptionalAttribute<string>;
25
25
  softwareVersion: OptionalAttribute<number>;
@@ -39,7 +39,7 @@ interface AttributeOptions<T> {
39
39
  export declare const Attribute: <T, V extends T>(id: number, schema: TlvSchema<T>, { default: conformanceValue, readAcl }?: AttributeOptions<V>) => Attribute<T>;
40
40
  export declare const OptionalAttribute: <T, V extends T>(id: number, schema: TlvSchema<T>, { default: conformanceValue, readAcl }?: AttributeOptions<V>) => OptionalAttribute<T>;
41
41
  export declare const WritableAttribute: <T, V extends T>(id: number, schema: TlvSchema<T>, { default: conformanceValue, readAcl, writeAcl }?: AttributeOptions<V>) => WritableAttribute<T>;
42
- export declare const OptionalWritableAttribute: <T, V extends T>(id: number, schema: TlvSchema<T>, { default: conformanceValue, readAcl, writeAcl }?: AttributeOptions<V>) => WritableAttribute<T>;
42
+ export declare const OptionalWritableAttribute: <T, V extends T>(id: number, schema: TlvSchema<T>, { default: conformanceValue, readAcl, writeAcl }?: AttributeOptions<V>) => OptionalWritableAttribute<T>;
43
43
  export declare const TlvNoArguments: import("../tlv/TlvObject.js").ObjectSchema<{}>;
44
44
  export declare const TlvNoResponse: import("../tlv/TlvVoid.js").VoidSchema;
45
45
  export interface Command<RequestT, ResponseT> {
@@ -12,9 +12,9 @@ export declare const RESP_MAX = 900;
12
12
  *
13
13
  * @see {@link MatterCoreSpecificationV1_0} § 11.17.5.8 */
14
14
  export declare const enum CertificateChainType {
15
- /** Request the DER- encoded DAC certificate */
15
+ /** Requests the DER-encoded DAC certificate */
16
16
  DeviceAttestation = 1,
17
- /** Request the DER- encoded PAI certificate */
17
+ /** Requests the DER-encoded PAI certificate */
18
18
  ProductAttestationIntermediate = 2
19
19
  }
20
20
  /**
@@ -73,8 +73,8 @@ export declare const OperationalCredentialsCluster: Cluster<import("../matter.js
73
73
  label: string;
74
74
  vendorId: import("../common/VendorId.js").VendorId;
75
75
  rootPublicKey: Uint8Array;
76
- fabricID: import("../common/FabricId.js").FabricId;
77
- nodeID: import("../common/NodeId.js").NodeId;
76
+ fabricId: import("../common/FabricId.js").FabricId;
77
+ nodeId: import("../common/NodeId.js").NodeId;
78
78
  }[]>;
79
79
  supportedFabrics: Attribute<number>;
80
80
  commissionedFabrics: Attribute<number>;
@@ -83,20 +83,20 @@ export declare const OperationalCredentialsCluster: Cluster<import("../matter.js
83
83
  clusterRevision: Attribute<number>;
84
84
  featureMap: Attribute<import("../matter.js").TypeFromBitSchema<import("../matter.js").BitSchema>>;
85
85
  }, {
86
- /** Sender is requesting attestation information from the receiver. */
86
+ /** Requests attestation information. */
87
87
  requestAttestation: Command<{
88
88
  attestationNonce: Uint8Array;
89
89
  }, {
90
90
  elements: Uint8Array;
91
91
  signature: Uint8Array;
92
92
  }>;
93
- /** Sender is requesting a device attestation certificate from the receiver. */
93
+ /** Requests a device attestation certificate. */
94
94
  requestCertChain: Command<{
95
95
  type: CertificateChainType;
96
96
  }, {
97
97
  certificate: Uint8Array;
98
98
  }>;
99
- /** Sender is requesting a certificate signing request (CSR) from the receiver. */
99
+ /** Requests a certificate signing request (CSR). */
100
100
  requestCertSigning: Command<{
101
101
  certSigningRequestNonce: Uint8Array;
102
102
  isForUpdateNOC?: boolean | undefined;
@@ -104,7 +104,7 @@ export declare const OperationalCredentialsCluster: Cluster<import("../matter.js
104
104
  elements: Uint8Array;
105
105
  signature: Uint8Array;
106
106
  }>;
107
- /** Sender is requesting to add the new node operational certificates. */
107
+ /** Adds new node operational certificates. */
108
108
  addOperationalCert: Command<{
109
109
  operationalCert: Uint8Array;
110
110
  identityProtectionKey: Uint8Array;
@@ -116,7 +116,7 @@ export declare const OperationalCredentialsCluster: Cluster<import("../matter.js
116
116
  fabricIndex?: import("../common/FabricIndex.js").FabricIndex | undefined;
117
117
  debugText?: string | undefined;
118
118
  }>;
119
- /** Sender is requesting to update the node operational certificates. */
119
+ /** Updates the node operational certificates. */
120
120
  updateOperationalCert: Command<{
121
121
  operationalCert: Uint8Array;
122
122
  intermediateCaCert?: Uint8Array | undefined;
@@ -125,10 +125,7 @@ export declare const OperationalCredentialsCluster: Cluster<import("../matter.js
125
125
  fabricIndex?: import("../common/FabricIndex.js").FabricIndex | undefined;
126
126
  debugText?: string | undefined;
127
127
  }>;
128
- /**
129
- * This command SHALL be used by an Administrative Node to set the user-visible Label field for a given
130
- * Fabric, as reflected by entries in the Fabrics attribute.
131
- */
128
+ /** Sets the user-visible Label field for a given Fabric. */
132
129
  updateFabricLabel: Command<{
133
130
  label: string;
134
131
  }, {
@@ -136,10 +133,7 @@ export declare const OperationalCredentialsCluster: Cluster<import("../matter.js
136
133
  fabricIndex?: import("../common/FabricIndex.js").FabricIndex | undefined;
137
134
  debugText?: string | undefined;
138
135
  }>;
139
- /**
140
- * This command is used by Administrative Nodes to remove a given fabric index and delete all associated
141
- * fabric-scoped data.
142
- */
136
+ /** Removes a given fabric index and delete all associated fabric-scoped data. */
143
137
  removeFabric: Command<{
144
138
  fabricIndex: import("../common/FabricIndex.js").FabricIndex;
145
139
  }, {
@@ -147,9 +141,7 @@ export declare const OperationalCredentialsCluster: Cluster<import("../matter.js
147
141
  fabricIndex?: import("../common/FabricIndex.js").FabricIndex | undefined;
148
142
  debugText?: string | undefined;
149
143
  }>;
150
- /**
151
- * This command SHALL add a Trusted Root CA Certificate, provided as its CHIP Certificate representation.
152
- */
144
+ /** Adds a Trusted Root CA Certificate, provided as its CHIP Certificate representation. */
153
145
  addRootCert: Command<{
154
146
  certificate: Uint8Array;
155
147
  }, void>;
@@ -8,7 +8,7 @@ export declare abstract class Schema<T, E> {
8
8
  /** Encodes the value using the schema. */
9
9
  encode(value: T): E;
10
10
  /** Decodes the encoded data using the schema. */
11
- decode(encoded: E): T;
11
+ decode(encoded: E, validate?: boolean): T;
12
12
  protected abstract encodeInternal(value: T): E;
13
13
  protected abstract decodeInternal(encoded: E): T;
14
14
  /** Optional validator that can be used to enforce constraints on the data before encoding / after decoding. */
@@ -9,5 +9,6 @@ export declare class AnySchema extends TlvSchema<TlvStream> {
9
9
  encodeTlvInternal(writer: TlvWriter, tlvStream: TlvStream, tagAssigned?: TlvTag | undefined): void;
10
10
  decodeTlvInternalValue(reader: TlvReader, typeLength: TlvTypeLength): TlvStream;
11
11
  decodeTlvValueRec(reader: TlvReader, typeLength: TlvTypeLength, tlvStream: TlvStream, tag?: TlvTag): TlvStream;
12
+ validate(tlvStream: TlvStream): void;
12
13
  }
13
14
  export declare const TlvAny: AnySchema;
@@ -16,13 +16,13 @@ type LengthConstraints = {
16
16
  * @see {@link MatterCoreSpecificationV1_0} § A.11.2 and A.11.4
17
17
  */
18
18
  export declare class ArraySchema<T> extends TlvSchema<T[]> {
19
- private readonly elementSchema;
19
+ readonly elementSchema: TlvSchema<T>;
20
20
  private readonly minLength;
21
21
  private readonly maxLength;
22
22
  constructor(elementSchema: TlvSchema<T>, minLength?: number, maxLength?: number);
23
23
  encodeTlvInternal(writer: TlvWriter, value: T[], tag?: TlvTag): void;
24
24
  decodeTlvInternalValue(reader: TlvReader, typeLength: TlvTypeLength): T[];
25
- validate({ length }: T[]): void;
25
+ validate(data: T[]): void;
26
26
  }
27
27
  /** Array TLV schema. */
28
28
  export declare const TlvArray: <T>(elementSchema: TlvSchema<T>, { minLength, maxLength, length }?: LengthConstraints) => ArraySchema<T>;
@@ -13,6 +13,7 @@ import { TlvReader, TlvSchema, TlvWriter } from "./TlvSchema.js";
13
13
  export declare class BooleanSchema extends TlvSchema<boolean> {
14
14
  encodeTlvInternal(writer: TlvWriter, value: boolean, tag?: TlvTag): void;
15
15
  decodeTlvInternalValue(_reader: TlvReader, typeLength: TlvTypeLength): boolean;
16
+ validate(value: boolean): void;
16
17
  }
17
18
  /** Boolean TLV schema. */
18
19
  export declare const TlvBoolean: BooleanSchema;
@@ -15,6 +15,7 @@ export declare class NullableSchema<T> extends TlvSchema<T | null> {
15
15
  constructor(schema: TlvSchema<T>);
16
16
  encodeTlvInternal(writer: TlvWriter, value: T | null, tag?: TlvTag): void;
17
17
  decodeTlvInternalValue(reader: TlvReader, typeLength: TlvTypeLength): T | null;
18
+ validate(value: T | null): void;
18
19
  }
19
20
  /** Nullable TLV schema. */
20
21
  export declare const TlvNullable: <T>(schema: TlvSchema<T>) => NullableSchema<T>;
@@ -16,6 +16,7 @@ export declare class TlvNumericSchema<T extends bigint | number> extends TlvSche
16
16
  encodeTlvInternal(writer: TlvWriter, value: T, tag?: TlvTag): void;
17
17
  decodeTlvInternalValue(reader: TlvReader, typeLength: TlvTypeLength): T;
18
18
  validate(value: T): void;
19
+ validateBoundaries(value: T): void;
19
20
  /** Restrict value range. */
20
21
  bound({ min, max }: NumericConstraints<T>): TlvNumericSchema<T>;
21
22
  }
@@ -27,6 +28,7 @@ export declare class TlvNumberSchema extends TlvNumericSchema<number> {
27
28
  constructor(type: TlvType.UnsignedInt | TlvType.SignedInt | TlvType.Float, lengthProvider: (value: number) => TlvLength, min?: number, max?: number);
28
29
  decodeTlvInternalValue(reader: TlvReader, typeLength: TlvTypeLength): number;
29
30
  bound({ min, max }: NumericConstraints<number>): TlvNumericSchema<number>;
31
+ validate(value: number): void;
30
32
  }
31
33
  export declare const TlvLongNumberSchema: {
32
34
  new (type: TlvType.UnsignedInt | TlvType.SignedInt | TlvType.Float, lengthProvider: (value: number | bigint) => TlvLength, min?: number | bigint | undefined, max?: number | bigint | undefined): TlvNumericSchema<number | bigint>;
@@ -10,6 +10,7 @@ export interface FieldType<T> {
10
10
  id: number;
11
11
  schema: TlvSchema<T>;
12
12
  optional?: boolean;
13
+ fallback?: T;
13
14
  }
14
15
  export interface OptionalFieldType<T> extends FieldType<T> {
15
16
  optional: true;
@@ -49,8 +50,12 @@ export declare class ObjectSchema<F extends TlvFields> extends TlvSchema<TypeFro
49
50
  export declare const TlvObject: <F extends TlvFields>(fields: F) => ObjectSchema<F>;
50
51
  /** List TLV schema. */
51
52
  export declare const TlvList: <F extends TlvFields>(fields: F) => ObjectSchema<F>;
52
- /** Object TLV mandatory field. */
53
- export declare const TlvField: <T>(id: number, schema: TlvSchema<T>) => FieldType<T>;
53
+ /**
54
+ * Object TLV mandatory field. Optionally provide a fallback value to initialize the field value when devices omit
55
+ * providing a value against the specifications or in special usecases. Make sure to use a value that is an equivalent
56
+ * to the value being empty.
57
+ */
58
+ export declare const TlvField: <T>(id: number, schema: TlvSchema<T>, fallback?: T | undefined) => FieldType<T>;
54
59
  /** Object TLV optional field. */
55
60
  export declare const TlvOptionalField: <T>(id: number, schema: TlvSchema<T>) => OptionalFieldType<T>;
56
61
  export {};
@@ -22,7 +22,7 @@ export declare class StringSchema<T extends TlvType.ByteString | TlvType.Utf8Str
22
22
  constructor(type: T, minLength?: number, maxLength?: number);
23
23
  encodeTlvInternal(writer: TlvWriter, value: TlvToPrimitive[T], tag?: TlvTag): void;
24
24
  decodeTlvInternalValue(reader: TlvReader, typeLength: TlvTypeLength): TlvToPrimitive[T];
25
- validate({ length }: TlvToPrimitive[T]): void;
25
+ validate(value: TlvToPrimitive[T]): void;
26
26
  bound({ minLength, maxLength, length }: LengthConstraints): StringSchema<T>;
27
27
  }
28
28
  /** ByteString TLV schema. */
@@ -12,6 +12,7 @@ export declare class VoidSchema extends TlvSchema<void> {
12
12
  encodeTlvInternal(_writer: TlvWriter, _value: void, _tag?: TlvTag): void;
13
13
  decodeTlv(_encoded: TlvStream): void;
14
14
  decodeTlvInternalValue(_reader: TlvReader, _typeLength: TlvTypeLength): void;
15
+ validate(data: void): void;
15
16
  }
16
17
  /** Void TLV schema. */
17
18
  export declare const TlvVoid: VoidSchema;
@@ -40,11 +40,11 @@ export const DescriptorCluster = Cluster({
40
40
  /** List containing each cluster ID for the server clusters present on the endpoint instance. */
41
41
  serverList: Attribute(1, TlvArray(TlvClusterId), { default: [] }),
42
42
  /** List containing each cluster ID for the client clusters present on the endpoint instance. */
43
- clientList: Attribute(3, TlvArray(TlvClusterId), { default: [] }),
43
+ clientList: Attribute(2, TlvArray(TlvClusterId), { default: [] }),
44
44
  /**
45
45
  * This indicates composition of the device type instance. Device type instance composition SHALL
46
46
  * include the endpoints in this list.
47
47
  */
48
- partsList: Attribute(4, TlvArray(TlvEndpointNumber), { default: [] }),
48
+ partsList: Attribute(3, TlvArray(TlvEndpointNumber), { default: [] }),
49
49
  },
50
50
  });
@@ -23,15 +23,15 @@ export const RESP_MAX = 900;
23
23
  * @see {@link MatterCoreSpecificationV1_0} § 11.17.5.3
24
24
  */
25
25
  const TlvFabricDescriptor = TlvObject({
26
- /** Contains the public key for the trusted root that scopes the fabric referenced by FabricIndex and its associated operational credential. */
26
+ /** The public key for the trusted root that scopes the fabric referenced by FabricIndex and its associated operational credential. */
27
27
  rootPublicKey: TlvField(1, TlvByteString.bound({ length: 65 })),
28
- /** Contains the value of AdminVendorID provided in the AddNOC command that led to the creation of this FabricDescriptorStruct. */
28
+ /** The value of AdminVendorID provided in the AddNOC command that led to the creation of this FabricDescriptorStruct. */
29
29
  vendorId: TlvField(2, TlvVendorId),
30
- /** Contains the FabricID allocated to the fabric referenced by FabricIndex. */
31
- fabricID: TlvField(3, TlvFabricId),
32
- /** Contain the NodeID in use within the fabric referenced by FabricIndex. */
33
- nodeID: TlvField(4, TlvNodeId),
34
- /** Contains a commissioner-set label for the fabric referenced by FabricIndex. */
30
+ /** The FabricID allocated to the fabric referenced by FabricIndex. */
31
+ fabricId: TlvField(3, TlvFabricId),
32
+ /** The NodeID in use within the fabric referenced by FabricIndex. */
33
+ nodeId: TlvField(4, TlvNodeId),
34
+ /** A commissioner-set label for the fabric referenced by FabricIndex. */
35
35
  label: TlvField(5, TlvString.bound({ maxLength: 32 })), /* default: "" */
36
36
  });
37
37
  /**
@@ -40,86 +40,83 @@ const TlvFabricDescriptor = TlvObject({
40
40
  * @see {@link MatterCoreSpecificationV1_0} § 11.17.5.2
41
41
  */
42
42
  const TlvNoc = TlvObject({
43
- /** Contains the NOC for the structs associated fabric. */
43
+ /** The NOC for the struct's associated fabric. */
44
44
  noc: TlvField(1, TlvByteString.bound({ maxLength: 400 })),
45
- /** Contain the ICAC or the structs associated fabric. */
45
+ /** The ICAC or the struct's associated fabric. */
46
46
  icac: TlvField(2, TlvNullable(TlvByteString.bound({ maxLength: 400 }))), /* default(not present): null */
47
47
  });
48
48
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.1 */
49
49
  const TlvAttestationRequest = TlvObject({
50
- /** Contains the attestation nonce to be used in the computation of the Attestation Information. */
50
+ /** The attestation nonce to be used in the computation of the Attestation Information. */
51
51
  attestationNonce: TlvField(0, TlvByteString.bound({ length: 32 })),
52
52
  });
53
53
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.2 */
54
54
  const TlvAttestationResponse = TlvObject({
55
- /** Contains the octet string of the serialized attestation_elements_message. */
55
+ /** The octet string of the serialized attestation_elements_message. */
56
56
  elements: TlvField(0, TlvByteString.bound({ maxLength: RESP_MAX })),
57
- /** Contain the octet string of the necessary attestation_signature. */
57
+ /** The octet string of the necessary attestation_signature. */
58
58
  signature: TlvField(1, TlvByteString.bound({ length: 64 })),
59
59
  });
60
60
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.5 */
61
61
  const TlvCertSigningRequestRequest = TlvObject({
62
- /** Contains the CSRNonce to be used in the computation of the NOCSR information. */
62
+ /** The CSRNonce to be used in the computation of the NOCSR information. */
63
63
  certSigningRequestNonce: TlvField(0, TlvByteString.bound({ length: 32 })),
64
64
  /**
65
65
  * If set to true, the internal state of the CSR associated keypair SHALL be tagged as being for
66
66
  * a subsequent UpdateNOC, otherwise the internal state of the CSR SHALL be tagged as being for a
67
- * subsequent AddNOC
67
+ * subsequent AddNOC.
68
68
  * */
69
69
  isForUpdateNOC: TlvOptionalField(1, TlvBoolean), /* default: false */
70
70
  });
71
71
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.6 */
72
72
  const TlvCertSigningRequestResponse = TlvObject({
73
- /** Contains the octet string of the serialized nocsr_elements_message. */
73
+ /** The octet string of the serialized nocsr_elements_message. */
74
74
  elements: TlvField(0, TlvByteString.bound({ maxLength: RESP_MAX })),
75
- /** Contain the octet string of the necessary attestation_signature. */
75
+ /** The octet string of the necessary attestation_signature. */
76
76
  signature: TlvField(1, TlvByteString.bound({ length: 64 })),
77
77
  });
78
78
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.3 */
79
79
  const TlvCertChainRequest = TlvObject({
80
- /** Contains the type of certificate to be requested. */
80
+ /** The type of certificate to be requested. */
81
81
  type: TlvField(0, TlvEnum()),
82
82
  });
83
83
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.4 */
84
84
  const TlvCertChainResponse = TlvObject({
85
- /** Contains the octet string of the requested certificate. */
85
+ /** The octet string of the requested certificate. */
86
86
  certificate: TlvField(0, TlvByteString.bound({ maxLength: 600 })),
87
87
  });
88
88
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.8 */
89
89
  const TlvAddNocRequest = TlvObject({
90
- /** Contains the Node Operational Certificate (NOC) to be added. */
90
+ /** The Node Operational Certificate (NOC) to be added. */
91
91
  operationalCert: TlvField(0, TlvByteString.bound({ maxLength: 400 })),
92
- /** Contains the Intermediate CA Certificate (ICAC). */
92
+ /** The Intermediate CA Certificate (ICAC). */
93
93
  intermediateCaCert: TlvOptionalField(1, TlvByteString.bound({ maxLength: 400 })),
94
- /** Contains the value of the Epoch Key for the Identity Protection Key (IPK) to set for the Fabric which is to be added. */
94
+ /** The value of the Epoch Key for the Identity Protection Key (IPK). */
95
95
  identityProtectionKey: TlvField(2, TlvByteString.bound({ length: 16 })),
96
- /**
97
- * Used to atomically add an Access Control Entry enabling that Subject to subsequently administer
98
- * the Node whose operational identity is being added by this command.
99
- */
96
+ /** That Subject will have administration access on this node. */
100
97
  caseAdminNode: TlvField(3, TlvSubjectId),
101
- /** Contains the Vendor ID of the entity issuing the AddNOC command. */
98
+ /** The Vendor ID of the entity issuing the AddNOC command. */
102
99
  adminVendorId: TlvField(4, TlvVendorId),
103
100
  });
104
101
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.9 */
105
102
  const TlvUpdateNocRequest = TlvObject({
106
- /** Contains the Node Operational Certificate (NOC). */
103
+ /** The Node Operational Certificate (NOC). */
107
104
  operationalCert: TlvField(0, TlvByteString.bound({ maxLength: 400 })),
108
- /** Contains the Intermediate CA Certificate (ICAC). */
105
+ /** The Intermediate CA Certificate (ICAC). */
109
106
  intermediateCaCert: TlvOptionalField(1, TlvByteString.bound({ maxLength: 400 })),
110
107
  });
111
108
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.13 */
112
109
  const TlvAddTrustedRootCertificateRequest = TlvObject({
113
- /** Contains the Trusted Root Certificate (TRC) to be added. */
110
+ /** The Trusted Root Certificate (TRC) to be added. */
114
111
  certificate: TlvField(0, TlvByteString.bound({ maxLength: 400 })),
115
112
  });
116
113
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.10 */
117
114
  const TlvOperationalCertificateStatusResponse = TlvObject({
118
- /** Contains a NOCStatus value representing the status of an operation involving a NOC. */
115
+ /** A NOCStatus value representing the status of an operation involving a NOC. */
119
116
  status: TlvField(0, TlvEnum()),
120
117
  /** When action was successful, contains the Fabric Index of the Fabric last added, removed or updated. */
121
118
  fabricIndex: TlvOptionalField(1, TlvFabricIndex),
122
- /** Optionally contains debugging textual information from the cluster implementation and should be visible in logs, not User UI */
119
+ /** Optional debugging textual information from the cluster implementation and should be visible in logs, not User UI */
123
120
  debugText: TlvOptionalField(2, TlvString.bound({ maxLength: 128 })),
124
121
  });
125
122
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.5.4 */
@@ -139,12 +136,12 @@ export const TlvCertSigningRequest = TlvObject({
139
136
  });
140
137
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.11 */
141
138
  const TlvUpdateFabricLabelRequest = TlvObject({
142
- /** Contains the label to set for the fabric associated with the current secure session. */
139
+ /** The label to set for the fabric associated with the current secure session. */
143
140
  label: TlvField(0, TlvString32max),
144
141
  });
145
142
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7.12 */
146
143
  const TlvRemoveFabricRequest = TlvObject({
147
- /** Contains the Fabric Index reference associated with the Fabric which is to be removed from the device. */
144
+ /** The Fabric Index reference associated with the Fabric which is to be removed from the device. */
148
145
  fabricIndex: TlvField(0, TlvFabricIndex),
149
146
  });
150
147
  /**
@@ -159,44 +156,36 @@ export const OperationalCredentialsCluster = Cluster({
159
156
  revision: 1,
160
157
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.6 */
161
158
  attributes: {
162
- /** Contains all NOCs applicable to this Node. */
159
+ /** All NOCs applicable to this Node. */
163
160
  nocs: Attribute(0, TlvArray(TlvNoc), { readAcl: 2 /* AccessLevel.Administer */ }),
164
- /** Describes all fabrics to which this Node is commissioned. */
161
+ /** Lists all fabrics to which this Node is commissioned. */
165
162
  fabrics: Attribute(1, TlvArray(TlvFabricDescriptor)),
166
- /** Contains the number of Fabrics that are supported by the device. */
163
+ /** The number of Fabrics that are supported by the device. */
167
164
  supportedFabrics: Attribute(2, TlvUInt8.bound({ min: 5, max: 254 })),
168
- /** Contains the number of Fabrics to which the device is currently commissioned. */
165
+ /** The number of Fabrics to which the device is currently commissioned. */
169
166
  commissionedFabrics: Attribute(3, TlvUInt8),
170
- /** Contains a read-only list of Trusted Root CA Certificates installed on the Node. */
167
+ /** A read-only list of Trusted Root CA Certificates installed on the Node. */
171
168
  trustedRootCertificates: Attribute(4, TlvArray(TlvByteString, { maxLength: 400 })),
172
- /** Contain accessing fabric index. */
169
+ /** Accessing fabric index. */
173
170
  currentFabricIndex: Attribute(5, TlvUInt8),
174
171
  },
175
172
  /** @see {@link MatterCoreSpecificationV1_0} § 11.17.7 */
176
173
  commands: {
177
- /** Sender is requesting attestation information from the receiver. */
174
+ /** Requests attestation information. */
178
175
  requestAttestation: Command(0, TlvAttestationRequest, 1, TlvAttestationResponse),
179
- /** Sender is requesting a device attestation certificate from the receiver. */
176
+ /** Requests a device attestation certificate. */
180
177
  requestCertChain: Command(2, TlvCertChainRequest, 3, TlvCertChainResponse),
181
- /** Sender is requesting a certificate signing request (CSR) from the receiver. */
178
+ /** Requests a certificate signing request (CSR). */
182
179
  requestCertSigning: Command(4, TlvCertSigningRequestRequest, 5, TlvCertSigningRequestResponse),
183
- /** Sender is requesting to add the new node operational certificates. */
180
+ /** Adds new node operational certificates. */
184
181
  addOperationalCert: Command(6, TlvAddNocRequest, 8, TlvOperationalCertificateStatusResponse),
185
- /** Sender is requesting to update the node operational certificates. */
182
+ /** Updates the node operational certificates. */
186
183
  updateOperationalCert: Command(7, TlvUpdateNocRequest, 8, TlvOperationalCertificateStatusResponse),
187
- /**
188
- * This command SHALL be used by an Administrative Node to set the user-visible Label field for a given
189
- * Fabric, as reflected by entries in the Fabrics attribute.
190
- */
184
+ /** Sets the user-visible Label field for a given Fabric. */
191
185
  updateFabricLabel: Command(9, TlvUpdateFabricLabelRequest, 8, TlvOperationalCertificateStatusResponse),
192
- /**
193
- * This command is used by Administrative Nodes to remove a given fabric index and delete all associated
194
- * fabric-scoped data.
195
- */
186
+ /** Removes a given fabric index and delete all associated fabric-scoped data. */
196
187
  removeFabric: Command(10, TlvRemoveFabricRequest, 8, TlvOperationalCertificateStatusResponse),
197
- /**
198
- * This command SHALL add a Trusted Root CA Certificate, provided as its CHIP Certificate representation.
199
- */
188
+ /** Adds a Trusted Root CA Certificate, provided as its CHIP Certificate representation. */
200
189
  addRootCert: Command(11, TlvAddTrustedRootCertificateRequest, 11, TlvNoResponse),
201
190
  },
202
191
  });
@@ -11,9 +11,11 @@ export class Schema {
11
11
  return this.encodeInternal(value);
12
12
  }
13
13
  /** Decodes the encoded data using the schema. */
14
- decode(encoded) {
14
+ decode(encoded, validate = true) {
15
15
  const result = this.decodeInternal(encoded);
16
- this.validate(result);
16
+ if (validate) {
17
+ this.validate(result);
18
+ }
17
19
  return result;
18
20
  }
19
21
  /** Optional validator that can be used to enforce constraints on the data before encoding / after decoding. */
@@ -63,5 +63,15 @@ export class AnySchema extends TlvSchema {
63
63
  }
64
64
  return tlvStream;
65
65
  }
66
+ validate(tlvStream) {
67
+ if (!Array.isArray(tlvStream))
68
+ throw new Error(`Expected TlvStream, got ${typeof tlvStream}.`);
69
+ tlvStream.forEach(({ typeLength }) => {
70
+ if (!typeLength || typeof typeLength !== "object")
71
+ throw new Error(`Expected typeLength properties in TlvStream, got ${typeof typeLength}.`);
72
+ if (typeof typeLength.type !== "number")
73
+ throw new Error(`Expected typeLength.type as number in TlvStream, got ${typeof typeLength.type}.`);
74
+ });
75
+ }
66
76
  }
67
77
  export const TlvAny = new AnySchema();
@@ -33,14 +33,16 @@ export class ArraySchema extends TlvSchema {
33
33
  break;
34
34
  result.push(this.elementSchema.decodeTlvInternalValue(reader, elementTypeLength));
35
35
  }
36
- this.validate(result);
37
36
  return result;
38
37
  }
39
- validate({ length }) {
40
- if (length > this.maxLength)
41
- throw new Error(`Array is too long: ${length}, max ${this.maxLength}.`);
42
- if (length < this.minLength)
43
- throw new Error(`Array is too short: ${length}, min ${this.minLength}.`);
38
+ validate(data) {
39
+ if (!Array.isArray(data))
40
+ throw new Error(`Expected array, got ${typeof data}.`);
41
+ if (data.length > this.maxLength)
42
+ throw new Error(`Array is too long: ${data.length}, max ${this.maxLength}.`);
43
+ if (data.length < this.minLength)
44
+ throw new Error(`Array is too short: ${data.length}, min ${this.minLength}.`);
45
+ data.forEach(element => this.elementSchema.validate(element));
44
46
  }
45
47
  }
46
48
  /** Array TLV schema. */
@@ -18,6 +18,10 @@ export class BooleanSchema extends TlvSchema {
18
18
  throw new Error(`Unexpected type ${typeLength.type}.`);
19
19
  return typeLength.value;
20
20
  }
21
+ validate(value) {
22
+ if (typeof value !== "boolean")
23
+ throw new Error(`Expected boolean, got ${typeof value}.`);
24
+ }
21
25
  }
22
26
  /** Boolean TLV schema. */
23
27
  export const TlvBoolean = new BooleanSchema();
@@ -27,6 +27,10 @@ export class NullableSchema extends TlvSchema {
27
27
  return null;
28
28
  return this.schema.decodeTlvInternalValue(reader, typeLength);
29
29
  }
30
+ validate(value) {
31
+ if (value !== null)
32
+ this.schema.validate(value);
33
+ }
30
34
  }
31
35
  /** Nullable TLV schema. */
32
36
  export const TlvNullable = (schema) => new NullableSchema(schema);
@@ -30,11 +30,14 @@ export class TlvNumericSchema extends TlvSchema {
30
30
  if (typeLength.type !== this.type)
31
31
  throw new Error(`Unexpected type ${typeLength.type}, was expecting ${this.type}.`);
32
32
  const value = reader.readPrimitive(typeLength);
33
- this.validate(value);
34
33
  return value;
35
34
  }
36
35
  validate(value) {
37
- super.validate(value);
36
+ if (typeof value !== "number" && typeof value !== 'bigint')
37
+ throw new Error(`Expected number, got ${typeof value}.`);
38
+ this.validateBoundaries(value);
39
+ }
40
+ validateBoundaries(value) {
38
41
  if (this.min !== undefined && value < this.min)
39
42
  throw new Error(`Invalid value: ${value} is below the minimum, ${this.min}.`);
40
43
  if (this.max !== undefined && value > this.max)
@@ -56,6 +59,11 @@ export class TlvNumberSchema extends TlvNumericSchema {
56
59
  bound({ min, max }) {
57
60
  return new TlvNumberSchema(this.type, this.lengthProvider, maxValue(min, this.min), minValue(max, this.max));
58
61
  }
62
+ validate(value) {
63
+ if (typeof value !== "number")
64
+ throw new Error(`Expected number, got ${typeof value}.`);
65
+ this.validateBoundaries(value);
66
+ }
59
67
  }
60
68
  export const TlvLongNumberSchema = (TlvNumericSchema);
61
69
  /** Unsigned integer TLV schema. */
@@ -57,13 +57,28 @@ export class ObjectSchema extends TlvSchema {
57
57
  const { field, name } = fieldName;
58
58
  result[name] = field.schema.decodeTlvInternalValue(reader, elementTypeLength);
59
59
  }
60
- this.validate(result);
60
+ // Check mandatory fields and, if missing, populate with fallback value if defined.
61
+ for (const name in this.fieldDefinitions) {
62
+ const { optional, fallback } = this.fieldDefinitions[name];
63
+ if (optional)
64
+ continue;
65
+ const value = result[name];
66
+ if (value !== undefined)
67
+ continue;
68
+ if (fallback === undefined)
69
+ throw new Error(`Missing mandatory field ${name}`);
70
+ result[name] = fallback;
71
+ }
61
72
  return result;
62
73
  }
63
74
  validate(value) {
64
75
  for (const name in this.fieldDefinitions) {
65
- if (!this.fieldDefinitions[name].optional && value[name] === undefined)
76
+ const { optional, schema } = this.fieldDefinitions[name];
77
+ if (optional && value[name] === undefined)
78
+ continue;
79
+ if (!optional && value[name] === undefined)
66
80
  throw new Error(`Missing mandatory field ${name}`);
81
+ schema.validate(value[name]);
67
82
  }
68
83
  }
69
84
  }
@@ -71,7 +86,11 @@ export class ObjectSchema extends TlvSchema {
71
86
  export const TlvObject = (fields) => new ObjectSchema(fields, 21 /* TlvType.Structure */);
72
87
  /** List TLV schema. */
73
88
  export const TlvList = (fields) => new ObjectSchema(fields, 23 /* TlvType.List */);
74
- /** Object TLV mandatory field. */
75
- export const TlvField = (id, schema) => ({ id, schema, optional: false });
89
+ /**
90
+ * Object TLV mandatory field. Optionally provide a fallback value to initialize the field value when devices omit
91
+ * providing a value against the specifications or in special usecases. Make sure to use a value that is an equivalent
92
+ * to the value being empty.
93
+ */
94
+ export const TlvField = (id, schema, fallback) => ({ id, schema, fallback, optional: false });
76
95
  /** Object TLV optional field. */
77
96
  export const TlvOptionalField = (id, schema) => ({ id, schema, optional: true });
@@ -6,6 +6,7 @@
6
6
  import { TlvCodec } from "./TlvCodec.js";
7
7
  import { TlvSchema } from "./TlvSchema.js";
8
8
  import { maxValue, minValue } from "../util/Number.js";
9
+ import { ByteArray } from "../util/ByteArray";
9
10
  /**
10
11
  * Schema to encode an byte string or an Utf8 string in TLV.
11
12
  *
@@ -30,11 +31,15 @@ export class StringSchema extends TlvSchema {
30
31
  throw new Error(`Unexpected type ${typeLength.type}.`);
31
32
  return reader.readPrimitive(typeLength);
32
33
  }
33
- validate({ length }) {
34
- if (length > this.maxLength)
35
- throw new Error(`Array is too long: ${length}, max ${this.maxLength}.`);
36
- if (length < this.minLength)
37
- throw new Error(`Array is too short: ${length}, min ${this.minLength}.`);
34
+ validate(value) {
35
+ if (this.type === 12 /* TlvType.Utf8String */ && typeof value !== "string")
36
+ throw new Error(`Expected string, got ${typeof value}.`);
37
+ if (this.type === 16 /* TlvType.ByteString */ && !(value instanceof ByteArray))
38
+ throw new Error(`Expected ByteArray, got ${typeof value}.`);
39
+ if (value.length > this.maxLength)
40
+ throw new Error(`String is too long: ${value.length}, max ${this.maxLength}.`);
41
+ if (value.length < this.minLength)
42
+ throw new Error(`String is too short: ${value.length}, min ${this.minLength}.`);
38
43
  }
39
44
  bound({ minLength, maxLength, length }) {
40
45
  return new StringSchema(this.type, length !== null && length !== void 0 ? length : maxValue(this.minLength, minLength), length !== null && length !== void 0 ? length : minValue(this.maxLength, maxLength));
@@ -17,6 +17,10 @@ export class VoidSchema extends TlvSchema {
17
17
  decodeTlvInternalValue(_reader, _typeLength) {
18
18
  throw new Error("decodeTlvInternalValue should never be called");
19
19
  }
20
+ validate(data) {
21
+ if (data !== undefined)
22
+ throw new Error(`Expected void, got ${typeof data}.`);
23
+ }
20
24
  }
21
25
  /** Void TLV schema. */
22
26
  export const TlvVoid = new VoidSchema();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@project-chip/matter.js",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Matter protocol in pure js",
5
5
  "keywords": [
6
6
  "iot",
@@ -26,7 +26,7 @@
26
26
  "clean": "rm -rf dist; rm -rf out",
27
27
  "build": "npm run clean; tsc --project tsconfig.dist-es.json; tsc --project tsconfig.dist-cjs.json; tsc --project tsconfig.dist-dts.json",
28
28
  "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
29
- "test-web": "karma start karma.conf.cjs"
29
+ "test-web": "karma start test/karma.conf.cjs"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/jasmine": "^4.3.0",