@matter/protocol 0.12.2-alpha.0-20250128-09631d531 → 0.12.2-alpha.0-20250201-eb5d40a2f

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 (49) hide show
  1. package/dist/cjs/interaction/AccessControlManager.d.ts +8 -5
  2. package/dist/cjs/interaction/AccessControlManager.d.ts.map +1 -1
  3. package/dist/cjs/interaction/AccessControlManager.js +1 -1
  4. package/dist/cjs/interaction/AccessControlManager.js.map +1 -1
  5. package/dist/cjs/interaction/AttributeDataEncoder.d.ts +8 -1
  6. package/dist/cjs/interaction/AttributeDataEncoder.d.ts.map +1 -1
  7. package/dist/cjs/interaction/AttributeDataEncoder.js.map +1 -1
  8. package/dist/cjs/interaction/InteractionMessenger.d.ts +7 -4
  9. package/dist/cjs/interaction/InteractionMessenger.d.ts.map +1 -1
  10. package/dist/cjs/interaction/InteractionMessenger.js +33 -26
  11. package/dist/cjs/interaction/InteractionMessenger.js.map +1 -1
  12. package/dist/cjs/interaction/InteractionServer.d.ts +22 -6
  13. package/dist/cjs/interaction/InteractionServer.d.ts.map +1 -1
  14. package/dist/cjs/interaction/InteractionServer.js +178 -165
  15. package/dist/cjs/interaction/InteractionServer.js.map +1 -1
  16. package/dist/cjs/interaction/ServerSubscription.d.ts +13 -3
  17. package/dist/cjs/interaction/ServerSubscription.d.ts.map +1 -1
  18. package/dist/cjs/interaction/ServerSubscription.js +121 -91
  19. package/dist/cjs/interaction/ServerSubscription.js.map +2 -2
  20. package/dist/cjs/peer/ControllerCommissioningFlow.js +7 -6
  21. package/dist/cjs/peer/ControllerCommissioningFlow.js.map +1 -1
  22. package/dist/esm/interaction/AccessControlManager.d.ts +8 -5
  23. package/dist/esm/interaction/AccessControlManager.d.ts.map +1 -1
  24. package/dist/esm/interaction/AccessControlManager.js +8 -2
  25. package/dist/esm/interaction/AccessControlManager.js.map +1 -1
  26. package/dist/esm/interaction/AttributeDataEncoder.d.ts +8 -1
  27. package/dist/esm/interaction/AttributeDataEncoder.d.ts.map +1 -1
  28. package/dist/esm/interaction/AttributeDataEncoder.js.map +1 -1
  29. package/dist/esm/interaction/InteractionMessenger.d.ts +7 -4
  30. package/dist/esm/interaction/InteractionMessenger.d.ts.map +1 -1
  31. package/dist/esm/interaction/InteractionMessenger.js +41 -27
  32. package/dist/esm/interaction/InteractionMessenger.js.map +1 -1
  33. package/dist/esm/interaction/InteractionServer.d.ts +22 -6
  34. package/dist/esm/interaction/InteractionServer.d.ts.map +1 -1
  35. package/dist/esm/interaction/InteractionServer.js +178 -165
  36. package/dist/esm/interaction/InteractionServer.js.map +1 -1
  37. package/dist/esm/interaction/ServerSubscription.d.ts +13 -3
  38. package/dist/esm/interaction/ServerSubscription.d.ts.map +1 -1
  39. package/dist/esm/interaction/ServerSubscription.js +121 -91
  40. package/dist/esm/interaction/ServerSubscription.js.map +2 -2
  41. package/dist/esm/peer/ControllerCommissioningFlow.js +7 -6
  42. package/dist/esm/peer/ControllerCommissioningFlow.js.map +1 -1
  43. package/package.json +6 -6
  44. package/src/interaction/AccessControlManager.ts +20 -8
  45. package/src/interaction/AttributeDataEncoder.ts +11 -1
  46. package/src/interaction/InteractionMessenger.ts +65 -33
  47. package/src/interaction/InteractionServer.ts +224 -188
  48. package/src/interaction/ServerSubscription.ts +155 -108
  49. package/src/peer/ControllerCommissioningFlow.ts +7 -7
