@project-chip/matter.js 0.9.2 → 0.9.3

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 (33) hide show
  1. package/dist/cjs/MatterDevice.d.ts +1 -0
  2. package/dist/cjs/MatterDevice.d.ts.map +1 -1
  3. package/dist/cjs/MatterDevice.js +3 -0
  4. package/dist/cjs/MatterDevice.js.map +2 -2
  5. package/dist/cjs/protocol/interaction/InteractionServer.d.ts.map +1 -1
  6. package/dist/cjs/protocol/interaction/InteractionServer.js +4 -2
  7. package/dist/cjs/protocol/interaction/InteractionServer.js.map +2 -2
  8. package/dist/cjs/session/SecureSession.d.ts.map +1 -1
  9. package/dist/cjs/session/SecureSession.js +2 -1
  10. package/dist/cjs/session/SecureSession.js.map +2 -2
  11. package/dist/cjs/session/SessionManager.d.ts +1 -0
  12. package/dist/cjs/session/SessionManager.d.ts.map +1 -1
  13. package/dist/cjs/session/SessionManager.js +7 -0
  14. package/dist/cjs/session/SessionManager.js.map +2 -2
  15. package/dist/esm/MatterDevice.d.ts +1 -0
  16. package/dist/esm/MatterDevice.d.ts.map +1 -1
  17. package/dist/esm/MatterDevice.js +3 -0
  18. package/dist/esm/MatterDevice.js.map +2 -2
  19. package/dist/esm/protocol/interaction/InteractionServer.d.ts.map +1 -1
  20. package/dist/esm/protocol/interaction/InteractionServer.js +4 -2
  21. package/dist/esm/protocol/interaction/InteractionServer.js.map +2 -2
  22. package/dist/esm/session/SecureSession.d.ts.map +1 -1
  23. package/dist/esm/session/SecureSession.js +2 -1
  24. package/dist/esm/session/SecureSession.js.map +2 -2
  25. package/dist/esm/session/SessionManager.d.ts +1 -0
  26. package/dist/esm/session/SessionManager.d.ts.map +1 -1
  27. package/dist/esm/session/SessionManager.js +7 -0
  28. package/dist/esm/session/SessionManager.js.map +2 -2
  29. package/package.json +3 -3
  30. package/src/MatterDevice.ts +4 -0
  31. package/src/protocol/interaction/InteractionServer.ts +4 -2
  32. package/src/session/SecureSession.ts +2 -1
  33. package/src/session/SessionManager.ts +8 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/protocol/interaction/InteractionServer.ts"],
4
- "sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { MatterDevice } from \"../../MatterDevice.js\";\nimport { TlvNoResponse } from \"../../cluster/Cluster.js\";\nimport {\n AnyAttributeServer,\n AttributeServer,\n FabricScopedAttributeServer,\n} from \"../../cluster/server/AttributeServer.js\";\nimport { CommandServer } from \"../../cluster/server/CommandServer.js\";\nimport { EventServer } from \"../../cluster/server/EventServer.js\";\nimport { Message, SessionType } from \"../../codec/MessageCodec.js\";\nimport { InternalError, MatterFlowError } from \"../../common/MatterError.js\";\nimport { tryCatch, tryCatchAsync } from \"../../common/TryCatchHandler.js\";\nimport { ValidationError } from \"../../common/ValidationError.js\";\nimport { Crypto } from \"../../crypto/Crypto.js\";\nimport { AttributeId } from \"../../datatype/AttributeId.js\";\nimport { ClusterId } from \"../../datatype/ClusterId.js\";\nimport { CommandId } from \"../../datatype/CommandId.js\";\nimport { EndpointNumber } from \"../../datatype/EndpointNumber.js\";\nimport { EventId } from \"../../datatype/EventId.js\";\nimport { EventNumber } from \"../../datatype/EventNumber.js\";\nimport { NodeId } from \"../../datatype/NodeId.js\";\nimport { EndpointInterface } from \"../../endpoint/EndpointInterface.js\";\nimport { Diagnostic } from \"../../log/Diagnostic.js\";\nimport { Logger } from \"../../log/Logger.js\";\nimport { GLOBAL_IDS } from \"../../model/index.js\";\nimport { MessageExchange } from \"../../protocol/MessageExchange.js\";\nimport { ProtocolHandler } from \"../../protocol/ProtocolHandler.js\";\nimport { EventHandler } from \"../../protocol/interaction/EventHandler.js\";\nimport { NoAssociatedFabricError, SecureSession, assertSecureSession } from \"../../session/SecureSession.js\";\nimport { ArraySchema } from \"../../tlv/TlvArray.js\";\nimport { TlvNoArguments } from \"../../tlv/TlvNoArguments.js\";\nimport { TypeFromSchema } from \"../../tlv/TlvSchema.js\";\nimport {\n decodeAttributeValueWithSchema,\n decodeListAttributeValueWithSchema,\n expandPathsInAttributeData,\n} from \"./AttributeDataDecoder.js\";\nimport {\n AttributeReportPayload,\n DataReportPayload,\n EventDataPayload,\n EventReportPayload,\n} from \"./AttributeDataEncoder.js\";\nimport { InteractionEndpointStructure } from \"./InteractionEndpointStructure.js\";\nimport {\n InteractionRecipient,\n InteractionServerMessenger,\n InvokeRequest,\n InvokeResponse,\n MessageType,\n ReadRequest,\n SubscribeRequest,\n TimedRequest,\n WriteRequest,\n WriteResponse,\n} from \"./InteractionMessenger.js\";\nimport {\n TlvAttributePath,\n TlvClusterPath,\n TlvCommandPath,\n TlvEventFilter,\n TlvEventPath,\n TlvInvokeResponseData,\n TlvSubscribeResponse,\n} from \"./InteractionProtocol.js\";\nimport { StatusCode, StatusResponseError } from \"./StatusCode.js\";\nimport { SubscriptionHandler } from \"./SubscriptionHandler.js\";\nimport { SubscriptionOptions } from \"./SubscriptionOptions.js\";\n\n/** Protocol ID for the Interaction Protocol as per Matter specification. */\nexport const INTERACTION_PROTOCOL_ID = 0x0001;\n\n/** Backward compatible re-export for Interaction Model version we support currently. */\nexport const INTERACTION_MODEL_REVISION = 11;\n\n/** Number of Invoke Path setting from our Interaction model implementation. */\nexport const MAX_PATHS_PER_INVOKE = 1;\n\nconst logger = Logger.get(\"InteractionServer\");\n\nexport interface CommandPath {\n nodeId?: NodeId;\n endpointId: EndpointNumber;\n clusterId: ClusterId;\n commandId: CommandId;\n}\n\nexport interface AttributePath {\n nodeId?: NodeId;\n endpointId: EndpointNumber;\n clusterId: ClusterId;\n attributeId: AttributeId;\n}\n\nexport interface EventPath {\n nodeId?: NodeId;\n endpointId: EndpointNumber;\n clusterId: ClusterId;\n eventId: EventId;\n}\n\nexport interface AttributeWithPath {\n path: AttributePath;\n attribute: AnyAttributeServer<any>;\n}\n\nexport interface EventWithPath {\n path: EventPath;\n event: EventServer<any, any>;\n}\n\nexport interface CommandWithPath {\n path: CommandPath;\n command: CommandServer<any, any>;\n}\n\nexport function genericElementPathToId(\n endpointId: EndpointNumber | undefined,\n clusterId: ClusterId | undefined,\n elementId: number | undefined,\n) {\n return `${endpointId}/${clusterId}/${elementId}`;\n}\n\nexport function commandPathToId({ endpointId, clusterId, commandId }: CommandPath) {\n return genericElementPathToId(endpointId, clusterId, commandId);\n}\n\nexport function attributePathToId({ endpointId, clusterId, attributeId }: TypeFromSchema<typeof TlvAttributePath>) {\n return genericElementPathToId(endpointId, clusterId, attributeId);\n}\n\nexport function eventPathToId({ endpointId, clusterId, eventId }: TypeFromSchema<typeof TlvEventPath>) {\n return genericElementPathToId(endpointId, clusterId, eventId);\n}\n\nexport function clusterPathToId({ nodeId, endpointId, clusterId }: TypeFromSchema<typeof TlvClusterPath>) {\n return `${nodeId}/${endpointId}/${clusterId}`;\n}\n\nfunction isConcreteAttributePath(\n path: TypeFromSchema<typeof TlvAttributePath>,\n): path is TypeFromSchema<typeof TlvAttributePath> & AttributePath {\n const { endpointId, clusterId, attributeId } = path;\n return endpointId !== undefined && clusterId !== undefined && attributeId !== undefined;\n}\n\nexport function validateReadAttributesPath(path: TypeFromSchema<typeof TlvAttributePath>, isGroupSession = false) {\n if (isGroupSession) {\n throw new StatusResponseError(\"Illegal read request with group session\", StatusCode.InvalidAction);\n }\n const { clusterId, attributeId } = path;\n if (clusterId === undefined && attributeId !== undefined) {\n if (!GLOBAL_IDS.has(attributeId)) {\n throw new StatusResponseError(\n `Illegal read request for wildcard cluster and non global attribute ${attributeId}`,\n StatusCode.InvalidAction,\n );\n }\n }\n}\n\nfunction validateWriteAttributesPath(path: TypeFromSchema<typeof TlvAttributePath>, isGroupSession = false) {\n const { endpointId, clusterId, attributeId } = path;\n if (clusterId === undefined || attributeId === undefined) {\n throw new StatusResponseError(\n \"Illegal write request with wildcard cluster or attribute ID\",\n StatusCode.InvalidAction,\n );\n }\n if (isGroupSession && endpointId !== undefined) {\n throw new StatusResponseError(\"Illegal write request with group ID and endpoint ID\", StatusCode.InvalidAction);\n }\n}\n\nfunction isConcreteEventPath(\n path: TypeFromSchema<typeof TlvEventPath>,\n): path is TypeFromSchema<typeof TlvEventPath> & EventPath {\n const { endpointId, clusterId, eventId } = path;\n return endpointId !== undefined && clusterId !== undefined && eventId !== undefined;\n}\n\nexport function validateReadEventPath(path: TypeFromSchema<typeof TlvEventPath>, isGroupSession = false) {\n const { clusterId, eventId } = path;\n if (clusterId === undefined && eventId !== undefined) {\n throw new StatusResponseError(\"Illegal read request with wildcard cluster ID\", StatusCode.InvalidAction);\n }\n if (isGroupSession) {\n throw new StatusResponseError(\"Illegal read request with group session\", StatusCode.InvalidAction);\n }\n}\n\nfunction isConcreteCommandPath(\n path: TypeFromSchema<typeof TlvCommandPath>,\n): path is TypeFromSchema<typeof TlvCommandPath> & CommandPath {\n const { endpointId, clusterId, commandId } = path;\n return endpointId !== undefined && clusterId !== undefined && commandId !== undefined;\n}\n\nfunction validateCommandPath(path: TypeFromSchema<typeof TlvCommandPath>, isGroupSession = false) {\n const { endpointId, clusterId, commandId } = path;\n if (clusterId === undefined || commandId === undefined) {\n throw new StatusResponseError(\n \"Illegal write request with wildcard cluster or attribute ID\",\n StatusCode.InvalidAction,\n );\n }\n if (isGroupSession && endpointId !== undefined) {\n throw new StatusResponseError(\"Illegal write request with group ID and endpoint ID\", StatusCode.InvalidAction);\n }\n}\n\n/**\n * Translates interactions from the Matter protocol to Matter.js APIs.\n */\nexport class InteractionServer implements ProtocolHandler<MatterDevice>, InteractionRecipient {\n #endpointStructure;\n #nextSubscriptionId = Crypto.getRandomUInt32();\n readonly #subscriptionMap = new Map<number, SubscriptionHandler>();\n #isClosing = false;\n #subscriptionConfig: SubscriptionOptions.Configuration;\n #eventHandler: EventHandler;\n\n constructor({ subscriptionOptions, eventHandler, endpointStructure }: InteractionServer.Configuration) {\n this.#subscriptionConfig = SubscriptionOptions.configurationFor(subscriptionOptions);\n this.#eventHandler = eventHandler;\n this.#endpointStructure = endpointStructure;\n\n this.#endpointStructure.change.on(() => {\n for (const subscription of this.#subscriptionMap.values()) {\n subscription.updateSubscription();\n }\n });\n }\n\n getId() {\n return INTERACTION_PROTOCOL_ID;\n }\n\n protected get isClosing() {\n return this.#isClosing;\n }\n\n async onNewExchange(exchange: MessageExchange<MatterDevice>) {\n // Note - changes here must be copied to TransactionalInteractionServer as it does not call super() to avoid\n // the stack frame\n if (this.#isClosing) return; // We are closing, ignore anything newly incoming\n await new InteractionServerMessenger(exchange).handleRequest(this);\n }\n\n async handleReadRequest(\n exchange: MessageExchange<MatterDevice>,\n {\n attributeRequests,\n dataVersionFilters,\n eventRequests,\n eventFilters,\n isFabricFiltered,\n interactionModelRevision,\n }: ReadRequest,\n message: Message,\n ): Promise<DataReportPayload> {\n logger.debug(\n `Received read request from ${exchange.channel.name}: attributes:${\n attributeRequests?.map(path => this.#endpointStructure.resolveAttributeName(path)).join(\", \") ?? \"none\"\n }, events:${\n eventRequests?.map(path => this.#endpointStructure.resolveEventName(path)).join(\", \") ?? \"none\"\n } isFabricFiltered=${isFabricFiltered}`,\n );\n\n if (interactionModelRevision > INTERACTION_MODEL_REVISION) {\n logger.debug(\n `Interaction model revision of sender ${interactionModelRevision} is higher than supported ${INTERACTION_MODEL_REVISION}.`,\n );\n }\n if (attributeRequests === undefined && eventRequests === undefined) {\n throw new StatusResponseError(\n \"Only Read requests with attributeRequests or eventRequests are supported right now\",\n StatusCode.UnsupportedRead,\n );\n }\n\n if (message.packetHeader.sessionType !== SessionType.Unicast) {\n throw new StatusResponseError(\n \"Subscriptions are only allowed on unicast sessions\",\n StatusCode.InvalidAction,\n );\n }\n\n const dataVersionFilterMap = new Map<string, number>(\n dataVersionFilters?.map(({ path, dataVersion }) => [clusterPathToId(path), dataVersion]) ?? [],\n );\n if (dataVersionFilterMap.size > 0) {\n logger.debug(\n `DataVersionFilters: ${Array.from(dataVersionFilterMap.entries())\n .map(([path, version]) => `${path}=${version}`)\n .join(\", \")}`,\n );\n }\n\n const attributeReportsPayload = new Array<AttributeReportPayload>();\n for (const requestPath of attributeRequests ?? []) {\n validateReadAttributesPath(requestPath);\n\n const attributes = this.#endpointStructure.getAttributes([requestPath]);\n\n // Requested attribute path not found in any cluster server on any endpoint\n if (attributes.length === 0) {\n // TODO Add checks for nodeId -> UnknownNode\n if (!isConcreteAttributePath(requestPath)) {\n // Wildcard path and we do not know any of the attributes: Ignore the error\n logger.debug(\n `Read from ${exchange.channel.name}: ${this.#endpointStructure.resolveAttributeName(\n requestPath,\n )}: ${this.#endpointStructure.resolveAttributeName(requestPath)}: ignore non-existing attribute`,\n );\n } else {\n const { endpointId, clusterId, attributeId } = requestPath;\n // Concrete path, but still unknown for us, so generate the right error status\n tryCatch(\n () => {\n this.#endpointStructure.validateConcreteAttributePath(endpointId, clusterId, attributeId);\n throw new InternalError(\n \"validateConcreteAttributePath should throw StatusResponseError but did not.\",\n );\n },\n StatusResponseError,\n error => {\n logger.debug(\n `Error reading attribute from ${\n exchange.channel.name\n }: ${this.#endpointStructure.resolveAttributeName(requestPath)}: unsupported path: Status=${\n error.code\n }`,\n );\n attributeReportsPayload.push({\n attributeStatus: { path: requestPath, status: { status: error.code } },\n });\n },\n );\n }\n continue;\n }\n\n // Process all known attributes for the given path\n for (const { path, attribute } of attributes) {\n const { nodeId, endpointId, clusterId } = path;\n\n try {\n const { value, version } = await tryCatchAsync(\n async () =>\n this.readAttribute(\n path,\n attribute,\n exchange,\n isFabricFiltered,\n message,\n this.#endpointStructure.getEndpoint(endpointId)!,\n ),\n NoAssociatedFabricError,\n async () => {\n // TODO: Remove when we remove legacy API\n // This is not fully correct but should be sufficient for now\n // This is fixed in the new API already, so this error should never throw\n // Fabric scoped attributes are access errors, fabric sensitive attributes are just filtered\n // Assume for now that in this place we only need to handle fabric sensitive case\n if (endpointId === undefined || clusterId === undefined) {\n throw new MatterFlowError(\"Should never happen\");\n }\n const cluster = this.#endpointStructure.getClusterServer(endpointId, clusterId);\n if (cluster === undefined || cluster.datasource == undefined) {\n throw new MatterFlowError(\"Should never happen\");\n }\n return {\n version: cluster.datasource.version,\n value: [],\n };\n },\n );\n\n const versionFilterValue =\n endpointId !== undefined && clusterId !== undefined\n ? dataVersionFilterMap.get(clusterPathToId({ nodeId, endpointId, clusterId }))\n : undefined;\n if (versionFilterValue !== undefined && versionFilterValue === version) {\n logger.debug(\n `Read attribute from ${exchange.channel.name}: ${this.#endpointStructure.resolveAttributeName(\n path,\n )}=${Logger.toJSON(value)} (version=${version}) ignored because of dataVersionFilter`,\n );\n continue;\n }\n\n logger.debug(\n `Read attribute from ${exchange.channel.name}: ${this.#endpointStructure.resolveAttributeName(\n path,\n )}=${Logger.toJSON(value)} (version=${version})`,\n );\n\n const { schema } = attribute;\n attributeReportsPayload.push({\n attributeData: { path, dataVersion: version, payload: value, schema },\n });\n } catch (error) {\n logger.error(\n `Error while reading attribute from ${\n exchange.channel.name\n } to ${this.#endpointStructure.resolveAttributeName(path)}:`,\n error,\n );\n if (error instanceof StatusResponseError) {\n // Add StatusResponseErrors, but only when the initial path was concrete, else error are ignored\n if (isConcreteAttributePath(requestPath)) {\n attributeReportsPayload.push({ attributeStatus: { path, status: { status: error.code } } });\n }\n } else {\n throw error;\n }\n }\n }\n }\n\n let eventReportsPayload: undefined | EventReportPayload[];\n if (eventRequests) {\n eventReportsPayload = [];\n for (const requestPath of eventRequests) {\n validateReadEventPath(requestPath);\n\n const events = this.#endpointStructure.getEvents([requestPath]);\n\n // Requested event path not found in any cluster server on any endpoint\n if (events.length === 0) {\n // TODO Add checks for nodeId\n if (!isConcreteEventPath(requestPath)) {\n // Wildcard path: Just leave out values\n logger.debug(\n `Read event from ${exchange.channel.name}: ${this.#endpointStructure.resolveEventName(\n requestPath,\n )}: ignore non-existing event`,\n );\n } else {\n const { endpointId, clusterId, eventId } = requestPath;\n tryCatch(\n () => {\n this.#endpointStructure.validateConcreteEventPath(endpointId, clusterId, eventId);\n throw new InternalError(\n \"validateConcreteEventPath should throw StatusResponseError but did not.\",\n );\n },\n StatusResponseError,\n error => {\n logger.debug(\n `Read event from ${\n exchange.channel.name\n }: ${this.#endpointStructure.resolveEventName(requestPath)}: unsupported path: Status=${\n error.code\n }`,\n );\n eventReportsPayload?.push({\n eventStatus: { path: requestPath, status: { status: error.code } },\n });\n },\n );\n }\n continue;\n }\n\n const reportsForPath = new Array<{ eventData: EventDataPayload }>();\n for (const { path, event } of events) {\n try {\n const { endpointId } = path;\n const matchingEvents = await this.readEvent(\n path,\n eventFilters,\n event,\n exchange,\n isFabricFiltered,\n message,\n this.#endpointStructure.getEndpoint(endpointId)!,\n );\n logger.debug(\n `Read event from ${exchange.channel.name}: ${this.#endpointStructure.resolveEventName(\n path,\n )}=${Logger.toJSON(matchingEvents)}`,\n );\n const { schema } = event;\n reportsForPath.push(\n ...matchingEvents.map(({ eventNumber, priority, epochTimestamp, data }) => ({\n eventData: {\n path,\n eventNumber,\n priority,\n epochTimestamp,\n payload: data,\n schema,\n },\n })),\n );\n } catch (error) {\n logger.error(\n `Error while reading event from ${\n exchange.channel.name\n } to ${this.#endpointStructure.resolveEventName(path)}:`,\n error,\n );\n if (error instanceof StatusResponseError) {\n // Add StatusResponseErrors, but only when the initial path was concrete, else error are ignored\n if (isConcreteEventPath(requestPath)) {\n eventReportsPayload?.push({ eventStatus: { path, status: { status: error.code } } });\n }\n } else {\n throw error;\n }\n }\n }\n eventReportsPayload.push(\n ...reportsForPath.sort((a, b) => {\n const eventNumberA = a.eventData?.eventNumber ?? EventNumber(0);\n const eventNumberB = b.eventData?.eventNumber ?? EventNumber(0);\n if (eventNumberA > eventNumberB) {\n return 1;\n } else if (eventNumberA < eventNumberB) {\n return -1;\n } else {\n return 0;\n }\n }),\n );\n }\n }\n\n // TODO support suppressResponse for responses\n return {\n interactionModelRevision: INTERACTION_MODEL_REVISION,\n suppressResponse: false,\n attributeReportsPayload, // TODO Return compressed response once https://github.com/project-chip/connectedhomeip/issues/29359 is solved\n eventReportsPayload,\n };\n }\n\n protected async readAttribute(\n _path: AttributePath,\n attribute: AnyAttributeServer<any>,\n exchange: MessageExchange<MatterDevice>,\n isFabricFiltered: boolean,\n message: Message,\n _endpoint: EndpointInterface,\n ) {\n return attribute.getWithVersion(exchange.session, isFabricFiltered, message);\n }\n\n protected async readEvent(\n _path: EventPath,\n eventFilters: TypeFromSchema<typeof TlvEventFilter>[] | undefined,\n event: EventServer<any, any>,\n exchange: MessageExchange<MatterDevice>,\n isFabricFiltered: boolean,\n message: Message,\n _endpoint: EndpointInterface,\n ) {\n return event.get(exchange.session, isFabricFiltered, message, eventFilters);\n }\n\n async handleWriteRequest(\n exchange: MessageExchange<MatterDevice>,\n { suppressResponse, timedRequest, writeRequests, interactionModelRevision, moreChunkedMessages }: WriteRequest,\n message: Message,\n ): Promise<WriteResponse> {\n const sessionType = message.packetHeader.sessionType;\n logger.debug(\n `Received write request from ${exchange.channel.name}: ${writeRequests\n .map(req => this.#endpointStructure.resolveAttributeName(req.path))\n .join(\", \")}, suppressResponse=${suppressResponse}, moreChunkedMessages=${moreChunkedMessages}`,\n );\n\n if (moreChunkedMessages && suppressResponse) {\n throw new StatusResponseError(\n \"MoreChunkedMessages and SuppressResponse cannot be used together in write messages\",\n StatusCode.InvalidAction,\n );\n }\n\n if (interactionModelRevision > INTERACTION_MODEL_REVISION) {\n logger.debug(\n `Interaction model revision of sender ${interactionModelRevision} is higher than supported ${INTERACTION_MODEL_REVISION}.`,\n );\n }\n\n const receivedWithinTimedInteraction = exchange.hasActiveTimedInteraction();\n\n if (receivedWithinTimedInteraction && moreChunkedMessages) {\n throw new StatusResponseError(\n \"Write Request action that is part of a Timed Write Interaction SHALL NOT be chunked.\",\n StatusCode.InvalidAction,\n );\n }\n\n if (exchange.hasExpiredTimedInteraction()) {\n exchange.clearTimedInteraction(); // ??\n throw new StatusResponseError(`Timed request window expired. Decline write request.`, StatusCode.Timeout);\n }\n\n if (timedRequest !== exchange.hasTimedInteraction()) {\n throw new StatusResponseError(\n `timedRequest flag of write interaction (${timedRequest}) mismatch with expected timed interaction (${receivedWithinTimedInteraction}).`,\n StatusCode.TimedRequestMismatch,\n );\n }\n\n if (receivedWithinTimedInteraction) {\n logger.debug(`Write request from ${exchange.channel.name} received while timed interaction is running.`);\n exchange.clearTimedInteraction();\n if (sessionType !== SessionType.Unicast) {\n throw new StatusResponseError(\n \"Write requests are only allowed on unicast sessions when a timed interaction is running.\",\n StatusCode.InvalidAction,\n ); // ???\n }\n }\n\n if (sessionType === SessionType.Group && !suppressResponse) {\n throw new StatusResponseError(\n \"Write requests are only allowed as group casts when suppressResponse=true.\",\n StatusCode.InvalidAction,\n ); // ???\n }\n\n const writeData = expandPathsInAttributeData(writeRequests, true);\n\n const writeResults = new Array<{\n path: TypeFromSchema<typeof TlvAttributePath>;\n statusCode: StatusCode;\n clusterStatusCode?: number;\n }>();\n const attributeListWrites = new Set<AttributeServer<any>>();\n const clusterDataVersionInfo = new Map<string, number>();\n const inaccessiblePaths = new Set<string>();\n\n // TODO Add handling for moreChunkedMessages here when adopting for Matter 1.3\n\n for (const writeRequest of writeData) {\n const { path: writePath, dataVersion } = writeRequest;\n const { listIndex } = writePath;\n\n validateWriteAttributesPath(writePath);\n\n const attributes = this.#endpointStructure.getAttributes([writePath], true);\n\n // No existing attribute matches the given path and is writable\n if (attributes.length === 0) {\n // TODO: Also check nodeId\n if (!isConcreteAttributePath(writePath)) {\n // Wildcard path: Just ignore\n logger.debug(\n `Write from ${exchange.channel.name}: ${this.#endpointStructure.resolveAttributeName(\n writePath,\n )}: ignore non-existing (wildcard) attribute`,\n );\n } else {\n const { endpointId, clusterId, attributeId } = writePath;\n\n // was a concrete path\n tryCatch(\n () => {\n if (\n this.#endpointStructure.validateConcreteAttributePath(\n endpointId,\n clusterId,\n attributeId,\n )\n ) {\n throw new StatusResponseError(\n `Attribute ${attributeId} is not writable.`,\n StatusCode.UnsupportedWrite,\n );\n }\n throw new InternalError(\n \"validateConcreteAttributePath check should throw StatusResponseError but did not.\",\n );\n },\n StatusResponseError,\n error => {\n logger.debug(\n `Write from ${exchange.channel.name}: ${this.#endpointStructure.resolveAttributeName(\n writePath,\n )} not allowed: Status=${error.code}`,\n );\n writeResults.push({ path: writePath, statusCode: error.code });\n },\n );\n }\n continue;\n }\n\n // Concrete path and found and writable\n if (attributes.length === 1 && isConcreteAttributePath(writePath)) {\n const { endpointId, clusterId } = writePath;\n const { attribute } = attributes[0];\n\n if (attribute.requiresTimedInteraction && !receivedWithinTimedInteraction) {\n logger.debug(`This write requires a timed interaction which is not initialized.`);\n writeResults.push({ path: writePath, statusCode: StatusCode.NeedsTimedInteraction });\n continue;\n }\n\n if (\n attribute instanceof FabricScopedAttributeServer &&\n (!exchange.session.isSecure || !(exchange.session as SecureSession<MatterDevice>).fabric)\n ) {\n logger.debug(`This write requires a secure session with a fabric assigned which is missing.`);\n writeResults.push({ path: writePath, statusCode: StatusCode.UnsupportedAccess });\n continue;\n }\n\n // Check the provided dataVersion with the dataVersion of the cluster\n // And remember this initial dataVersion for all checks inside this write transaction to allow proper\n // processing of chunked lists\n if (dataVersion !== undefined) {\n const datasource = this.#endpointStructure.getClusterServer(endpointId, clusterId)?.datasource;\n const { nodeId } = writePath;\n const clusterKey = clusterPathToId({ nodeId, endpointId, clusterId });\n const currentDataVersion = clusterDataVersionInfo.get(clusterKey) ?? datasource?.version;\n\n if (currentDataVersion !== undefined) {\n if (dataVersion !== currentDataVersion) {\n logger.debug(\n `This write requires a specific data version (${dataVersion}) which do not match the current cluster data version (${currentDataVersion}).`,\n );\n writeResults.push({ path: writePath, statusCode: StatusCode.DataVersionMismatch });\n continue;\n }\n clusterDataVersionInfo.set(clusterKey, currentDataVersion);\n }\n }\n }\n\n for (const { path, attribute } of attributes) {\n const { schema, defaultValue } = attribute;\n const pathId = attributePathToId(path);\n\n try {\n if (\n !(attribute instanceof AttributeServer) &&\n !(attribute instanceof FabricScopedAttributeServer)\n ) {\n throw new StatusResponseError(\n \"Fixed attributes cannot be written\",\n StatusCode.UnsupportedWrite,\n );\n }\n\n if (inaccessiblePaths.has(pathId)) {\n logger.debug(`This write is not allowed due to previous access denied.`);\n continue;\n }\n\n const { endpointId } = path;\n const value =\n listIndex === undefined\n ? decodeAttributeValueWithSchema(schema, [writeRequest], defaultValue)\n : decodeListAttributeValueWithSchema(\n schema,\n [writeRequest],\n (\n await this.readAttribute(\n path,\n attribute,\n exchange,\n true,\n message,\n this.#endpointStructure.getEndpoint(endpointId)!,\n )\n ).value ?? defaultValue,\n );\n logger.debug(\n `Handle write request from ${\n exchange.channel.name\n } resolved to: ${this.#endpointStructure.resolveAttributeName(path)}=${Logger.toJSON(\n value,\n )} (listIndex=${listIndex}, for-version=${dataVersion})`,\n );\n\n if (attribute.requiresTimedInteraction && !receivedWithinTimedInteraction) {\n logger.debug(`This write requires a timed interaction which is not initialized.`);\n throw new StatusResponseError(\n \"This write requires a timed interaction which is not initialized.\",\n StatusCode.NeedsTimedInteraction,\n );\n }\n\n await this.writeAttribute(\n path,\n attribute,\n value,\n exchange,\n message,\n this.#endpointStructure.getEndpoint(endpointId)!,\n receivedWithinTimedInteraction,\n schema instanceof ArraySchema,\n );\n if (schema instanceof ArraySchema && !attributeListWrites.has(attribute)) {\n attributeListWrites.add(attribute);\n }\n } catch (error: any) {\n if (error instanceof StatusResponseError && error.code === StatusCode.UnsupportedAccess) {\n inaccessiblePaths.add(pathId);\n }\n if (attributes.length === 1 && isConcreteAttributePath(writePath)) {\n // For Multi-Attribute-Writes we ignore errors\n logger.error(\n `Error while handling write request from ${\n exchange.channel.name\n } to ${this.#endpointStructure.resolveAttributeName(path)}:`,\n error instanceof StatusResponseError ? error.message : error,\n );\n if (error instanceof StatusResponseError) {\n writeResults.push({ path, statusCode: error.code, clusterStatusCode: error.clusterCode });\n continue;\n }\n writeResults.push({ path, statusCode: StatusCode.ConstraintError });\n continue;\n } else {\n logger.debug(\n `While handling write request from ${\n exchange.channel.name\n } to ${this.#endpointStructure.resolveAttributeName(path)} ignored: ${error.message}`,\n );\n\n // TODO - This behavior may be wrong.\n //\n // If a wildcard write fails we should either:\n //\n // 1. Ignore entirely (add nothing to write results), or\n // 2. Add an error response for the concrete attribute that failed.\n //\n // Spec is a little ambiguous. After request path expansion, in core 1.2 8.7.3.2 it states:\n //\n // \"If the path indicates attribute data that is not writable, then the path SHALL be\n // discarded\"\n //\n // So is this \"not writable\" -- so it should be #1 -- or is this \"writable\" but with invalid\n // data? The latter is error case #2 but spec doesn't make clear what the status code would\n // be... We could fall back to CONSTRAINT_ERROR like we do above though\n //\n // Currently what we do is add a success response for every concrete path that fails.\n }\n }\n writeResults.push({ path, statusCode: StatusCode.Success });\n }\n //.filter(({ statusCode }) => statusCode !== StatusCode.Success); // see https://github.com/project-chip/connectedhomeip/issues/26198\n }\n\n const errorResults = writeResults.filter(({ statusCode }) => statusCode !== StatusCode.Success);\n logger.debug(\n `Write request from ${exchange.channel.name} done ${\n errorResults.length\n ? `with following errors: ${errorResults\n .map(\n ({ path, statusCode }) =>\n `${this.#endpointStructure.resolveAttributeName(path)}=${Logger.toJSON(statusCode)}`,\n )\n .join(\", \")}`\n : \"without errors\"\n }`,\n );\n\n const response = {\n interactionModelRevision: INTERACTION_MODEL_REVISION,\n writeResponses: writeResults.map(({ path, statusCode, clusterStatusCode }) => ({\n path,\n status: { status: statusCode, clusterStatus: clusterStatusCode },\n })),\n };\n\n // Trigger attribute events for delayed list writes\n for (const attribute of attributeListWrites.values()) {\n try {\n attribute.triggerDelayedChangeEvents();\n } catch (error) {\n logger.error(\n `Ignored Error while writing attribute from ${exchange.channel.name} to ${attribute.name}:`,\n error,\n );\n }\n }\n\n return response;\n }\n\n protected async writeAttribute(\n _path: AttributePath,\n attribute: AttributeServer<any>,\n value: any,\n exchange: MessageExchange<MatterDevice>,\n message: Message,\n _endpoint: EndpointInterface,\n _receivedWithinTimedInteraction?: boolean,\n isListWrite = false,\n ) {\n attribute.set(value, exchange.session, message, isListWrite);\n }\n\n async handleSubscribeRequest(\n exchange: MessageExchange<MatterDevice>,\n {\n minIntervalFloorSeconds,\n maxIntervalCeilingSeconds,\n attributeRequests,\n dataVersionFilters,\n eventRequests,\n eventFilters,\n keepSubscriptions,\n isFabricFiltered,\n interactionModelRevision,\n }: SubscribeRequest,\n messenger: InteractionServerMessenger,\n message: Message,\n ): Promise<void> {\n logger.debug(\n `Received subscribe request from ${exchange.channel.name} (keepSubscriptions=${keepSubscriptions}, isFabricFiltered=${isFabricFiltered})`,\n );\n\n if (interactionModelRevision > INTERACTION_MODEL_REVISION) {\n logger.debug(\n `Interaction model revision of sender ${interactionModelRevision} is higher than supported ${INTERACTION_MODEL_REVISION}.`,\n );\n }\n\n if (message.packetHeader.sessionType !== SessionType.Unicast) {\n throw new StatusResponseError(\n \"Subscriptions are only allowed on unicast sessions\",\n StatusCode.InvalidAction,\n );\n }\n\n assertSecureSession(exchange.session, \"Subscriptions are only implemented on secure sessions\");\n const session = exchange.session;\n const fabric = session.fabric;\n if (fabric === undefined)\n throw new StatusResponseError(\n \"Subscriptions are only implemented after a fabric has been assigned\",\n StatusCode.InvalidAction,\n );\n\n if (\n (!Array.isArray(attributeRequests) || attributeRequests.length === 0) &&\n (!Array.isArray(eventRequests) || eventRequests.length === 0)\n ) {\n throw new StatusResponseError(\"No attributes or events requested\", StatusCode.InvalidAction);\n }\n\n logger.debug(\n `Subscribe to attributes:${\n attributeRequests?.map(path => this.#endpointStructure.resolveAttributeName(path)).join(\", \") ?? \"none\"\n }, events:${\n eventRequests?.map(path => this.#endpointStructure.resolveEventName(path)).join(\", \") ?? \"none\"\n }`,\n );\n\n if (dataVersionFilters !== undefined && dataVersionFilters.length > 0) {\n logger.debug(\n `DataVersionFilters: ${dataVersionFilters\n .map(\n ({ path: { nodeId, endpointId, clusterId }, dataVersion }) =>\n `${clusterPathToId({ nodeId, endpointId, clusterId })}=${dataVersion}`,\n )\n .join(\", \")}`,\n );\n }\n if (eventFilters !== undefined && eventFilters.length > 0)\n logger.debug(\n `Event filters: ${eventFilters.map(filter => `${filter.nodeId}/${filter.eventMin}`).join(\", \")}`,\n );\n\n // Validate of the paths before proceeding\n attributeRequests?.forEach(path => validateReadAttributesPath(path));\n eventRequests?.forEach(path => validateReadEventPath(path));\n\n if (minIntervalFloorSeconds < 0) {\n throw new StatusResponseError(\n \"minIntervalFloorSeconds should be greater or equal to 0\",\n StatusCode.InvalidAction,\n );\n }\n if (maxIntervalCeilingSeconds < 0) {\n throw new StatusResponseError(\n \"maxIntervalCeilingSeconds should be greater or equal to 1\",\n StatusCode.InvalidAction,\n );\n }\n if (maxIntervalCeilingSeconds < minIntervalFloorSeconds) {\n throw new StatusResponseError(\n \"maxIntervalCeilingSeconds should be greater or equal to minIntervalFloorSeconds\",\n StatusCode.InvalidAction,\n );\n }\n\n // TODO: Interpret specs:\n // The publisher SHALL compute an appropriate value for the MaxInterval field in the action. This SHALL respect the following constraint: MinIntervalFloor \u2264 MaxInterval \u2264 MAX(SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT=60mn, MaxIntervalCeiling)\n\n if (this.#nextSubscriptionId === 0xffffffff) this.#nextSubscriptionId = 0;\n const subscriptionId = this.#nextSubscriptionId++;\n const subscriptionHandler = new SubscriptionHandler(\n subscriptionId,\n session,\n this.#endpointStructure,\n attributeRequests,\n dataVersionFilters,\n eventRequests,\n eventFilters,\n this.#eventHandler,\n isFabricFiltered,\n minIntervalFloorSeconds,\n maxIntervalCeilingSeconds,\n () => this.#subscriptionMap.delete(subscriptionId),\n this.#subscriptionConfig,\n );\n\n try {\n // Send initial data report to prime the subscription with initial data\n await subscriptionHandler.sendInitialReport(\n messenger,\n (path, attribute) =>\n this.readAttribute(\n path,\n attribute,\n exchange,\n isFabricFiltered,\n message,\n this.#endpointStructure.getEndpoint(path.endpointId)!,\n ),\n (path, event, eventFilters) =>\n this.readEvent(\n path,\n eventFilters,\n event,\n exchange,\n isFabricFiltered,\n message,\n this.#endpointStructure.getEndpoint(path.endpointId)!,\n ),\n );\n } catch (error: any) {\n logger.error(\n `Subscription ${subscriptionId} for Session ${session.id}: Error while sending initial data reports`,\n error,\n );\n await subscriptionHandler.cancel(); // Cleanup\n if (error instanceof StatusResponseError) {\n logger.info(`Sending status response ${error.code} for interaction error: ${error.message}`);\n await messenger.sendStatus(error.code);\n }\n await messenger.close();\n return; // Make sure to not bubble up the exception\n }\n\n if (!keepSubscriptions) {\n logger.debug(`Clear subscriptions for Session ${session.name} because keepSubscriptions=false`);\n await session.clearSubscriptions(true);\n }\n\n const maxInterval = subscriptionHandler.getMaxInterval();\n logger.info(\n `Successfully created subscription ${subscriptionId} for Session ${\n session.id\n }. Updates: ${minIntervalFloorSeconds} - ${maxIntervalCeilingSeconds} => ${maxInterval} seconds (sendInterval = ${subscriptionHandler.getSendInterval()} seconds)`,\n );\n // Then send the subscription response\n await messenger.send(\n MessageType.SubscribeResponse,\n TlvSubscribeResponse.encode({\n subscriptionId,\n maxInterval,\n interactionModelRevision: INTERACTION_MODEL_REVISION,\n }),\n );\n\n this.#subscriptionMap.set(subscriptionId, subscriptionHandler);\n session.addSubscription(subscriptionHandler);\n subscriptionHandler.activateSendingUpdates();\n }\n\n async handleInvokeRequest(\n exchange: MessageExchange<MatterDevice>,\n { invokeRequests, timedRequest, suppressResponse, interactionModelRevision }: InvokeRequest,\n message: Message,\n ): Promise<InvokeResponse> {\n logger.debug(\n `Received invoke request from ${exchange.channel.name}: ${invokeRequests\n .map(({ commandPath: { endpointId, clusterId, commandId } }) =>\n this.#endpointStructure.resolveCommandName({ endpointId, clusterId, commandId }),\n )\n .join(\", \")}, suppressResponse=${suppressResponse}`,\n );\n\n if (interactionModelRevision > INTERACTION_MODEL_REVISION) {\n logger.debug(\n `Interaction model revision of sender ${interactionModelRevision} is higher than supported ${INTERACTION_MODEL_REVISION}.`,\n );\n }\n\n const receivedWithinTimedInteraction = exchange.hasActiveTimedInteraction();\n if (exchange.hasExpiredTimedInteraction()) {\n exchange.clearTimedInteraction(); // ??\n throw new StatusResponseError(`Timed request window expired. Decline invoke request.`, StatusCode.Timeout);\n }\n\n if (timedRequest !== exchange.hasTimedInteraction()) {\n throw new StatusResponseError(\n `timedRequest flag of invoke interaction (${timedRequest}) mismatch with expected timed interaction (${receivedWithinTimedInteraction}).`,\n StatusCode.TimedRequestMismatch,\n );\n }\n\n if (receivedWithinTimedInteraction) {\n logger.debug(`Invoke request from ${exchange.channel.name} received while timed interaction is running.`);\n exchange.clearTimedInteraction();\n if (message.packetHeader.sessionType !== SessionType.Unicast) {\n throw new StatusResponseError(\n \"Invoke requests are only allowed on unicast sessions when a timed interaction is running.\",\n StatusCode.InvalidAction,\n ); // ???\n }\n }\n\n if (invokeRequests.length > 1) {\n throw new StatusResponseError(\"Multi-command invoke requests are not supported\", StatusCode.InvalidAction);\n }\n\n invokeRequests.forEach(({ commandPath }) => validateCommandPath(commandPath));\n\n const invokeResponses: TypeFromSchema<typeof TlvInvokeResponseData>[] = [];\n\n await Promise.all(\n invokeRequests.flatMap(async ({ commandPath, commandFields }) => {\n const commands = this.#endpointStructure.getCommands([commandPath]);\n\n // TODO also check ACL and Timed, Fabric scoping constrains\n\n if (commands.length === 0) {\n // TODO Also check nodeId\n if (!isConcreteCommandPath(commandPath)) {\n // Wildcard path: Just ignore\n logger.debug(\n `Invoke from ${exchange.channel.name}: ${this.#endpointStructure.resolveCommandName(\n commandPath,\n )} ignore non-existing attribute`,\n );\n } else {\n const { endpointId, clusterId, commandId } = commandPath;\n invokeResponses.push(\n tryCatch(\n () => {\n this.#endpointStructure.validateConcreteCommandPath(\n endpointId,\n clusterId,\n commandId,\n );\n throw new InternalError(\n \"validateConcreteCommandPath should throw StatusResponseError but did not.\",\n );\n },\n StatusResponseError,\n error => {\n logger.debug(\n `Invoke from ${\n exchange.channel.name\n }: ${this.#endpointStructure.resolveCommandName(\n commandPath,\n )} unsupported path: Status=${error.code}`,\n );\n return { status: { commandPath, status: { status: error.code } } };\n },\n ),\n );\n }\n return;\n }\n\n for (const { command, path } of commands) {\n const { endpointId } = path;\n if (endpointId === undefined) {\n // Should never happen\n logger.error(\n `Invoke from ${exchange.channel.name}: ${this.#endpointStructure.resolveCommandName(\n path,\n )} invalid path because empty endpoint!`,\n );\n invokeResponses.push({\n status: { commandPath: path, status: { status: StatusCode.UnsupportedEndpoint } },\n });\n continue;\n }\n const endpoint = this.#endpointStructure.getEndpoint(endpointId);\n if (endpoint === undefined) {\n // Should never happen\n logger.error(\n `Invoke from ${exchange.channel.name}: ${this.#endpointStructure.resolveCommandName(\n path,\n )} invalid path because endpoint not found!`,\n );\n invokeResponses.push({\n status: { commandPath: path, status: { status: StatusCode.UnsupportedEndpoint } },\n });\n continue;\n }\n if (command.requiresTimedInteraction && !receivedWithinTimedInteraction) {\n logger.debug(`This invoke requires a timed interaction which is not initialized.`);\n invokeResponses.push({\n status: { commandPath: path, status: { status: StatusCode.NeedsTimedInteraction } },\n });\n continue;\n }\n\n const result = await tryCatchAsync(\n async () =>\n await this.invokeCommand(\n path,\n command,\n exchange,\n commandFields ?? TlvNoArguments.encodeTlv(commandFields),\n message,\n endpoint,\n receivedWithinTimedInteraction,\n ),\n StatusResponseError,\n async error => {\n const errorLogText = `Error ${Diagnostic.hex(error.code)}${\n error.clusterCode !== undefined ? `/${Diagnostic.hex(error.clusterCode)}` : \"\"\n } while invoking command: ${error.message}`;\n if (error instanceof ValidationError) {\n logger.info(\n `Validation-${errorLogText}${error.fieldName !== undefined ? ` in field ${error.fieldName}` : \"\"}`,\n );\n } else {\n logger.info(errorLogText);\n }\n return {\n code: error.code,\n clusterCode: error.clusterCode,\n responseId: command.responseId,\n response: TlvNoResponse.encodeTlv(),\n };\n },\n );\n const { code, clusterCode, responseId, response } = result;\n if (response.length === 0) {\n invokeResponses.push({\n status: { commandPath: path, status: { status: code, clusterStatus: clusterCode } },\n });\n } else {\n invokeResponses.push({\n command: {\n commandPath: { ...path, commandId: responseId },\n commandFields: response,\n },\n });\n }\n }\n }),\n );\n\n // TODO support suppressResponse for responses\n return {\n suppressResponse: false,\n interactionModelRevision: INTERACTION_MODEL_REVISION,\n invokeResponses,\n };\n }\n\n protected async invokeCommand(\n _path: CommandPath,\n command: CommandServer<any, any>,\n exchange: MessageExchange<MatterDevice>,\n commandFields: any,\n message: Message,\n endpoint: EndpointInterface,\n _receivedWithinTimedInteraction = false,\n ) {\n return command.invoke(exchange.session, commandFields, message, endpoint);\n }\n\n handleTimedRequest(exchange: MessageExchange<MatterDevice>, { timeout, interactionModelRevision }: TimedRequest) {\n logger.debug(`Received timed request (${timeout}ms) from ${exchange.channel.name}`);\n\n if (interactionModelRevision > INTERACTION_MODEL_REVISION) {\n logger.debug(\n `Interaction model revision of sender ${interactionModelRevision} is higher than supported ${INTERACTION_MODEL_REVISION}.`,\n );\n }\n\n exchange.startTimedInteraction(timeout);\n }\n\n async close() {\n this.#isClosing = true;\n for (const subscription of this.#subscriptionMap.values()) {\n await subscription.cancel(true);\n }\n }\n}\n\nexport namespace InteractionServer {\n export interface Configuration {\n readonly subscriptionOptions?: SubscriptionOptions;\n readonly eventHandler: EventHandler;\n readonly endpointStructure: InteractionEndpointStructure;\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { MatterDevice } from \"../../MatterDevice.js\";\nimport { TlvNoResponse } from \"../../cluster/Cluster.js\";\nimport {\n AnyAttributeServer,\n AttributeServer,\n FabricScopedAttributeServer,\n} from \"../../cluster/server/AttributeServer.js\";\nimport { CommandServer } from \"../../cluster/server/CommandServer.js\";\nimport { EventServer } from \"../../cluster/server/EventServer.js\";\nimport { Message, SessionType } from \"../../codec/MessageCodec.js\";\nimport { InternalError, MatterFlowError } from \"../../common/MatterError.js\";\nimport { tryCatch, tryCatchAsync } from \"../../common/TryCatchHandler.js\";\nimport { ValidationError } from \"../../common/ValidationError.js\";\nimport { Crypto } from \"../../crypto/Crypto.js\";\nimport { AttributeId } from \"../../datatype/AttributeId.js\";\nimport { ClusterId } from \"../../datatype/ClusterId.js\";\nimport { CommandId } from \"../../datatype/CommandId.js\";\nimport { EndpointNumber } from \"../../datatype/EndpointNumber.js\";\nimport { EventId } from \"../../datatype/EventId.js\";\nimport { EventNumber } from \"../../datatype/EventNumber.js\";\nimport { NodeId } from \"../../datatype/NodeId.js\";\nimport { EndpointInterface } from \"../../endpoint/EndpointInterface.js\";\nimport { Diagnostic } from \"../../log/Diagnostic.js\";\nimport { Logger } from \"../../log/Logger.js\";\nimport { GLOBAL_IDS } from \"../../model/index.js\";\nimport { MessageExchange } from \"../../protocol/MessageExchange.js\";\nimport { ProtocolHandler } from \"../../protocol/ProtocolHandler.js\";\nimport { EventHandler } from \"../../protocol/interaction/EventHandler.js\";\nimport { NoAssociatedFabricError, SecureSession, assertSecureSession } from \"../../session/SecureSession.js\";\nimport { ArraySchema } from \"../../tlv/TlvArray.js\";\nimport { TlvNoArguments } from \"../../tlv/TlvNoArguments.js\";\nimport { TypeFromSchema } from \"../../tlv/TlvSchema.js\";\nimport {\n decodeAttributeValueWithSchema,\n decodeListAttributeValueWithSchema,\n expandPathsInAttributeData,\n} from \"./AttributeDataDecoder.js\";\nimport {\n AttributeReportPayload,\n DataReportPayload,\n EventDataPayload,\n EventReportPayload,\n} from \"./AttributeDataEncoder.js\";\nimport { InteractionEndpointStructure } from \"./InteractionEndpointStructure.js\";\nimport {\n InteractionRecipient,\n InteractionServerMessenger,\n InvokeRequest,\n InvokeResponse,\n MessageType,\n ReadRequest,\n SubscribeRequest,\n TimedRequest,\n WriteRequest,\n WriteResponse,\n} from \"./InteractionMessenger.js\";\nimport {\n TlvAttributePath,\n TlvClusterPath,\n TlvCommandPath,\n TlvEventFilter,\n TlvEventPath,\n TlvInvokeResponseData,\n TlvSubscribeResponse,\n} from \"./InteractionProtocol.js\";\nimport { StatusCode, StatusResponseError } from \"./StatusCode.js\";\nimport { SubscriptionHandler } from \"./SubscriptionHandler.js\";\nimport { SubscriptionOptions } from \"./SubscriptionOptions.js\";\n\n/** Protocol ID for the Interaction Protocol as per Matter specification. */\nexport const INTERACTION_PROTOCOL_ID = 0x0001;\n\n/** Backward compatible re-export for Interaction Model version we support currently. */\nexport const INTERACTION_MODEL_REVISION = 11;\n\n/** Number of Invoke Path setting from our Interaction model implementation. */\nexport const MAX_PATHS_PER_INVOKE = 1;\n\nconst logger = Logger.get(\"InteractionServer\");\n\nexport interface CommandPath {\n nodeId?: NodeId;\n endpointId: EndpointNumber;\n clusterId: ClusterId;\n commandId: CommandId;\n}\n\nexport interface AttributePath {\n nodeId?: NodeId;\n endpointId: EndpointNumber;\n clusterId: ClusterId;\n attributeId: AttributeId;\n}\n\nexport interface EventPath {\n nodeId?: NodeId;\n endpointId: EndpointNumber;\n clusterId: ClusterId;\n eventId: EventId;\n}\n\nexport interface AttributeWithPath {\n path: AttributePath;\n attribute: AnyAttributeServer<any>;\n}\n\nexport interface EventWithPath {\n path: EventPath;\n event: EventServer<any, any>;\n}\n\nexport interface CommandWithPath {\n path: CommandPath;\n command: CommandServer<any, any>;\n}\n\nexport function genericElementPathToId(\n endpointId: EndpointNumber | undefined,\n clusterId: ClusterId | undefined,\n elementId: number | undefined,\n) {\n return `${endpointId}/${clusterId}/${elementId}`;\n}\n\nexport function commandPathToId({ endpointId, clusterId, commandId }: CommandPath) {\n return genericElementPathToId(endpointId, clusterId, commandId);\n}\n\nexport function attributePathToId({ endpointId, clusterId, attributeId }: TypeFromSchema<typeof TlvAttributePath>) {\n return genericElementPathToId(endpointId, clusterId, attributeId);\n}\n\nexport function eventPathToId({ endpointId, clusterId, eventId }: TypeFromSchema<typeof TlvEventPath>) {\n return genericElementPathToId(endpointId, clusterId, eventId);\n}\n\nexport function clusterPathToId({ nodeId, endpointId, clusterId }: TypeFromSchema<typeof TlvClusterPath>) {\n return `${nodeId}/${endpointId}/${clusterId}`;\n}\n\nfunction isConcreteAttributePath(\n path: TypeFromSchema<typeof TlvAttributePath>,\n): path is TypeFromSchema<typeof TlvAttributePath> & AttributePath {\n const { endpointId, clusterId, attributeId } = path;\n return endpointId !== undefined && clusterId !== undefined && attributeId !== undefined;\n}\n\nexport function validateReadAttributesPath(path: TypeFromSchema<typeof TlvAttributePath>, isGroupSession = false) {\n if (isGroupSession) {\n throw new StatusResponseError(\"Illegal read request with group session\", StatusCode.InvalidAction);\n }\n const { clusterId, attributeId } = path;\n if (clusterId === undefined && attributeId !== undefined) {\n if (!GLOBAL_IDS.has(attributeId)) {\n throw new StatusResponseError(\n `Illegal read request for wildcard cluster and non global attribute ${attributeId}`,\n StatusCode.InvalidAction,\n );\n }\n }\n}\n\nfunction validateWriteAttributesPath(path: TypeFromSchema<typeof TlvAttributePath>, isGroupSession = false) {\n const { endpointId, clusterId, attributeId } = path;\n if (clusterId === undefined || attributeId === undefined) {\n throw new StatusResponseError(\n \"Illegal write request with wildcard cluster or attribute ID\",\n StatusCode.InvalidAction,\n );\n }\n if (isGroupSession && endpointId !== undefined) {\n throw new StatusResponseError(\"Illegal write request with group ID and endpoint ID\", StatusCode.InvalidAction);\n }\n}\n\nfunction isConcreteEventPath(\n path: TypeFromSchema<typeof TlvEventPath>,\n): path is TypeFromSchema<typeof TlvEventPath> & EventPath {\n const { endpointId, clusterId, eventId } = path;\n return endpointId !== undefined && clusterId !== undefined && eventId !== undefined;\n}\n\nexport function validateReadEventPath(path: TypeFromSchema<typeof TlvEventPath>, isGroupSession = false) {\n const { clusterId, eventId } = path;\n if (clusterId === undefined && eventId !== undefined) {\n throw new StatusResponseError(\"Illegal read request with wildcard cluster ID\", StatusCode.InvalidAction);\n }\n if (isGroupSession) {\n throw new StatusResponseError(\"Illegal read request with group session\", StatusCode.InvalidAction);\n }\n}\n\nfunction isConcreteCommandPath(\n path: TypeFromSchema<typeof TlvCommandPath>,\n): path is TypeFromSchema<typeof TlvCommandPath> & CommandPath {\n const { endpointId, clusterId, commandId } = path;\n return endpointId !== undefined && clusterId !== undefined && commandId !== undefined;\n}\n\nfunction validateCommandPath(path: TypeFromSchema<typeof TlvCommandPath>, isGroupSession = false) {\n const { endpointId, clusterId, commandId } = path;\n if (clusterId === undefined || commandId === undefined) {\n throw new StatusResponseError(\n \"Illegal write request with wildcard cluster or attribute ID\",\n StatusCode.InvalidAction,\n );\n }\n if (isGroupSession && endpointId !== undefined) {\n throw new StatusResponseError(\"Illegal write request with group ID and endpoint ID\", StatusCode.InvalidAction);\n }\n}\n\n/**\n * Translates interactions from the Matter protocol to Matter.js APIs.\n */\nexport class InteractionServer implements ProtocolHandler<MatterDevice>, InteractionRecipient {\n #endpointStructure;\n #nextSubscriptionId = Crypto.getRandomUInt32();\n readonly #subscriptionMap = new Map<number, SubscriptionHandler>();\n #isClosing = false;\n #subscriptionConfig: SubscriptionOptions.Configuration;\n #eventHandler: EventHandler;\n\n constructor({ subscriptionOptions, eventHandler, endpointStructure }: InteractionServer.Configuration) {\n this.#subscriptionConfig = SubscriptionOptions.configurationFor(subscriptionOptions);\n this.#eventHandler = eventHandler;\n this.#endpointStructure = endpointStructure;\n\n this.#endpointStructure.change.on(() => {\n for (const subscription of this.#subscriptionMap.values()) {\n subscription.updateSubscription();\n }\n });\n }\n\n getId() {\n return INTERACTION_PROTOCOL_ID;\n }\n\n protected get isClosing() {\n return this.#isClosing;\n }\n\n async onNewExchange(exchange: MessageExchange<MatterDevice>) {\n // Note - changes here must be copied to TransactionalInteractionServer as it does not call super() to avoid\n // the stack frame\n if (this.#isClosing) return; // We are closing, ignore anything newly incoming\n await new InteractionServerMessenger(exchange).handleRequest(this);\n }\n\n async handleReadRequest(\n exchange: MessageExchange<MatterDevice>,\n {\n attributeRequests,\n dataVersionFilters,\n eventRequests,\n eventFilters,\n isFabricFiltered,\n interactionModelRevision,\n }: ReadRequest,\n message: Message,\n ): Promise<DataReportPayload> {\n logger.debug(\n `Received read request from ${exchange.channel.name}: attributes:${\n attributeRequests?.map(path => this.#endpointStructure.resolveAttributeName(path)).join(\", \") ?? \"none\"\n }, events:${\n eventRequests?.map(path => this.#endpointStructure.resolveEventName(path)).join(\", \") ?? \"none\"\n } isFabricFiltered=${isFabricFiltered}`,\n );\n\n if (interactionModelRevision > INTERACTION_MODEL_REVISION) {\n logger.debug(\n `Interaction model revision of sender ${interactionModelRevision} is higher than supported ${INTERACTION_MODEL_REVISION}.`,\n );\n }\n if (attributeRequests === undefined && eventRequests === undefined) {\n throw new StatusResponseError(\n \"Only Read requests with attributeRequests or eventRequests are supported right now\",\n StatusCode.UnsupportedRead,\n );\n }\n\n if (message.packetHeader.sessionType !== SessionType.Unicast) {\n throw new StatusResponseError(\n \"Subscriptions are only allowed on unicast sessions\",\n StatusCode.InvalidAction,\n );\n }\n\n const dataVersionFilterMap = new Map<string, number>(\n dataVersionFilters?.map(({ path, dataVersion }) => [clusterPathToId(path), dataVersion]) ?? [],\n );\n if (dataVersionFilterMap.size > 0) {\n logger.debug(\n `DataVersionFilters: ${Array.from(dataVersionFilterMap.entries())\n .map(([path, version]) => `${path}=${version}`)\n .join(\", \")}`,\n );\n }\n\n const attributeReportsPayload = new Array<AttributeReportPayload>();\n for (const requestPath of attributeRequests ?? []) {\n validateReadAttributesPath(requestPath);\n\n const attributes = this.#endpointStructure.getAttributes([requestPath]);\n\n // Requested attribute path not found in any cluster server on any endpoint\n if (attributes.length === 0) {\n // TODO Add checks for nodeId -> UnknownNode\n if (!isConcreteAttributePath(requestPath)) {\n // Wildcard path and we do not know any of the attributes: Ignore the error\n logger.debug(\n `Read from ${exchange.channel.name}: ${this.#endpointStructure.resolveAttributeName(\n requestPath,\n )}: ${this.#endpointStructure.resolveAttributeName(requestPath)}: ignore non-existing attribute`,\n );\n } else {\n const { endpointId, clusterId, attributeId } = requestPath;\n // Concrete path, but still unknown for us, so generate the right error status\n tryCatch(\n () => {\n this.#endpointStructure.validateConcreteAttributePath(endpointId, clusterId, attributeId);\n throw new InternalError(\n \"validateConcreteAttributePath should throw StatusResponseError but did not.\",\n );\n },\n StatusResponseError,\n error => {\n logger.debug(\n `Error reading attribute from ${\n exchange.channel.name\n }: ${this.#endpointStructure.resolveAttributeName(requestPath)}: unsupported path: Status=${\n error.code\n }`,\n );\n attributeReportsPayload.push({\n attributeStatus: { path: requestPath, status: { status: error.code } },\n });\n },\n );\n }\n continue;\n }\n\n // Process all known attributes for the given path\n for (const { path, attribute } of attributes) {\n const { nodeId, endpointId, clusterId } = path;\n\n try {\n const { value, version } = await tryCatchAsync(\n async () =>\n this.readAttribute(\n path,\n attribute,\n exchange,\n isFabricFiltered,\n message,\n this.#endpointStructure.getEndpoint(endpointId)!,\n ),\n NoAssociatedFabricError,\n async () => {\n // TODO: Remove when we remove legacy API\n // This is not fully correct but should be sufficient for now\n // This is fixed in the new API already, so this error should never throw\n // Fabric scoped attributes are access errors, fabric sensitive attributes are just filtered\n // Assume for now that in this place we only need to handle fabric sensitive case\n if (endpointId === undefined || clusterId === undefined) {\n throw new MatterFlowError(\"Should never happen\");\n }\n const cluster = this.#endpointStructure.getClusterServer(endpointId, clusterId);\n if (cluster === undefined || cluster.datasource == undefined) {\n throw new MatterFlowError(\"Should never happen\");\n }\n return {\n version: cluster.datasource.version,\n value: [],\n };\n },\n );\n\n const versionFilterValue =\n endpointId !== undefined && clusterId !== undefined\n ? dataVersionFilterMap.get(clusterPathToId({ nodeId, endpointId, clusterId }))\n : undefined;\n if (versionFilterValue !== undefined && versionFilterValue === version) {\n logger.debug(\n `Read attribute from ${exchange.channel.name}: ${this.#endpointStructure.resolveAttributeName(\n path,\n )}=${Logger.toJSON(value)} (version=${version}) ignored because of dataVersionFilter`,\n );\n continue;\n }\n\n logger.debug(\n `Read attribute from ${exchange.channel.name}: ${this.#endpointStructure.resolveAttributeName(\n path,\n )}=${Logger.toJSON(value)} (version=${version})`,\n );\n\n const { schema } = attribute;\n attributeReportsPayload.push({\n attributeData: { path, dataVersion: version, payload: value, schema },\n });\n } catch (error) {\n logger.error(\n `Error while reading attribute from ${\n exchange.channel.name\n } to ${this.#endpointStructure.resolveAttributeName(path)}:`,\n error,\n );\n if (error instanceof StatusResponseError) {\n // Add StatusResponseErrors, but only when the initial path was concrete, else error are ignored\n if (isConcreteAttributePath(requestPath)) {\n attributeReportsPayload.push({ attributeStatus: { path, status: { status: error.code } } });\n }\n } else {\n throw error;\n }\n }\n }\n }\n\n let eventReportsPayload: undefined | EventReportPayload[];\n if (eventRequests) {\n eventReportsPayload = [];\n for (const requestPath of eventRequests) {\n validateReadEventPath(requestPath);\n\n const events = this.#endpointStructure.getEvents([requestPath]);\n\n // Requested event path not found in any cluster server on any endpoint\n if (events.length === 0) {\n // TODO Add checks for nodeId\n if (!isConcreteEventPath(requestPath)) {\n // Wildcard path: Just leave out values\n logger.debug(\n `Read event from ${exchange.channel.name}: ${this.#endpointStructure.resolveEventName(\n requestPath,\n )}: ignore non-existing event`,\n );\n } else {\n const { endpointId, clusterId, eventId } = requestPath;\n tryCatch(\n () => {\n this.#endpointStructure.validateConcreteEventPath(endpointId, clusterId, eventId);\n throw new InternalError(\n \"validateConcreteEventPath should throw StatusResponseError but did not.\",\n );\n },\n StatusResponseError,\n error => {\n logger.debug(\n `Read event from ${\n exchange.channel.name\n }: ${this.#endpointStructure.resolveEventName(requestPath)}: unsupported path: Status=${\n error.code\n }`,\n );\n eventReportsPayload?.push({\n eventStatus: { path: requestPath, status: { status: error.code } },\n });\n },\n );\n }\n continue;\n }\n\n const reportsForPath = new Array<{ eventData: EventDataPayload }>();\n for (const { path, event } of events) {\n try {\n const { endpointId } = path;\n const matchingEvents = await this.readEvent(\n path,\n eventFilters,\n event,\n exchange,\n isFabricFiltered,\n message,\n this.#endpointStructure.getEndpoint(endpointId)!,\n );\n logger.debug(\n `Read event from ${exchange.channel.name}: ${this.#endpointStructure.resolveEventName(\n path,\n )}=${Logger.toJSON(matchingEvents)}`,\n );\n const { schema } = event;\n reportsForPath.push(\n ...matchingEvents.map(({ eventNumber, priority, epochTimestamp, data }) => ({\n eventData: {\n path,\n eventNumber,\n priority,\n epochTimestamp,\n payload: data,\n schema,\n },\n })),\n );\n } catch (error) {\n logger.error(\n `Error while reading event from ${\n exchange.channel.name\n } to ${this.#endpointStructure.resolveEventName(path)}:`,\n error,\n );\n if (error instanceof StatusResponseError) {\n // Add StatusResponseErrors, but only when the initial path was concrete, else error are ignored\n if (isConcreteEventPath(requestPath)) {\n eventReportsPayload?.push({ eventStatus: { path, status: { status: error.code } } });\n }\n } else {\n throw error;\n }\n }\n }\n eventReportsPayload.push(\n ...reportsForPath.sort((a, b) => {\n const eventNumberA = a.eventData?.eventNumber ?? EventNumber(0);\n const eventNumberB = b.eventData?.eventNumber ?? EventNumber(0);\n if (eventNumberA > eventNumberB) {\n return 1;\n } else if (eventNumberA < eventNumberB) {\n return -1;\n } else {\n return 0;\n }\n }),\n );\n }\n }\n\n // TODO support suppressResponse for responses\n return {\n interactionModelRevision: INTERACTION_MODEL_REVISION,\n suppressResponse: false,\n attributeReportsPayload, // TODO Return compressed response once https://github.com/project-chip/connectedhomeip/issues/29359 is solved\n eventReportsPayload,\n };\n }\n\n protected async readAttribute(\n _path: AttributePath,\n attribute: AnyAttributeServer<any>,\n exchange: MessageExchange<MatterDevice>,\n isFabricFiltered: boolean,\n message: Message,\n _endpoint: EndpointInterface,\n ) {\n return attribute.getWithVersion(exchange.session, isFabricFiltered, message);\n }\n\n protected async readEvent(\n _path: EventPath,\n eventFilters: TypeFromSchema<typeof TlvEventFilter>[] | undefined,\n event: EventServer<any, any>,\n exchange: MessageExchange<MatterDevice>,\n isFabricFiltered: boolean,\n message: Message,\n _endpoint: EndpointInterface,\n ) {\n return event.get(exchange.session, isFabricFiltered, message, eventFilters);\n }\n\n async handleWriteRequest(\n exchange: MessageExchange<MatterDevice>,\n { suppressResponse, timedRequest, writeRequests, interactionModelRevision, moreChunkedMessages }: WriteRequest,\n message: Message,\n ): Promise<WriteResponse> {\n const sessionType = message.packetHeader.sessionType;\n logger.debug(\n `Received write request from ${exchange.channel.name}: ${writeRequests\n .map(req => this.#endpointStructure.resolveAttributeName(req.path))\n .join(\", \")}, suppressResponse=${suppressResponse}, moreChunkedMessages=${moreChunkedMessages}`,\n );\n\n if (moreChunkedMessages && suppressResponse) {\n throw new StatusResponseError(\n \"MoreChunkedMessages and SuppressResponse cannot be used together in write messages\",\n StatusCode.InvalidAction,\n );\n }\n\n if (interactionModelRevision > INTERACTION_MODEL_REVISION) {\n logger.debug(\n `Interaction model revision of sender ${interactionModelRevision} is higher than supported ${INTERACTION_MODEL_REVISION}.`,\n );\n }\n\n const receivedWithinTimedInteraction = exchange.hasActiveTimedInteraction();\n\n if (receivedWithinTimedInteraction && moreChunkedMessages) {\n throw new StatusResponseError(\n \"Write Request action that is part of a Timed Write Interaction SHALL NOT be chunked.\",\n StatusCode.InvalidAction,\n );\n }\n\n if (exchange.hasExpiredTimedInteraction()) {\n exchange.clearTimedInteraction(); // ??\n throw new StatusResponseError(`Timed request window expired. Decline write request.`, StatusCode.Timeout);\n }\n\n if (timedRequest !== exchange.hasTimedInteraction()) {\n throw new StatusResponseError(\n `timedRequest flag of write interaction (${timedRequest}) mismatch with expected timed interaction (${receivedWithinTimedInteraction}).`,\n StatusCode.TimedRequestMismatch,\n );\n }\n\n if (receivedWithinTimedInteraction) {\n logger.debug(`Write request from ${exchange.channel.name} received while timed interaction is running.`);\n exchange.clearTimedInteraction();\n if (sessionType !== SessionType.Unicast) {\n throw new StatusResponseError(\n \"Write requests are only allowed on unicast sessions when a timed interaction is running.\",\n StatusCode.InvalidAction,\n ); // ???\n }\n }\n\n if (sessionType === SessionType.Group && !suppressResponse) {\n throw new StatusResponseError(\n \"Write requests are only allowed as group casts when suppressResponse=true.\",\n StatusCode.InvalidAction,\n ); // ???\n }\n\n const writeData = expandPathsInAttributeData(writeRequests, true);\n\n const writeResults = new Array<{\n path: TypeFromSchema<typeof TlvAttributePath>;\n statusCode: StatusCode;\n clusterStatusCode?: number;\n }>();\n const attributeListWrites = new Set<AttributeServer<any>>();\n const clusterDataVersionInfo = new Map<string, number>();\n const inaccessiblePaths = new Set<string>();\n\n // TODO Add handling for moreChunkedMessages here when adopting for Matter 1.3\n\n for (const writeRequest of writeData) {\n const { path: writePath, dataVersion } = writeRequest;\n const { listIndex } = writePath;\n\n validateWriteAttributesPath(writePath);\n\n const attributes = this.#endpointStructure.getAttributes([writePath], true);\n\n // No existing attribute matches the given path and is writable\n if (attributes.length === 0) {\n // TODO: Also check nodeId\n if (!isConcreteAttributePath(writePath)) {\n // Wildcard path: Just ignore\n logger.debug(\n `Write from ${exchange.channel.name}: ${this.#endpointStructure.resolveAttributeName(\n writePath,\n )}: ignore non-existing (wildcard) attribute`,\n );\n } else {\n const { endpointId, clusterId, attributeId } = writePath;\n\n // was a concrete path\n tryCatch(\n () => {\n if (\n this.#endpointStructure.validateConcreteAttributePath(\n endpointId,\n clusterId,\n attributeId,\n )\n ) {\n throw new StatusResponseError(\n `Attribute ${attributeId} is not writable.`,\n StatusCode.UnsupportedWrite,\n );\n }\n throw new InternalError(\n \"validateConcreteAttributePath check should throw StatusResponseError but did not.\",\n );\n },\n StatusResponseError,\n error => {\n logger.debug(\n `Write from ${exchange.channel.name}: ${this.#endpointStructure.resolveAttributeName(\n writePath,\n )} not allowed: Status=${error.code}`,\n );\n writeResults.push({ path: writePath, statusCode: error.code });\n },\n );\n }\n continue;\n }\n\n // Concrete path and found and writable\n if (attributes.length === 1 && isConcreteAttributePath(writePath)) {\n const { endpointId, clusterId } = writePath;\n const { attribute } = attributes[0];\n\n if (attribute.requiresTimedInteraction && !receivedWithinTimedInteraction) {\n logger.debug(`This write requires a timed interaction which is not initialized.`);\n writeResults.push({ path: writePath, statusCode: StatusCode.NeedsTimedInteraction });\n continue;\n }\n\n if (\n attribute instanceof FabricScopedAttributeServer &&\n (!exchange.session.isSecure || !(exchange.session as SecureSession<MatterDevice>).fabric)\n ) {\n logger.debug(`This write requires a secure session with a fabric assigned which is missing.`);\n writeResults.push({ path: writePath, statusCode: StatusCode.UnsupportedAccess });\n continue;\n }\n\n // Check the provided dataVersion with the dataVersion of the cluster\n // And remember this initial dataVersion for all checks inside this write transaction to allow proper\n // processing of chunked lists\n if (dataVersion !== undefined) {\n const datasource = this.#endpointStructure.getClusterServer(endpointId, clusterId)?.datasource;\n const { nodeId } = writePath;\n const clusterKey = clusterPathToId({ nodeId, endpointId, clusterId });\n const currentDataVersion = clusterDataVersionInfo.get(clusterKey) ?? datasource?.version;\n\n if (currentDataVersion !== undefined) {\n if (dataVersion !== currentDataVersion) {\n logger.debug(\n `This write requires a specific data version (${dataVersion}) which do not match the current cluster data version (${currentDataVersion}).`,\n );\n writeResults.push({ path: writePath, statusCode: StatusCode.DataVersionMismatch });\n continue;\n }\n clusterDataVersionInfo.set(clusterKey, currentDataVersion);\n }\n }\n }\n\n for (const { path, attribute } of attributes) {\n const { schema, defaultValue } = attribute;\n const pathId = attributePathToId(path);\n\n try {\n if (\n !(attribute instanceof AttributeServer) &&\n !(attribute instanceof FabricScopedAttributeServer)\n ) {\n throw new StatusResponseError(\n \"Fixed attributes cannot be written\",\n StatusCode.UnsupportedWrite,\n );\n }\n\n if (inaccessiblePaths.has(pathId)) {\n logger.debug(`This write is not allowed due to previous access denied.`);\n continue;\n }\n\n const { endpointId } = path;\n const value =\n listIndex === undefined\n ? decodeAttributeValueWithSchema(schema, [writeRequest], defaultValue)\n : decodeListAttributeValueWithSchema(\n schema,\n [writeRequest],\n (\n await this.readAttribute(\n path,\n attribute,\n exchange,\n true,\n message,\n this.#endpointStructure.getEndpoint(endpointId)!,\n )\n ).value ?? defaultValue,\n );\n logger.debug(\n `Handle write request from ${\n exchange.channel.name\n } resolved to: ${this.#endpointStructure.resolveAttributeName(path)}=${Logger.toJSON(\n value,\n )} (listIndex=${listIndex}, for-version=${dataVersion})`,\n );\n\n if (attribute.requiresTimedInteraction && !receivedWithinTimedInteraction) {\n logger.debug(`This write requires a timed interaction which is not initialized.`);\n throw new StatusResponseError(\n \"This write requires a timed interaction which is not initialized.\",\n StatusCode.NeedsTimedInteraction,\n );\n }\n\n await this.writeAttribute(\n path,\n attribute,\n value,\n exchange,\n message,\n this.#endpointStructure.getEndpoint(endpointId)!,\n receivedWithinTimedInteraction,\n schema instanceof ArraySchema,\n );\n if (schema instanceof ArraySchema && !attributeListWrites.has(attribute)) {\n attributeListWrites.add(attribute);\n }\n } catch (error: any) {\n if (error instanceof StatusResponseError && error.code === StatusCode.UnsupportedAccess) {\n inaccessiblePaths.add(pathId);\n }\n if (attributes.length === 1 && isConcreteAttributePath(writePath)) {\n // For Multi-Attribute-Writes we ignore errors\n logger.error(\n `Error while handling write request from ${\n exchange.channel.name\n } to ${this.#endpointStructure.resolveAttributeName(path)}:`,\n error instanceof StatusResponseError ? error.message : error,\n );\n if (error instanceof StatusResponseError) {\n writeResults.push({ path, statusCode: error.code, clusterStatusCode: error.clusterCode });\n continue;\n }\n writeResults.push({ path, statusCode: StatusCode.ConstraintError });\n continue;\n } else {\n logger.debug(\n `While handling write request from ${\n exchange.channel.name\n } to ${this.#endpointStructure.resolveAttributeName(path)} ignored: ${error.message}`,\n );\n\n // TODO - This behavior may be wrong.\n //\n // If a wildcard write fails we should either:\n //\n // 1. Ignore entirely (add nothing to write results), or\n // 2. Add an error response for the concrete attribute that failed.\n //\n // Spec is a little ambiguous. After request path expansion, in core 1.2 8.7.3.2 it states:\n //\n // \"If the path indicates attribute data that is not writable, then the path SHALL be\n // discarded\"\n //\n // So is this \"not writable\" -- so it should be #1 -- or is this \"writable\" but with invalid\n // data? The latter is error case #2 but spec doesn't make clear what the status code would\n // be... We could fall back to CONSTRAINT_ERROR like we do above though\n //\n // Currently what we do is add a success response for every concrete path that fails.\n }\n }\n writeResults.push({ path, statusCode: StatusCode.Success });\n }\n //.filter(({ statusCode }) => statusCode !== StatusCode.Success); // see https://github.com/project-chip/connectedhomeip/issues/26198\n }\n\n const errorResults = writeResults.filter(({ statusCode }) => statusCode !== StatusCode.Success);\n logger.debug(\n `Write request from ${exchange.channel.name} done ${\n errorResults.length\n ? `with following errors: ${errorResults\n .map(\n ({ path, statusCode }) =>\n `${this.#endpointStructure.resolveAttributeName(path)}=${Logger.toJSON(statusCode)}`,\n )\n .join(\", \")}`\n : \"without errors\"\n }`,\n );\n\n const response = {\n interactionModelRevision: INTERACTION_MODEL_REVISION,\n writeResponses: writeResults.map(({ path, statusCode, clusterStatusCode }) => ({\n path,\n status: { status: statusCode, clusterStatus: clusterStatusCode },\n })),\n };\n\n // Trigger attribute events for delayed list writes\n for (const attribute of attributeListWrites.values()) {\n try {\n attribute.triggerDelayedChangeEvents();\n } catch (error) {\n logger.error(\n `Ignored Error while writing attribute from ${exchange.channel.name} to ${attribute.name}:`,\n error,\n );\n }\n }\n\n return response;\n }\n\n protected async writeAttribute(\n _path: AttributePath,\n attribute: AttributeServer<any>,\n value: any,\n exchange: MessageExchange<MatterDevice>,\n message: Message,\n _endpoint: EndpointInterface,\n _receivedWithinTimedInteraction?: boolean,\n isListWrite = false,\n ) {\n attribute.set(value, exchange.session, message, isListWrite);\n }\n\n async handleSubscribeRequest(\n exchange: MessageExchange<MatterDevice>,\n {\n minIntervalFloorSeconds,\n maxIntervalCeilingSeconds,\n attributeRequests,\n dataVersionFilters,\n eventRequests,\n eventFilters,\n keepSubscriptions,\n isFabricFiltered,\n interactionModelRevision,\n }: SubscribeRequest,\n messenger: InteractionServerMessenger,\n message: Message,\n ): Promise<void> {\n logger.debug(\n `Received subscribe request from ${exchange.channel.name} (keepSubscriptions=${keepSubscriptions}, isFabricFiltered=${isFabricFiltered})`,\n );\n\n if (interactionModelRevision > INTERACTION_MODEL_REVISION) {\n logger.debug(\n `Interaction model revision of sender ${interactionModelRevision} is higher than supported ${INTERACTION_MODEL_REVISION}.`,\n );\n }\n\n if (message.packetHeader.sessionType !== SessionType.Unicast) {\n throw new StatusResponseError(\n \"Subscriptions are only allowed on unicast sessions\",\n StatusCode.InvalidAction,\n );\n }\n\n assertSecureSession(exchange.session, \"Subscriptions are only implemented on secure sessions\");\n const session = exchange.session;\n const fabric = session.fabric;\n if (fabric === undefined)\n throw new StatusResponseError(\n \"Subscriptions are only implemented after a fabric has been assigned\",\n StatusCode.InvalidAction,\n );\n\n if (\n (!Array.isArray(attributeRequests) || attributeRequests.length === 0) &&\n (!Array.isArray(eventRequests) || eventRequests.length === 0)\n ) {\n throw new StatusResponseError(\"No attributes or events requested\", StatusCode.InvalidAction);\n }\n\n logger.debug(\n `Subscribe to attributes:${\n attributeRequests?.map(path => this.#endpointStructure.resolveAttributeName(path)).join(\", \") ?? \"none\"\n }, events:${\n eventRequests?.map(path => this.#endpointStructure.resolveEventName(path)).join(\", \") ?? \"none\"\n }`,\n );\n\n if (dataVersionFilters !== undefined && dataVersionFilters.length > 0) {\n logger.debug(\n `DataVersionFilters: ${dataVersionFilters\n .map(\n ({ path: { nodeId, endpointId, clusterId }, dataVersion }) =>\n `${clusterPathToId({ nodeId, endpointId, clusterId })}=${dataVersion}`,\n )\n .join(\", \")}`,\n );\n }\n if (eventFilters !== undefined && eventFilters.length > 0)\n logger.debug(\n `Event filters: ${eventFilters.map(filter => `${filter.nodeId}/${filter.eventMin}`).join(\", \")}`,\n );\n\n // Validate of the paths before proceeding\n attributeRequests?.forEach(path => validateReadAttributesPath(path));\n eventRequests?.forEach(path => validateReadEventPath(path));\n\n if (minIntervalFloorSeconds < 0) {\n throw new StatusResponseError(\n \"minIntervalFloorSeconds should be greater or equal to 0\",\n StatusCode.InvalidAction,\n );\n }\n if (maxIntervalCeilingSeconds < 0) {\n throw new StatusResponseError(\n \"maxIntervalCeilingSeconds should be greater or equal to 1\",\n StatusCode.InvalidAction,\n );\n }\n if (maxIntervalCeilingSeconds < minIntervalFloorSeconds) {\n throw new StatusResponseError(\n \"maxIntervalCeilingSeconds should be greater or equal to minIntervalFloorSeconds\",\n StatusCode.InvalidAction,\n );\n }\n\n // TODO: Interpret specs:\n // The publisher SHALL compute an appropriate value for the MaxInterval field in the action. This SHALL respect the following constraint: MinIntervalFloor \u2264 MaxInterval \u2264 MAX(SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT=60mn, MaxIntervalCeiling)\n\n if (this.#nextSubscriptionId === 0xffffffff) this.#nextSubscriptionId = 0;\n const subscriptionId = this.#nextSubscriptionId++;\n const subscriptionHandler = new SubscriptionHandler(\n subscriptionId,\n session,\n this.#endpointStructure,\n attributeRequests,\n dataVersionFilters,\n eventRequests,\n eventFilters,\n this.#eventHandler,\n isFabricFiltered,\n minIntervalFloorSeconds,\n maxIntervalCeilingSeconds,\n () => this.#subscriptionMap.delete(subscriptionId),\n this.#subscriptionConfig,\n );\n\n try {\n // Send initial data report to prime the subscription with initial data\n await subscriptionHandler.sendInitialReport(\n messenger,\n (path, attribute) =>\n this.readAttribute(\n path,\n attribute,\n exchange,\n isFabricFiltered,\n message,\n this.#endpointStructure.getEndpoint(path.endpointId)!,\n ),\n (path, event, eventFilters) =>\n this.readEvent(\n path,\n eventFilters,\n event,\n exchange,\n isFabricFiltered,\n message,\n this.#endpointStructure.getEndpoint(path.endpointId)!,\n ),\n );\n } catch (error: any) {\n logger.error(\n `Subscription ${subscriptionId} for Session ${session.id}: Error while sending initial data reports`,\n error,\n );\n await subscriptionHandler.cancel(); // Cleanup\n if (error instanceof StatusResponseError) {\n logger.info(`Sending status response ${error.code} for interaction error: ${error.message}`);\n await messenger.sendStatus(error.code);\n }\n await messenger.close();\n return; // Make sure to not bubble up the exception\n }\n\n if (!keepSubscriptions) {\n logger.debug(\n `Clear subscriptions for Subscriber node ${session.peerNodeId} because keepSubscriptions=false`,\n );\n await session.context.clearSubscriptionsForNode(session.peerNodeId, true);\n }\n\n const maxInterval = subscriptionHandler.getMaxInterval();\n logger.info(\n `Successfully created subscription ${subscriptionId} for Session ${\n session.id\n }. Updates: ${minIntervalFloorSeconds} - ${maxIntervalCeilingSeconds} => ${maxInterval} seconds (sendInterval = ${subscriptionHandler.getSendInterval()} seconds)`,\n );\n // Then send the subscription response\n await messenger.send(\n MessageType.SubscribeResponse,\n TlvSubscribeResponse.encode({\n subscriptionId,\n maxInterval,\n interactionModelRevision: INTERACTION_MODEL_REVISION,\n }),\n );\n\n this.#subscriptionMap.set(subscriptionId, subscriptionHandler);\n session.addSubscription(subscriptionHandler);\n subscriptionHandler.activateSendingUpdates();\n }\n\n async handleInvokeRequest(\n exchange: MessageExchange<MatterDevice>,\n { invokeRequests, timedRequest, suppressResponse, interactionModelRevision }: InvokeRequest,\n message: Message,\n ): Promise<InvokeResponse> {\n logger.debug(\n `Received invoke request from ${exchange.channel.name}: ${invokeRequests\n .map(({ commandPath: { endpointId, clusterId, commandId } }) =>\n this.#endpointStructure.resolveCommandName({ endpointId, clusterId, commandId }),\n )\n .join(\", \")}, suppressResponse=${suppressResponse}`,\n );\n\n if (interactionModelRevision > INTERACTION_MODEL_REVISION) {\n logger.debug(\n `Interaction model revision of sender ${interactionModelRevision} is higher than supported ${INTERACTION_MODEL_REVISION}.`,\n );\n }\n\n const receivedWithinTimedInteraction = exchange.hasActiveTimedInteraction();\n if (exchange.hasExpiredTimedInteraction()) {\n exchange.clearTimedInteraction(); // ??\n throw new StatusResponseError(`Timed request window expired. Decline invoke request.`, StatusCode.Timeout);\n }\n\n if (timedRequest !== exchange.hasTimedInteraction()) {\n throw new StatusResponseError(\n `timedRequest flag of invoke interaction (${timedRequest}) mismatch with expected timed interaction (${receivedWithinTimedInteraction}).`,\n StatusCode.TimedRequestMismatch,\n );\n }\n\n if (receivedWithinTimedInteraction) {\n logger.debug(`Invoke request from ${exchange.channel.name} received while timed interaction is running.`);\n exchange.clearTimedInteraction();\n if (message.packetHeader.sessionType !== SessionType.Unicast) {\n throw new StatusResponseError(\n \"Invoke requests are only allowed on unicast sessions when a timed interaction is running.\",\n StatusCode.InvalidAction,\n ); // ???\n }\n }\n\n if (invokeRequests.length > 1) {\n throw new StatusResponseError(\"Multi-command invoke requests are not supported\", StatusCode.InvalidAction);\n }\n\n invokeRequests.forEach(({ commandPath }) => validateCommandPath(commandPath));\n\n const invokeResponses: TypeFromSchema<typeof TlvInvokeResponseData>[] = [];\n\n await Promise.all(\n invokeRequests.flatMap(async ({ commandPath, commandFields }) => {\n const commands = this.#endpointStructure.getCommands([commandPath]);\n\n // TODO also check ACL and Timed, Fabric scoping constrains\n\n if (commands.length === 0) {\n // TODO Also check nodeId\n if (!isConcreteCommandPath(commandPath)) {\n // Wildcard path: Just ignore\n logger.debug(\n `Invoke from ${exchange.channel.name}: ${this.#endpointStructure.resolveCommandName(\n commandPath,\n )} ignore non-existing attribute`,\n );\n } else {\n const { endpointId, clusterId, commandId } = commandPath;\n invokeResponses.push(\n tryCatch(\n () => {\n this.#endpointStructure.validateConcreteCommandPath(\n endpointId,\n clusterId,\n commandId,\n );\n throw new InternalError(\n \"validateConcreteCommandPath should throw StatusResponseError but did not.\",\n );\n },\n StatusResponseError,\n error => {\n logger.debug(\n `Invoke from ${\n exchange.channel.name\n }: ${this.#endpointStructure.resolveCommandName(\n commandPath,\n )} unsupported path: Status=${error.code}`,\n );\n return { status: { commandPath, status: { status: error.code } } };\n },\n ),\n );\n }\n return;\n }\n\n for (const { command, path } of commands) {\n const { endpointId } = path;\n if (endpointId === undefined) {\n // Should never happen\n logger.error(\n `Invoke from ${exchange.channel.name}: ${this.#endpointStructure.resolveCommandName(\n path,\n )} invalid path because empty endpoint!`,\n );\n invokeResponses.push({\n status: { commandPath: path, status: { status: StatusCode.UnsupportedEndpoint } },\n });\n continue;\n }\n const endpoint = this.#endpointStructure.getEndpoint(endpointId);\n if (endpoint === undefined) {\n // Should never happen\n logger.error(\n `Invoke from ${exchange.channel.name}: ${this.#endpointStructure.resolveCommandName(\n path,\n )} invalid path because endpoint not found!`,\n );\n invokeResponses.push({\n status: { commandPath: path, status: { status: StatusCode.UnsupportedEndpoint } },\n });\n continue;\n }\n if (command.requiresTimedInteraction && !receivedWithinTimedInteraction) {\n logger.debug(`This invoke requires a timed interaction which is not initialized.`);\n invokeResponses.push({\n status: { commandPath: path, status: { status: StatusCode.NeedsTimedInteraction } },\n });\n continue;\n }\n\n const result = await tryCatchAsync(\n async () =>\n await this.invokeCommand(\n path,\n command,\n exchange,\n commandFields ?? TlvNoArguments.encodeTlv(commandFields),\n message,\n endpoint,\n receivedWithinTimedInteraction,\n ),\n StatusResponseError,\n async error => {\n const errorLogText = `Error ${Diagnostic.hex(error.code)}${\n error.clusterCode !== undefined ? `/${Diagnostic.hex(error.clusterCode)}` : \"\"\n } while invoking command: ${error.message}`;\n if (error instanceof ValidationError) {\n logger.info(\n `Validation-${errorLogText}${error.fieldName !== undefined ? ` in field ${error.fieldName}` : \"\"}`,\n );\n } else {\n logger.info(errorLogText);\n }\n return {\n code: error.code,\n clusterCode: error.clusterCode,\n responseId: command.responseId,\n response: TlvNoResponse.encodeTlv(),\n };\n },\n );\n const { code, clusterCode, responseId, response } = result;\n if (response.length === 0) {\n invokeResponses.push({\n status: { commandPath: path, status: { status: code, clusterStatus: clusterCode } },\n });\n } else {\n invokeResponses.push({\n command: {\n commandPath: { ...path, commandId: responseId },\n commandFields: response,\n },\n });\n }\n }\n }),\n );\n\n // TODO support suppressResponse for responses\n return {\n suppressResponse: false,\n interactionModelRevision: INTERACTION_MODEL_REVISION,\n invokeResponses,\n };\n }\n\n protected async invokeCommand(\n _path: CommandPath,\n command: CommandServer<any, any>,\n exchange: MessageExchange<MatterDevice>,\n commandFields: any,\n message: Message,\n endpoint: EndpointInterface,\n _receivedWithinTimedInteraction = false,\n ) {\n return command.invoke(exchange.session, commandFields, message, endpoint);\n }\n\n handleTimedRequest(exchange: MessageExchange<MatterDevice>, { timeout, interactionModelRevision }: TimedRequest) {\n logger.debug(`Received timed request (${timeout}ms) from ${exchange.channel.name}`);\n\n if (interactionModelRevision > INTERACTION_MODEL_REVISION) {\n logger.debug(\n `Interaction model revision of sender ${interactionModelRevision} is higher than supported ${INTERACTION_MODEL_REVISION}.`,\n );\n }\n\n exchange.startTimedInteraction(timeout);\n }\n\n async close() {\n this.#isClosing = true;\n for (const subscription of this.#subscriptionMap.values()) {\n await subscription.cancel(true);\n }\n }\n}\n\nexport namespace InteractionServer {\n export interface Configuration {\n readonly subscriptionOptions?: SubscriptionOptions;\n readonly eventHandler: EventHandler;\n readonly endpointStructure: InteractionEndpointStructure;\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["eventFilters"]
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SecureSession.d.ts","sourceRoot":"","sources":["../../../src/session/SecureSession.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SecureSession.d.ts","sourceRoot":"","sources":["../../../src/session/SecureSession.ts"],"names":[],"mappings":"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"}
@@ -248,7 +248,8 @@ class SecureSession extends import_Session.Session {
248
248
  }