@@ -4,7 +4,14 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
- import { Diagnostic, Logger, MatterFlowError, NoResponseTimeoutError, UnexpectedDataError } from "#general";
7
+ import {
8
+ Diagnostic,
9
+ InternalError,
10
+ Logger,
11
+ MatterFlowError,
12
+ NoResponseTimeoutError,
13
+ UnexpectedDataError,
14
+ } from "#general";
8
15
  import { Specification } from "#model";
9
16
  import {
10
17
  Status,
@@ -38,11 +45,14 @@ import {
38
45
  UnexpectedMessageError,
39
46
  } from "../protocol/MessageExchange.js";
40
47
  import {
41
- DataReportPayload,
48
+ AttributeReportPayload,
49
+ BaseDataReport,
42
50
  canAttributePayloadBeChunked,
43
51
  chunkAttributePayload,
52
+ DataReportPayloadIterator,
44
53
  encodeAttributePayload,
45
54
  encodeEventPayload,
55
+ EventReportPayload,
46
56
  } from "./AttributeDataEncoder.js";
47
57
 
48
58
  export enum MessageType {
@@ -170,7 +180,11 @@ class InteractionMessenger {
170
180
  }
171
181
 
172
182
  export interface InteractionRecipient {
173
- handleReadRequest(exchange: MessageExchange, request: ReadRequest, message: Message): Promise<DataReport>;
183
+ handleReadRequest(
184
+ exchange: MessageExchange,
185
+ request: ReadRequest,
186
+ message: Message,
187
+ ): Promise<{ dataReport: DataReport; payload: DataReportPayloadIterator }>;
174
188
  handleWriteRequest(exchange: MessageExchange, request: WriteRequest, message: Message): Promise<WriteResponse>;
175
189
  handleSubscribeRequest(
176
190
  exchange: MessageExchange,
@@ -205,11 +219,15 @@ export class InteractionServerMessenger extends InteractionMessenger {
205
219
  );
206
220
  }
207
221
  const readRequest = TlvReadRequest.decode(message.payload);
208
- // This potentially sends multiple DataReport Messages
209
- await this.sendDataReport(
210
- await recipient.handleReadRequest(this.exchange, readRequest, message),
211
- readRequest.isFabricFiltered,
222
+
223
+ const { dataReport, payload } = await recipient.handleReadRequest(
224
+ this.exchange,
225
+ readRequest,
226
+ message,
212
227
  );
228
+
229
+ // This potentially sends multiple DataReport Messages
230
+ await this.sendDataReport(dataReport, readRequest.isFabricFiltered, payload);
213
231
  break;
214
232
  }
215
233
  case MessageType.WriteRequest: {
@@ -268,17 +286,16 @@ export class InteractionServerMessenger extends InteractionMessenger {
268
286
  }
269
287
 
270
288
  /**
271
- * Handle DataReportPayload with the content of a DataReport to send, split them into multiple DataReport
289
+ * Handle a DataReport with a Payload Iterator for a DataReport to send, split them into multiple DataReport
272
290
  * messages and send them out based on the size.
273
291
  */
274
- async sendDataReport(dataReportPayload: DataReportPayload, forFabricFilteredRead: boolean, waitForAck = true) {
275
- const {
276
- subscriptionId,
277
- attributeReportsPayload,
278
- eventReportsPayload,
279
- suppressResponse,
280
- interactionModelRevision,
281
- } = dataReportPayload;
292
+ async sendDataReport(
293
+ baseDataReport: BaseDataReport,
294
+ forFabricFilteredRead: boolean,
295
+ payload?: DataReportPayloadIterator,
296
+ waitForAck = true,
297
+ ) {
298
+ const { subscriptionId, suppressResponse, interactionModelRevision } = baseDataReport;
282
299
 
283
300
  const dataReport: TypeFromSchema<typeof TlvDataReportForSend> = {
284
301
  subscriptionId,
@@ -288,33 +305,49 @@ export class InteractionServerMessenger extends InteractionMessenger {
288
305
  eventReports: undefined,
289
306
  };
290
307
 
291
- if (attributeReportsPayload !== undefined || eventReportsPayload !== undefined) {
308
+ if (payload !== undefined) {
292
309
  // TODO Add tag compressing once https://github.com/project-chip/connectedhomeip/issues/29359 is solved
293
-
294
- const attributeReportsToSend = [...(attributeReportsPayload ?? [])];
295
- const eventReportsToSend = [...(eventReportsPayload ?? [])];
296
-
297
310
  dataReport.moreChunkedMessages = true; // Assume we have multiple chunks, also for size calculation
298
311
  const emptyDataReportBytes = TlvDataReportForSend.encode(dataReport);
299
312
 
300
- let firstAttributeAddedToReportMessage = false;
301
- let firstEventAddedToReportMessage = false;
302
313
  const sendAndResetReport = async () => {
303
314
  await this.sendDataReportMessage(dataReport, waitForAck);
304
- dataReport.attributeReports = undefined;
305
- dataReport.eventReports = undefined;
306
- messageSize = emptyDataReportBytes.length;
307
- firstAttributeAddedToReportMessage = false;
308
- firstEventAddedToReportMessage = false;
315
+ delete dataReport.attributeReports;
316
+ delete dataReport.eventReports;
317
+ messageSize = emptyDataReportBytes.length + 3; // We add 3 bytes because either one of the both removed arrays will be added or it is the last message and we don't care
309
318
  };
310
-
311
319
  let messageSize = emptyDataReportBytes.length;
320
+
321
+ let attributeReportsToSend = new Array<AttributeReportPayload>();
322
+ let eventReportsToSend = new Array<EventReportPayload>();
323
+
312
324
  while (true) {
325
+ // If we have no data to process we need to get the next chunk
326
+ // If no more data is available we cancel the while loop and send final message
327
+ if (attributeReportsToSend.length === 0 && eventReportsToSend.length === 0) {
328
+ const { done, value } = payload.next();
329
+ if (done) {
330
+ // No more chunks to send
331
+ delete dataReport.moreChunkedMessages;
332
+ break;
333
+ }
334
+ if (value === undefined) {
335
+ continue;
336
+ }
337
+ if ("attributeData" in value || "attributeStatus" in value) {
338
+ attributeReportsToSend = [value];
339
+ } else if ("eventData" in value || "eventStatus" in value) {
340
+ eventReportsToSend = [value];
341
+ } else {
342
+ throw new InternalError(`Invalid report type: ${value}`);
343
+ }
344
+ }
345
+
346
+ // If we have attribute data to send, we add them first
313
347
  if (attributeReportsToSend.length > 0) {
314
348
  const attributeReport = attributeReportsToSend.shift();
315
349
  if (attributeReport !== undefined) {
316
- if (!firstAttributeAddedToReportMessage) {
317
- firstAttributeAddedToReportMessage = true;
350
+ if (dataReport.attributeReports === undefined) {
318
351
  messageSize += 3; // Array element is added now which needs 3 bytes
319
352
  }
320
353
  const allowMissingFieldsForNonFabricFilteredRead =
@@ -342,8 +375,7 @@ export class InteractionServerMessenger extends InteractionMessenger {
342
375
  delete dataReport.moreChunkedMessages;
343
376
  break;
344
377
  }
345
- if (!firstEventAddedToReportMessage) {
346
- firstEventAddedToReportMessage = true;
378
+ if (dataReport.eventReports === undefined) {
347
379
  messageSize += 3; // Array element is added now which needs 3 bytes
348
380
  }
349
381
  const allowMissingFieldsForNonFabricFilteredRead =