249
249
  }
250
250
  async clearSubscriptions(flushSubscriptions = false) {
251
- for (const subscription of this.#subscriptions) {
251
+ const subscriptions = [...this.#subscriptions];
252
+ for (const subscription of subscriptions) {
252
253
  await subscription.cancel(flushSubscriptions);
253
254
  }
254
255
  this.#subscriptions.length = 0;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/session/SecureSession.ts"],
4
- "sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { DecodedMessage, DecodedPacket, Message, MessageCodec, Packet } from \"../codec/MessageCodec.js\";\nimport { MatterFlowError } from \"../common/MatterError.js\";\nimport { CRYPTO_SYMMETRIC_KEY_LENGTH, Crypto } from \"../crypto/Crypto.js\";\nimport { CaseAuthenticatedTag } from \"../datatype/CaseAuthenticatedTag.js\";\nimport { NodeId } from \"../datatype/NodeId.js\";\nimport { Fabric } from \"../fabric/Fabric.js\";\nimport { Diagnostic } from \"../log/Diagnostic.js\";\nimport { Logger } from \"../log/Logger.js\";\nimport { MessageCounter } from \"../protocol/MessageCounter.js\";\nimport { MessageReceptionStateEncryptedWithoutRollover } from \"../protocol/MessageReceptionState.js\";\nimport { StatusCode, StatusResponseError } from \"../protocol/interaction/StatusCode.js\";\nimport { SubscriptionHandler } from \"../protocol/interaction/SubscriptionHandler.js\";\nimport { ByteArray, Endian } from \"../util/ByteArray.js\";\nimport { DataWriter } from \"../util/DataWriter.js\";\nimport { Session, SessionParameterOptions } from \"./Session.js\";\n\nconst logger = Logger.get(\"SecureSession\");\n\nconst SESSION_KEYS_INFO = ByteArray.fromString(\"SessionKeys\");\nconst SESSION_RESUMPTION_KEYS_INFO = ByteArray.fromString(\"SessionResumptionKeys\");\n\nexport class NoAssociatedFabricError extends StatusResponseError {\n constructor(message: string) {\n super(message, StatusCode.UnsupportedAccess);\n }\n}\n\nexport class SecureSession<T> extends Session<T> {\n readonly #subscriptions = new Array<SubscriptionHandler>();\n #closingAfterExchangeFinished = false;\n #sendCloseMessageWhenClosing = true;\n readonly #context: T;\n readonly #id: number;\n #fabric: Fabric | undefined;\n readonly #peerNodeId: NodeId;\n readonly #peerSessionId: number;\n readonly #decryptKey: ByteArray;\n readonly #encryptKey: ByteArray;\n readonly #attestationKey: ByteArray;\n readonly #subscriptionChangedCallback: () => void;\n #caseAuthenticatedTags: CaseAuthenticatedTag[];\n\n static async create<T>(args: {\n context: T;\n id: number;\n fabric: Fabric | undefined;\n peerNodeId: NodeId;\n peerSessionId: number;\n sharedSecret: ByteArray;\n salt: ByteArray;\n isInitiator: boolean;\n isResumption: boolean;\n closeCallback: () => Promise<void>;\n subscriptionChangedCallback?: () => void;\n sessionParameters?: SessionParameterOptions;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n }) {\n const {\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n sharedSecret,\n salt,\n isInitiator,\n isResumption,\n closeCallback,\n sessionParameters,\n caseAuthenticatedTags,\n subscriptionChangedCallback,\n } = args;\n const keys = await Crypto.hkdf(\n sharedSecret,\n salt,\n isResumption ? SESSION_RESUMPTION_KEYS_INFO : SESSION_KEYS_INFO,\n CRYPTO_SYMMETRIC_KEY_LENGTH * 3,\n );\n const decryptKey = isInitiator ? keys.slice(16, 32) : keys.slice(0, 16);\n const encryptKey = isInitiator ? keys.slice(0, 16) : keys.slice(16, 32);\n const attestationKey = keys.slice(32, 48);\n return new SecureSession({\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n decryptKey,\n encryptKey,\n attestationKey,\n closeCallback,\n subscriptionChangedCallback,\n sessionParameters,\n isInitiator,\n caseAuthenticatedTags,\n });\n }\n\n constructor(args: {\n context: T;\n id: number;\n fabric: Fabric | undefined;\n peerNodeId: NodeId;\n peerSessionId: number;\n decryptKey: ByteArray;\n encryptKey: ByteArray;\n attestationKey: ByteArray;\n closeCallback: () => Promise<void>;\n subscriptionChangedCallback?: () => void;\n sessionParameters?: SessionParameterOptions;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n isInitiator: boolean;\n }) {\n super({\n ...args,\n setActiveTimestamp: true, // We always set the active timestamp for Secure sessions\n // Can be changed to a PersistedMessageCounter if we implement session storage\n messageCounter: new MessageCounter(() => {\n // Secure Session Message Counter\n // Expire/End the session before the counter rolls over\n this.end(true, true).catch(error => logger.error(`Error while closing session: ${error}`));\n }),\n messageReceptionState: new MessageReceptionStateEncryptedWithoutRollover(),\n });\n const {\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n decryptKey,\n encryptKey,\n attestationKey,\n subscriptionChangedCallback = () => {},\n caseAuthenticatedTags,\n } = args;\n\n this.#context = context;\n this.#id = id;\n this.#fabric = fabric;\n this.#peerNodeId = peerNodeId;\n this.#peerSessionId = peerSessionId;\n this.#decryptKey = decryptKey;\n this.#encryptKey = encryptKey;\n this.#attestationKey = attestationKey;\n this.#subscriptionChangedCallback = subscriptionChangedCallback;\n this.#caseAuthenticatedTags = caseAuthenticatedTags ?? fabric?.caseAuthenticatedTags ?? [];\n\n fabric?.addSession(this);\n\n logger.debug(\n `Created secure ${this.isPase ? \"PASE\" : \"CASE\"} session for fabric index ${fabric?.fabricIndex}`,\n this.name,\n Diagnostic.dict({\n idleIntervalMs: this.idleIntervalMs,\n activeIntervalMs: this.activeIntervalMs,\n activeThresholdMs: this.activeThresholdMs,\n }),\n );\n }\n\n get caseAuthenticatedTags() {\n return this.#caseAuthenticatedTags;\n }\n\n get closingAfterExchangeFinished() {\n return this.#closingAfterExchangeFinished;\n }\n\n get sendCloseMessageWhenClosing() {\n return this.#sendCloseMessageWhenClosing;\n }\n\n get isSecure(): boolean {\n return true;\n }\n\n get isPase(): boolean {\n return this.#peerNodeId === NodeId.UNSPECIFIED_NODE_ID;\n }\n\n async close(closeAfterExchangeFinished?: boolean) {\n if (closeAfterExchangeFinished === undefined) {\n closeAfterExchangeFinished = this.isPeerActive(); // We delay session close if the peer is actively communicating with us\n }\n await this.end(true, closeAfterExchangeFinished);\n }\n\n decode({ header, applicationPayload, messageExtension }: DecodedPacket, aad: ByteArray): DecodedMessage {\n if (header.hasMessageExtensions) {\n logger.info(`Message extensions are not supported. Ignoring ${messageExtension?.toHex()}`);\n }\n const nonce = this.generateNonce(header.securityFlags, header.messageId, this.#peerNodeId);\n const message = MessageCodec.decodePayload({\n header,\n applicationPayload: Crypto.decrypt(this.#decryptKey, applicationPayload, nonce, aad),\n });\n\n if (message.payloadHeader.hasSecuredExtension) {\n logger.info(`Secured extensions are not supported. Ignoring ${message.securityExtension?.toHex()}`);\n }\n\n return message;\n }\n\n encode(message: Message): Packet {\n message.packetHeader.sessionId = this.#peerSessionId;\n const { header, applicationPayload } = MessageCodec.encodePayload(message);\n const headerBytes = MessageCodec.encodePacketHeader(message.packetHeader);\n const securityFlags = headerBytes[3];\n const sessionNodeId = this.isPase\n ? NodeId.UNSPECIFIED_NODE_ID\n : this.#fabric?.nodeId ?? NodeId.UNSPECIFIED_NODE_ID;\n const nonce = this.generateNonce(securityFlags, header.messageId, sessionNodeId);\n return { header, applicationPayload: Crypto.encrypt(this.#encryptKey, applicationPayload, nonce, headerBytes) };\n }\n\n getAttestationChallengeKey(): ByteArray {\n return this.#attestationKey;\n }\n\n get fabric() {\n return this.#fabric;\n }\n\n addAssociatedFabric(fabric: Fabric) {\n if (this.#fabric !== undefined) {\n throw new MatterFlowError(\"Session already has an associated Fabric. Cannot change this.\");\n }\n this.#fabric = fabric;\n this.#caseAuthenticatedTags = fabric.caseAuthenticatedTags;\n }\n\n get id() {\n return this.#id;\n }\n\n get name() {\n return `secure/${this.#id}`;\n }\n\n get context() {\n return this.#context;\n }\n\n get peerSessionId(): number {\n return this.#peerSessionId;\n }\n\n get nodeId() {\n return this.#fabric?.nodeId ?? NodeId.UNSPECIFIED_NODE_ID;\n }\n\n get peerNodeId() {\n return this.#peerNodeId;\n }\n\n get numberOfActiveSubscriptions() {\n return this.#subscriptions.length;\n }\n\n get associatedFabric(): Fabric {\n if (this.#fabric === undefined) {\n throw new NoAssociatedFabricError(\n `${this.isPase ? \"PASE \" : \"\"}Session needs to have an associated Fabric for fabric sensitive data handling.`,\n );\n }\n return this.#fabric;\n }\n\n addSubscription(subscription: SubscriptionHandler) {\n this.#subscriptions.push(subscription);\n logger.debug(`Added subscription ${subscription.subscriptionId} to ${this.name}`);\n this.#subscriptionChangedCallback();\n }\n\n removeSubscription(subscriptionId: number) {\n const index = this.#subscriptions.findIndex(subscription => subscription.subscriptionId === subscriptionId);\n if (index !== -1) {\n this.#subscriptions.splice(index, 1);\n logger.debug(`Removed subscription ${subscriptionId} from ${this.name}`);\n this.#subscriptionChangedCallback();\n }\n }\n\n async clearSubscriptions(flushSubscriptions = false) {\n for (const subscription of this.#subscriptions) {\n await subscription.cancel(flushSubscriptions);\n }\n this.#subscriptions.length = 0;\n }\n\n /** Ends a session. Outstanding subscription data will be flushed before the session is destroyed. */\n async end(sendClose: boolean, closeAfterExchangeFinished = false) {\n await this.clearSubscriptions(true);\n await this.destroy(sendClose, closeAfterExchangeFinished);\n }\n\n /** Destroys a session. Outstanding subscription data will be discarded. */\n async destroy(sendClose = false, closeAfterExchangeFinished = true) {\n await this.clearSubscriptions(false);\n this.#fabric?.removeSession(this);\n if (!sendClose) {\n this.#sendCloseMessageWhenClosing = false;\n }\n\n if (closeAfterExchangeFinished) {\n logger.info(`Register Session ${this.name} to send a close when exchange is ended.`);\n this.#closingAfterExchangeFinished = true;\n } else {\n await this.closeCallback();\n }\n }\n\n private generateNonce(securityFlags: number, messageId: number, nodeId: NodeId) {\n const writer = new DataWriter(Endian.Little);\n writer.writeUInt8(securityFlags);\n writer.writeUInt32(messageId);\n writer.writeUInt64(nodeId);\n return writer.toByteArray();\n }\n}\n\nexport function assertSecureSession<T>(session: Session<T>, errorText?: string): asserts session is SecureSession<T> {\n if (!session.isSecure) {\n throw new MatterFlowError(errorText ?? \"Insecure session in secure context\");\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { DecodedMessage, DecodedPacket, Message, MessageCodec, Packet } from \"../codec/MessageCodec.js\";\nimport { MatterFlowError } from \"../common/MatterError.js\";\nimport { CRYPTO_SYMMETRIC_KEY_LENGTH, Crypto } from \"../crypto/Crypto.js\";\nimport { CaseAuthenticatedTag } from \"../datatype/CaseAuthenticatedTag.js\";\nimport { NodeId } from \"../datatype/NodeId.js\";\nimport { Fabric } from \"../fabric/Fabric.js\";\nimport { Diagnostic } from \"../log/Diagnostic.js\";\nimport { Logger } from \"../log/Logger.js\";\nimport { MessageCounter } from \"../protocol/MessageCounter.js\";\nimport { MessageReceptionStateEncryptedWithoutRollover } from \"../protocol/MessageReceptionState.js\";\nimport { StatusCode, StatusResponseError } from \"../protocol/interaction/StatusCode.js\";\nimport { SubscriptionHandler } from \"../protocol/interaction/SubscriptionHandler.js\";\nimport { ByteArray, Endian } from \"../util/ByteArray.js\";\nimport { DataWriter } from \"../util/DataWriter.js\";\nimport { Session, SessionParameterOptions } from \"./Session.js\";\n\nconst logger = Logger.get(\"SecureSession\");\n\nconst SESSION_KEYS_INFO = ByteArray.fromString(\"SessionKeys\");\nconst SESSION_RESUMPTION_KEYS_INFO = ByteArray.fromString(\"SessionResumptionKeys\");\n\nexport class NoAssociatedFabricError extends StatusResponseError {\n constructor(message: string) {\n super(message, StatusCode.UnsupportedAccess);\n }\n}\n\nexport class SecureSession<T> extends Session<T> {\n readonly #subscriptions = new Array<SubscriptionHandler>();\n #closingAfterExchangeFinished = false;\n #sendCloseMessageWhenClosing = true;\n readonly #context: T;\n readonly #id: number;\n #fabric: Fabric | undefined;\n readonly #peerNodeId: NodeId;\n readonly #peerSessionId: number;\n readonly #decryptKey: ByteArray;\n readonly #encryptKey: ByteArray;\n readonly #attestationKey: ByteArray;\n readonly #subscriptionChangedCallback: () => void;\n #caseAuthenticatedTags: CaseAuthenticatedTag[];\n\n static async create<T>(args: {\n context: T;\n id: number;\n fabric: Fabric | undefined;\n peerNodeId: NodeId;\n peerSessionId: number;\n sharedSecret: ByteArray;\n salt: ByteArray;\n isInitiator: boolean;\n isResumption: boolean;\n closeCallback: () => Promise<void>;\n subscriptionChangedCallback?: () => void;\n sessionParameters?: SessionParameterOptions;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n }) {\n const {\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n sharedSecret,\n salt,\n isInitiator,\n isResumption,\n closeCallback,\n sessionParameters,\n caseAuthenticatedTags,\n subscriptionChangedCallback,\n } = args;\n const keys = await Crypto.hkdf(\n sharedSecret,\n salt,\n isResumption ? SESSION_RESUMPTION_KEYS_INFO : SESSION_KEYS_INFO,\n CRYPTO_SYMMETRIC_KEY_LENGTH * 3,\n );\n const decryptKey = isInitiator ? keys.slice(16, 32) : keys.slice(0, 16);\n const encryptKey = isInitiator ? keys.slice(0, 16) : keys.slice(16, 32);\n const attestationKey = keys.slice(32, 48);\n return new SecureSession({\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n decryptKey,\n encryptKey,\n attestationKey,\n closeCallback,\n subscriptionChangedCallback,\n sessionParameters,\n isInitiator,\n caseAuthenticatedTags,\n });\n }\n\n constructor(args: {\n context: T;\n id: number;\n fabric: Fabric | undefined;\n peerNodeId: NodeId;\n peerSessionId: number;\n decryptKey: ByteArray;\n encryptKey: ByteArray;\n attestationKey: ByteArray;\n closeCallback: () => Promise<void>;\n subscriptionChangedCallback?: () => void;\n sessionParameters?: SessionParameterOptions;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n isInitiator: boolean;\n }) {\n super({\n ...args,\n setActiveTimestamp: true, // We always set the active timestamp for Secure sessions\n // Can be changed to a PersistedMessageCounter if we implement session storage\n messageCounter: new MessageCounter(() => {\n // Secure Session Message Counter\n // Expire/End the session before the counter rolls over\n this.end(true, true).catch(error => logger.error(`Error while closing session: ${error}`));\n }),\n messageReceptionState: new MessageReceptionStateEncryptedWithoutRollover(),\n });\n const {\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n decryptKey,\n encryptKey,\n attestationKey,\n subscriptionChangedCallback = () => {},\n caseAuthenticatedTags,\n } = args;\n\n this.#context = context;\n this.#id = id;\n this.#fabric = fabric;\n this.#peerNodeId = peerNodeId;\n this.#peerSessionId = peerSessionId;\n this.#decryptKey = decryptKey;\n this.#encryptKey = encryptKey;\n this.#attestationKey = attestationKey;\n this.#subscriptionChangedCallback = subscriptionChangedCallback;\n this.#caseAuthenticatedTags = caseAuthenticatedTags ?? fabric?.caseAuthenticatedTags ?? [];\n\n fabric?.addSession(this);\n\n logger.debug(\n `Created secure ${this.isPase ? \"PASE\" : \"CASE\"} session for fabric index ${fabric?.fabricIndex}`,\n this.name,\n Diagnostic.dict({\n idleIntervalMs: this.idleIntervalMs,\n activeIntervalMs: this.activeIntervalMs,\n activeThresholdMs: this.activeThresholdMs,\n }),\n );\n }\n\n get caseAuthenticatedTags() {\n return this.#caseAuthenticatedTags;\n }\n\n get closingAfterExchangeFinished() {\n return this.#closingAfterExchangeFinished;\n }\n\n get sendCloseMessageWhenClosing() {\n return this.#sendCloseMessageWhenClosing;\n }\n\n get isSecure(): boolean {\n return true;\n }\n\n get isPase(): boolean {\n return this.#peerNodeId === NodeId.UNSPECIFIED_NODE_ID;\n }\n\n async close(closeAfterExchangeFinished?: boolean) {\n if (closeAfterExchangeFinished === undefined) {\n closeAfterExchangeFinished = this.isPeerActive(); // We delay session close if the peer is actively communicating with us\n }\n await this.end(true, closeAfterExchangeFinished);\n }\n\n decode({ header, applicationPayload, messageExtension }: DecodedPacket, aad: ByteArray): DecodedMessage {\n if (header.hasMessageExtensions) {\n logger.info(`Message extensions are not supported. Ignoring ${messageExtension?.toHex()}`);\n }\n const nonce = this.generateNonce(header.securityFlags, header.messageId, this.#peerNodeId);\n const message = MessageCodec.decodePayload({\n header,\n applicationPayload: Crypto.decrypt(this.#decryptKey, applicationPayload, nonce, aad),\n });\n\n if (message.payloadHeader.hasSecuredExtension) {\n logger.info(`Secured extensions are not supported. Ignoring ${message.securityExtension?.toHex()}`);\n }\n\n return message;\n }\n\n encode(message: Message): Packet {\n message.packetHeader.sessionId = this.#peerSessionId;\n const { header, applicationPayload } = MessageCodec.encodePayload(message);\n const headerBytes = MessageCodec.encodePacketHeader(message.packetHeader);\n const securityFlags = headerBytes[3];\n const sessionNodeId = this.isPase\n ? NodeId.UNSPECIFIED_NODE_ID\n : this.#fabric?.nodeId ?? NodeId.UNSPECIFIED_NODE_ID;\n const nonce = this.generateNonce(securityFlags, header.messageId, sessionNodeId);\n return { header, applicationPayload: Crypto.encrypt(this.#encryptKey, applicationPayload, nonce, headerBytes) };\n }\n\n getAttestationChallengeKey(): ByteArray {\n return this.#attestationKey;\n }\n\n get fabric() {\n return this.#fabric;\n }\n\n addAssociatedFabric(fabric: Fabric) {\n if (this.#fabric !== undefined) {\n throw new MatterFlowError(\"Session already has an associated Fabric. Cannot change this.\");\n }\n this.#fabric = fabric;\n this.#caseAuthenticatedTags = fabric.caseAuthenticatedTags;\n }\n\n get id() {\n return this.#id;\n }\n\n get name() {\n return `secure/${this.#id}`;\n }\n\n get context() {\n return this.#context;\n }\n\n get peerSessionId(): number {\n return this.#peerSessionId;\n }\n\n get nodeId() {\n return this.#fabric?.nodeId ?? NodeId.UNSPECIFIED_NODE_ID;\n }\n\n get peerNodeId() {\n return this.#peerNodeId;\n }\n\n get numberOfActiveSubscriptions() {\n return this.#subscriptions.length;\n }\n\n get associatedFabric(): Fabric {\n if (this.#fabric === undefined) {\n throw new NoAssociatedFabricError(\n `${this.isPase ? \"PASE \" : \"\"}Session needs to have an associated Fabric for fabric sensitive data handling.`,\n );\n }\n return this.#fabric;\n }\n\n addSubscription(subscription: SubscriptionHandler) {\n this.#subscriptions.push(subscription);\n logger.debug(`Added subscription ${subscription.subscriptionId} to ${this.name}`);\n this.#subscriptionChangedCallback();\n }\n\n removeSubscription(subscriptionId: number) {\n const index = this.#subscriptions.findIndex(subscription => subscription.subscriptionId === subscriptionId);\n if (index !== -1) {\n this.#subscriptions.splice(index, 1);\n logger.debug(`Removed subscription ${subscriptionId} from ${this.name}`);\n this.#subscriptionChangedCallback();\n }\n }\n\n async clearSubscriptions(flushSubscriptions = false) {\n const subscriptions = [...this.#subscriptions]; // get all values because subscriptions will remove themselves when cancelled\n for (const subscription of subscriptions) {\n await subscription.cancel(flushSubscriptions);\n }\n this.#subscriptions.length = 0;\n }\n\n /** Ends a session. Outstanding subscription data will be flushed before the session is destroyed. */\n async end(sendClose: boolean, closeAfterExchangeFinished = false) {\n await this.clearSubscriptions(true);\n await this.destroy(sendClose, closeAfterExchangeFinished);\n }\n\n /** Destroys a session. Outstanding subscription data will be discarded. */\n async destroy(sendClose = false, closeAfterExchangeFinished = true) {\n await this.clearSubscriptions(false);\n this.#fabric?.removeSession(this);\n if (!sendClose) {\n this.#sendCloseMessageWhenClosing = false;\n }\n\n if (closeAfterExchangeFinished) {\n logger.info(`Register Session ${this.name} to send a close when exchange is ended.`);\n this.#closingAfterExchangeFinished = true;\n } else {\n await this.closeCallback();\n }\n }\n\n private generateNonce(securityFlags: number, messageId: number, nodeId: NodeId) {\n const writer = new DataWriter(Endian.Little);\n writer.writeUInt8(securityFlags);\n writer.writeUInt32(messageId);\n writer.writeUInt64(nodeId);\n return writer.toByteArray();\n }\n}\n\nexport function assertSecureSession<T>(session: Session<T>, errorText?: string): asserts session is SecureSession<T> {\n if (!session.isSecure) {\n throw new MatterFlowError(errorText ?? \"Insecure session in secure context\");\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,0BAA6E;AAC7E,yBAAgC;AAChC,oBAAoD;AAEpD,oBAAuB;AAEvB,wBAA2B;AAC3B,oBAAuB;AACvB,4BAA+B;AAC/B,mCAA8D;AAC9D,wBAAgD;AAEhD,uBAAkC;AAClC,wBAA2B;AAC3B,qBAAiD;AApBjD;AAAA;AAAA;AAAA;AAAA;AAsBA,MAAM,SAAS,qBAAO,IAAI,eAAe;AAEzC,MAAM,oBAAoB,2BAAU,WAAW,aAAa;AAC5D,MAAM,+BAA+B,2BAAU,WAAW,uBAAuB;AAE1E,MAAM,gCAAgC,sCAAoB;AAAA,EAC7D,YAAY,SAAiB;AACzB,UAAM,SAAS,6BAAW,iBAAiB;AAAA,EAC/C;AACJ;AAEO,MAAM,sBAAyB,uBAAW;AAAA,EACpC,iBAAiB,IAAI,MAA2B;AAAA,EACzD,gCAAgC;AAAA,EAChC,+BAA+B;AAAA,EACtB;AAAA,EACA;AAAA,EACT;AAAA,EACS;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT;AAAA,EAEA,aAAa,OAAU,MAcpB;AACC,UAAM;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACJ,IAAI;AACJ,UAAM,OAAO,MAAM,qBAAO;AAAA,MACtB;AAAA,MACA;AAAA,MACA,eAAe,+BAA+B;AAAA,MAC9C,4CAA8B;AAAA,IAClC;AACA,UAAM,aAAa,cAAc,KAAK,MAAM,IAAI,EAAE,IAAI,KAAK,MAAM,GAAG,EAAE;AACtE,UAAM,aAAa,cAAc,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK,MAAM,IAAI,EAAE;AACtE,UAAM,iBAAiB,KAAK,MAAM,IAAI,EAAE;AACxC,WAAO,IAAI,cAAc;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,YAAY,MAcT;AACC,UAAM;AAAA,MACF,GAAG;AAAA,MACH,oBAAoB;AAAA;AAAA;AAAA,MAEpB,gBAAgB,IAAI,qCAAe,MAAM;AAGrC,aAAK,IAAI,MAAM,IAAI,EAAE,MAAM,WAAS,OAAO,MAAM,gCAAgC,KAAK,EAAE,CAAC;AAAA,MAC7F,CAAC;AAAA,MACD,uBAAuB,IAAI,2EAA8C;AAAA,IAC7E,CAAC;AACD,UAAM;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,8BAA8B,MAAM;AAAA,MAAC;AAAA,MACrC;AAAA,IACJ,IAAI;AAEJ,SAAK,WAAW;AAChB,SAAK,MAAM;AACX,SAAK,UAAU;AACf,SAAK,cAAc;AACnB,SAAK,iBAAiB;AACtB,SAAK,cAAc;AACnB,SAAK,cAAc;AACnB,SAAK,kBAAkB;AACvB,SAAK,+BAA+B;AACpC,SAAK,yBAAyB,yBAAyB,QAAQ,yBAAyB,CAAC;AAEzF,YAAQ,WAAW,IAAI;AAEvB,WAAO;AAAA,MACH,kBAAkB,KAAK,SAAS,SAAS,MAAM,6BAA6B,QAAQ,WAAW;AAAA,MAC/F,KAAK;AAAA,MACL,6BAAW,KAAK;AAAA,QACZ,gBAAgB,KAAK;AAAA,QACrB,kBAAkB,KAAK;AAAA,QACvB,mBAAmB,KAAK;AAAA,MAC5B,CAAC;AAAA,IACL;AAAA,EACJ;AAAA,EAEA,IAAI,wBAAwB;AACxB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,+BAA+B;AAC/B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,8BAA8B;AAC9B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,WAAoB;AACpB,WAAO;AAAA,EACX;AAAA,EAEA,IAAI,SAAkB;AAClB,WAAO,KAAK,gBAAgB,qBAAO;AAAA,EACvC;AAAA,EAEA,MAAM,MAAM,4BAAsC;AAC9C,QAAI,+BAA+B,QAAW;AAC1C,mCAA6B,KAAK,aAAa;AAAA,IACnD;AACA,UAAM,KAAK,IAAI,MAAM,0BAA0B;AAAA,EACnD;AAAA,EAEA,OAAO,EAAE,QAAQ,oBAAoB,iBAAiB,GAAkB,KAAgC;AACpG,QAAI,OAAO,sBAAsB;AAC7B,aAAO,KAAK,kDAAkD,kBAAkB,MAAM,CAAC,EAAE;AAAA,IAC7F;AACA,UAAM,QAAQ,KAAK,cAAc,OAAO,eAAe,OAAO,WAAW,KAAK,WAAW;AACzF,UAAM,UAAU,iCAAa,cAAc;AAAA,MACvC;AAAA,MACA,oBAAoB,qBAAO,QAAQ,KAAK,aAAa,oBAAoB,OAAO,GAAG;AAAA,IACvF,CAAC;AAED,QAAI,QAAQ,cAAc,qBAAqB;AAC3C,aAAO,KAAK,kDAAkD,QAAQ,mBAAmB,MAAM,CAAC,EAAE;AAAA,IACtG;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,OAAO,SAA0B;AAC7B,YAAQ,aAAa,YAAY,KAAK;AACtC,UAAM,EAAE,QAAQ,mBAAmB,IAAI,iCAAa,cAAc,OAAO;AACzE,UAAM,cAAc,iCAAa,mBAAmB,QAAQ,YAAY;AACxE,UAAM,gBAAgB,YAAY,CAAC;AACnC,UAAM,gBAAgB,KAAK,SACrB,qBAAO,sBACP,KAAK,SAAS,UAAU,qBAAO;AACrC,UAAM,QAAQ,KAAK,cAAc,eAAe,OAAO,WAAW,aAAa;AAC/E,WAAO,EAAE,QAAQ,oBAAoB,qBAAO,QAAQ,KAAK,aAAa,oBAAoB,OAAO,WAAW,EAAE;AAAA,EAClH;AAAA,EAEA,6BAAwC;AACpC,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,SAAS;AACT,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,oBAAoB,QAAgB;AAChC,QAAI,KAAK,YAAY,QAAW;AAC5B,YAAM,IAAI,mCAAgB,+DAA+D;AAAA,IAC7F;AACA,SAAK,UAAU;AACf,SAAK,yBAAyB,OAAO;AAAA,EACzC;AAAA,EAEA,IAAI,KAAK;AACL,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,OAAO;AACP,WAAO,UAAU,KAAK,GAAG;AAAA,EAC7B;AAAA,EAEA,IAAI,UAAU;AACV,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,gBAAwB;AACxB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,SAAS;AACT,WAAO,KAAK,SAAS,UAAU,qBAAO;AAAA,EAC1C;AAAA,EAEA,IAAI,aAAa;AACb,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,8BAA8B;AAC9B,WAAO,KAAK,eAAe;AAAA,EAC/B;AAAA,EAEA,IAAI,mBAA2B;AAC3B,QAAI,KAAK,YAAY,QAAW;AAC5B,YAAM,IAAI;AAAA,QACN,GAAG,KAAK,SAAS,UAAU,EAAE;AAAA,MACjC;AAAA,IACJ;AACA,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,gBAAgB,cAAmC;AAC/C,SAAK,eAAe,KAAK,YAAY;AACrC,WAAO,MAAM,sBAAsB,aAAa,cAAc,OAAO,KAAK,IAAI,EAAE;AAChF,SAAK,6BAA6B;AAAA,EACtC;AAAA,EAEA,mBAAmB,gBAAwB;AACvC,UAAM,QAAQ,KAAK,eAAe,UAAU,kBAAgB,aAAa,mBAAmB,cAAc;AAC1G,QAAI,UAAU,IAAI;AACd,WAAK,eAAe,OAAO,OAAO,CAAC;AACnC,aAAO,MAAM,wBAAwB,cAAc,SAAS,KAAK,IAAI,EAAE;AACvE,WAAK,6BAA6B;AAAA,IACtC;AAAA,EACJ;AAAA,EAEA,MAAM,mBAAmB,qBAAqB,OAAO;AACjD,UAAM,gBAAgB,CAAC,GAAG,KAAK,cAAc;AAC7C,eAAW,gBAAgB,eAAe;AACtC,YAAM,aAAa,OAAO,kBAAkB;AAAA,IAChD;AACA,SAAK,eAAe,SAAS;AAAA,EACjC;AAAA;AAAA,EAGA,MAAM,IAAI,WAAoB,6BAA6B,OAAO;AAC9D,UAAM,KAAK,mBAAmB,IAAI;AAClC,UAAM,KAAK,QAAQ,WAAW,0BAA0B;AAAA,EAC5D;AAAA;AAAA,EAGA,MAAM,QAAQ,YAAY,OAAO,6BAA6B,MAAM;AAChE,UAAM,KAAK,mBAAmB,KAAK;AACnC,SAAK,SAAS,cAAc,IAAI;AAChC,QAAI,CAAC,WAAW;AACZ,WAAK,+BAA+B;AAAA,IACxC;AAEA,QAAI,4BAA4B;AAC5B,aAAO,KAAK,oBAAoB,KAAK,IAAI,0CAA0C;AACnF,WAAK,gCAAgC;AAAA,IACzC,OAAO;AACH,YAAM,KAAK,cAAc;AAAA,IAC7B;AAAA,EACJ;AAAA,EAEQ,cAAc,eAAuB,WAAmB,QAAgB;AAC5E,UAAM,SAAS,IAAI,6BAAW,wBAAO,MAAM;AAC3C,WAAO,WAAW,aAAa;AAC/B,WAAO,YAAY,SAAS;AAC5B,WAAO,YAAY,MAAM;AACzB,WAAO,OAAO,YAAY;AAAA,EAC9B;AACJ;AAEO,SAAS,oBAAuB,SAAqB,WAAyD;AACjH,MAAI,CAAC,QAAQ,UAAU;AACnB,UAAM,IAAI,mCAAgB,aAAa,oCAAoC;AAAA,EAC/E;AACJ;",
6
6
  "names": []
7
7
  }
@@ -72,6 +72,7 @@ export declare class SessionManager<ContextT> {
72
72
  lastActiveTimestamp: number | undefined;
73
73
  numberOfActiveSubscriptions: number;
74
74
  }[];
75
+ clearSubscriptionsForNode(nodeId: NodeId, flushSubscriptions?: boolean): Promise<void>;
75
76
  close(): Promise<void>;
76
77
  }
77
78
  //# sourceMappingURL=SessionManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SessionManager.d.ts","sourceRoot":"","sources":["../../../src/session/SessionManager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAI1E,eAAO,MAAM,2BAA2B,IAAS,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAC7B,YAAY,EAAE,SAAS,CAAC;IACxB,YAAY,EAAE,SAAS,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,qBAAqB,CAAC,EAAE,oBAAoB,EAAE,CAAC;CAClD;AAgBD,qBAAa,cAAc,CAAC,QAAQ;;IAY5B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,QAAQ,EAClC,cAAc,EAAE,cAAc;IAKlC,IAAI,oBAAoB,yDAEvB;IAED,IAAI,aAAa,yDAEhB;IAED,IAAI,aAAa,8DAEhB;IAED,qBAAqB,CAAC,OAAO,EAAE;QAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;QAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;KACzB;IA4BK,mBAAmB,CAAC,IAAI,EAAE;QAC5B,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,SAAS,CAAC;QACxB,IAAI,EAAE,SAAS,CAAC;QAChB,WAAW,EAAE,OAAO,CAAC;QACrB,YAAY,EAAE,OAAO,CAAC;QACtB,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;QAC5C,qBAAqB,CAAC,EAAE,oBAAoB,EAAE,CAAC;KAClD;IA0CD,aAAa,CAAC,SAAS,EAAE,MAAM;IAOzB,sBAAsB,CAAC,UAAU,EAAE,MAAM;IAK/C,yBAAyB;IAanB,yBAAyB;IAkB/B,UAAU,CAAC,SAAS,EAAE,MAAM;IAI5B,cAAc;IAMd,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAS1C,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,UAAQ;IAUhE,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM;IAOxC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;IASxD,wBAAwB,CAAC,YAAY,EAAE,SAAS;IAIhD,4BAA4B,CAAC,MAAM,EAAE,MAAM;IAIrC,oBAAoB,CAAC,gBAAgB,EAAE,gBAAgB;IAKvD,gCAAgC,CAAC,MAAM,EAAE,MAAM;IAS/C,sBAAsB;IAqBtB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE;IAkCvC,2BAA2B;;;;;;;;;;;IAgBrB,KAAK;CAWd"}
1
+ {"version":3,"file":"SessionManager.d.ts","sourceRoot":"","sources":["../../../src/session/SessionManager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAI1E,eAAO,MAAM,2BAA2B,IAAS,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAC7B,YAAY,EAAE,SAAS,CAAC;IACxB,YAAY,EAAE,SAAS,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,qBAAqB,CAAC,EAAE,oBAAoB,EAAE,CAAC;CAClD;AAgBD,qBAAa,cAAc,CAAC,QAAQ;;IAY5B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,QAAQ,EAClC,cAAc,EAAE,cAAc;IAKlC,IAAI,oBAAoB,yDAEvB;IAED,IAAI,aAAa,yDAEhB;IAED,IAAI,aAAa,8DAEhB;IAED,qBAAqB,CAAC,OAAO,EAAE;QAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;QAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;KACzB;IA4BK,mBAAmB,CAAC,IAAI,EAAE;QAC5B,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,SAAS,CAAC;QACxB,IAAI,EAAE,SAAS,CAAC;QAChB,WAAW,EAAE,OAAO,CAAC;QACrB,YAAY,EAAE,OAAO,CAAC;QACtB,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;QAC5C,qBAAqB,CAAC,EAAE,oBAAoB,EAAE,CAAC;KAClD;IA0CD,aAAa,CAAC,SAAS,EAAE,MAAM;IAOzB,sBAAsB,CAAC,UAAU,EAAE,MAAM;IAK/C,yBAAyB;IAanB,yBAAyB;IAkB/B,UAAU,CAAC,SAAS,EAAE,MAAM;IAI5B,cAAc;IAMd,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAS1C,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,UAAQ;IAUhE,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM;IAOxC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;IASxD,wBAAwB,CAAC,YAAY,EAAE,SAAS;IAIhD,4BAA4B,CAAC,MAAM,EAAE,MAAM;IAIrC,oBAAoB,CAAC,gBAAgB,EAAE,gBAAgB;IAKvD,gCAAgC,CAAC,MAAM,EAAE,MAAM;IAS/C,sBAAsB;IAqBtB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE;IAkCvC,2BAA2B;;;;;;;;;;;IAgBrB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAAE,OAAO;IAQtE,KAAK;CAWd"}
@@ -275,6 +275,13 @@ class SessionManager {
275
275
  numberOfActiveSubscriptions: session instanceof import_SecureSession.SecureSession ? session.numberOfActiveSubscriptions : 0
276
276
  }));
277
277
  }
278
+ async clearSubscriptionsForNode(nodeId, flushSubscriptions) {
279
+ for (const session of this.#sessions) {
280
+ if (session.peerNodeId === nodeId) {
281
+ await session.clearSubscriptions(flushSubscriptions);
282
+ }
283
+ }
284
+ }
278
285
  async close() {
279
286
  await this.storeResumptionRecords();
280
287
  for (const session of this.#sessions) {