@matter/protocol 0.15.4 → 0.15.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/action/client/ReadScope.d.ts +4 -0
- package/dist/cjs/action/client/ReadScope.d.ts.map +1 -1
- package/dist/cjs/action/client/ReadScope.js +2 -1
- package/dist/cjs/action/client/ReadScope.js.map +1 -1
- package/dist/cjs/action/server/EventReadResponse.d.ts.map +1 -1
- package/dist/cjs/action/server/EventReadResponse.js +2 -2
- package/dist/cjs/action/server/EventReadResponse.js.map +1 -1
- package/dist/cjs/events/OccurrenceManager.d.ts.map +1 -1
- package/dist/cjs/events/OccurrenceManager.js +2 -1
- package/dist/cjs/events/OccurrenceManager.js.map +1 -1
- package/dist/cjs/fabric/Fabric.d.ts.map +1 -1
- package/dist/cjs/fabric/Fabric.js.map +1 -1
- package/dist/cjs/fabric/FabricAuthority.d.ts +0 -1
- package/dist/cjs/fabric/FabricAuthority.d.ts.map +1 -1
- package/dist/cjs/fabric/FabricAuthority.js +2 -3
- package/dist/cjs/fabric/FabricAuthority.js.map +1 -1
- package/dist/cjs/fabric/TestFabric.d.ts.map +1 -1
- package/dist/cjs/fabric/TestFabric.js +2 -1
- package/dist/cjs/fabric/TestFabric.js.map +1 -1
- package/dist/cjs/interaction/AttributeDataDecoder.d.ts +9 -7
- package/dist/cjs/interaction/AttributeDataDecoder.d.ts.map +1 -1
- package/dist/cjs/interaction/AttributeDataDecoder.js.map +1 -1
- package/dist/cjs/interaction/DecodedDataReport.d.ts +1 -0
- package/dist/cjs/interaction/DecodedDataReport.d.ts.map +1 -1
- package/dist/cjs/interaction/DecodedDataReport.js.map +1 -1
- package/dist/cjs/interaction/InteractionClient.d.ts +12 -2
- package/dist/cjs/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionClient.js +94 -67
- package/dist/cjs/interaction/InteractionClient.js.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.d.ts +10 -90
- package/dist/cjs/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.js +113 -31
- package/dist/cjs/interaction/InteractionMessenger.js.map +2 -2
- package/dist/cjs/interaction/SubscriptionClient.d.ts +2 -2
- package/dist/cjs/interaction/SubscriptionClient.d.ts.map +1 -1
- package/dist/cjs/interaction/SubscriptionClient.js +1 -1
- package/dist/cjs/interaction/SubscriptionClient.js.map +1 -1
- package/dist/cjs/mdns/MdnsScanner.d.ts.map +1 -1
- package/dist/cjs/mdns/MdnsScanner.js +1 -2
- package/dist/cjs/mdns/MdnsScanner.js.map +1 -1
- package/dist/cjs/mdns/MdnsServer.js +1 -1
- package/dist/cjs/mdns/MdnsServer.js.map +1 -1
- package/dist/cjs/peer/PeerAddressStore.d.ts +3 -1
- package/dist/cjs/peer/PeerAddressStore.d.ts.map +1 -1
- package/dist/cjs/peer/PeerAddressStore.js.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.js +2 -2
- package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
- package/dist/cjs/protocol/MessageExchange.d.ts.map +1 -1
- package/dist/cjs/protocol/MessageExchange.js +1 -0
- package/dist/cjs/protocol/MessageExchange.js.map +1 -1
- package/dist/cjs/session/SessionManager.d.ts.map +1 -1
- package/dist/cjs/session/SessionManager.js +17 -9
- package/dist/cjs/session/SessionManager.js.map +1 -1
- package/dist/cjs/session/pase/PaseServer.d.ts.map +1 -1
- package/dist/cjs/session/pase/PaseServer.js +2 -1
- package/dist/cjs/session/pase/PaseServer.js.map +1 -1
- package/dist/esm/action/client/ReadScope.d.ts +4 -0
- package/dist/esm/action/client/ReadScope.d.ts.map +1 -1
- package/dist/esm/action/client/ReadScope.js +2 -1
- package/dist/esm/action/client/ReadScope.js.map +1 -1
- package/dist/esm/action/server/EventReadResponse.d.ts.map +1 -1
- package/dist/esm/action/server/EventReadResponse.js +3 -2
- package/dist/esm/action/server/EventReadResponse.js.map +1 -1
- package/dist/esm/events/OccurrenceManager.d.ts.map +1 -1
- package/dist/esm/events/OccurrenceManager.js +2 -1
- package/dist/esm/events/OccurrenceManager.js.map +1 -1
- package/dist/esm/fabric/Fabric.d.ts.map +1 -1
- package/dist/esm/fabric/Fabric.js.map +1 -1
- package/dist/esm/fabric/FabricAuthority.d.ts +0 -1
- package/dist/esm/fabric/FabricAuthority.d.ts.map +1 -1
- package/dist/esm/fabric/FabricAuthority.js +2 -3
- package/dist/esm/fabric/FabricAuthority.js.map +1 -1
- package/dist/esm/fabric/TestFabric.d.ts.map +1 -1
- package/dist/esm/fabric/TestFabric.js +3 -2
- package/dist/esm/fabric/TestFabric.js.map +1 -1
- package/dist/esm/interaction/AttributeDataDecoder.d.ts +9 -7
- package/dist/esm/interaction/AttributeDataDecoder.d.ts.map +1 -1
- package/dist/esm/interaction/AttributeDataDecoder.js.map +1 -1
- package/dist/esm/interaction/DecodedDataReport.d.ts +1 -0
- package/dist/esm/interaction/DecodedDataReport.d.ts.map +1 -1
- package/dist/esm/interaction/DecodedDataReport.js.map +1 -1
- package/dist/esm/interaction/InteractionClient.d.ts +12 -2
- package/dist/esm/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionClient.js +96 -68
- package/dist/esm/interaction/InteractionClient.js.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.d.ts +10 -90
- package/dist/esm/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.js +113 -31
- package/dist/esm/interaction/InteractionMessenger.js.map +2 -2
- package/dist/esm/interaction/SubscriptionClient.d.ts +2 -2
- package/dist/esm/interaction/SubscriptionClient.d.ts.map +1 -1
- package/dist/esm/interaction/SubscriptionClient.js +1 -1
- package/dist/esm/interaction/SubscriptionClient.js.map +1 -1
- package/dist/esm/mdns/MdnsScanner.d.ts.map +1 -1
- package/dist/esm/mdns/MdnsScanner.js +1 -2
- package/dist/esm/mdns/MdnsScanner.js.map +1 -1
- package/dist/esm/mdns/MdnsServer.js +1 -1
- package/dist/esm/mdns/MdnsServer.js.map +1 -1
- package/dist/esm/peer/PeerAddressStore.d.ts +3 -1
- package/dist/esm/peer/PeerAddressStore.d.ts.map +1 -1
- package/dist/esm/peer/PeerAddressStore.js.map +1 -1
- package/dist/esm/protocol/ExchangeManager.js +2 -2
- package/dist/esm/protocol/ExchangeManager.js.map +1 -1
- package/dist/esm/protocol/MessageExchange.d.ts.map +1 -1
- package/dist/esm/protocol/MessageExchange.js +1 -0
- package/dist/esm/protocol/MessageExchange.js.map +1 -1
- package/dist/esm/session/SessionManager.d.ts.map +1 -1
- package/dist/esm/session/SessionManager.js +19 -10
- package/dist/esm/session/SessionManager.js.map +1 -1
- package/dist/esm/session/pase/PaseServer.d.ts.map +1 -1
- package/dist/esm/session/pase/PaseServer.js +2 -1
- package/dist/esm/session/pase/PaseServer.js.map +1 -1
- package/package.json +6 -6
- package/src/action/client/ReadScope.ts +7 -0
- package/src/action/server/EventReadResponse.ts +7 -3
- package/src/events/OccurrenceManager.ts +2 -1
- package/src/fabric/Fabric.ts +1 -1
- package/src/fabric/FabricAuthority.ts +2 -2
- package/src/fabric/TestFabric.ts +2 -1
- package/src/interaction/AttributeDataDecoder.ts +4 -1
- package/src/interaction/DecodedDataReport.ts +1 -0
- package/src/interaction/InteractionClient.ts +152 -77
- package/src/interaction/InteractionMessenger.ts +143 -31
- package/src/interaction/SubscriptionClient.ts +6 -5
- package/src/mdns/MdnsScanner.ts +1 -2
- package/src/mdns/MdnsServer.ts +2 -2
- package/src/peer/PeerAddressStore.ts +3 -1
- package/src/protocol/ExchangeManager.ts +2 -2
- package/src/protocol/MessageExchange.ts +1 -0
- package/src/session/SessionManager.ts +35 -24
- package/src/session/pase/PaseServer.ts +2 -1
|
@@ -13,14 +13,20 @@ import {
|
|
|
13
13
|
NoResponseTimeoutError,
|
|
14
14
|
UnexpectedDataError,
|
|
15
15
|
} from "#general";
|
|
16
|
+
import { DecodedAttributeReportValue } from "#interaction/AttributeDataDecoder.js";
|
|
17
|
+
import { DecodedDataReport } from "#interaction/DecodedDataReport.js";
|
|
16
18
|
import { Specification } from "#model";
|
|
17
19
|
import { ChannelNotConnectedError } from "#protocol/MessageChannel.js";
|
|
18
20
|
import {
|
|
21
|
+
AttributeId,
|
|
22
|
+
ClusterId,
|
|
23
|
+
EndpointNumber,
|
|
19
24
|
ReceivedStatusResponseError,
|
|
20
25
|
Status,
|
|
21
26
|
StatusCode,
|
|
22
27
|
StatusResponseError,
|
|
23
28
|
TlvAny,
|
|
29
|
+
TlvAttributeReport,
|
|
24
30
|
TlvDataReport,
|
|
25
31
|
TlvDataReportForSend,
|
|
26
32
|
TlvDataVersionFilter,
|
|
@@ -796,8 +802,105 @@ export class IncomingInteractionClientMessenger extends InteractionMessenger {
|
|
|
796
802
|
return message;
|
|
797
803
|
}
|
|
798
804
|
|
|
799
|
-
|
|
800
|
-
|
|
805
|
+
/**
|
|
806
|
+
* Reads data report stream and aggregates them into a single report.
|
|
807
|
+
* Additionally, a callback can be provided that is called for each cluster chunk received.
|
|
808
|
+
*/
|
|
809
|
+
async readAggregateDataReport(
|
|
810
|
+
chunkListener?: (chunk: DecodedAttributeReportValue<any>[]) => Promise<void>,
|
|
811
|
+
expectedSubscriptionIds?: number[],
|
|
812
|
+
): Promise<DecodedDataReport> {
|
|
813
|
+
let result: DecodedDataReport | undefined = undefined;
|
|
814
|
+
let currentEndpointId: EndpointNumber | undefined = undefined;
|
|
815
|
+
let currentClusterId: ClusterId | undefined = undefined;
|
|
816
|
+
const currentClusterChunk = new Array<DecodedAttributeReportValue<any>>();
|
|
817
|
+
let pendingAttributeReports: TypeFromSchema<typeof TlvAttributeReport>[] | undefined = undefined;
|
|
818
|
+
|
|
819
|
+
const handleAttributeReportEntries = (
|
|
820
|
+
attributeReports: TypeFromSchema<typeof TlvAttributeReport>[] | undefined,
|
|
821
|
+
previousPendingAttributeReports: TypeFromSchema<typeof TlvAttributeReport>[] | undefined,
|
|
822
|
+
) => {
|
|
823
|
+
if (previousPendingAttributeReports?.length) {
|
|
824
|
+
attributeReports = attributeReports ?? [];
|
|
825
|
+
attributeReports.unshift(...previousPendingAttributeReports);
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
let lastAttributeDataIndex = -1;
|
|
829
|
+
if (attributeReports?.length) {
|
|
830
|
+
let lastEndpointId: EndpointNumber | undefined = undefined;
|
|
831
|
+
let lastClusterId: ClusterId | undefined = undefined;
|
|
832
|
+
let lastAttributeId: AttributeId | undefined = undefined;
|
|
833
|
+
for (let i = attributeReports.length - 1; i >= 0; i--) {
|
|
834
|
+
const attributeReport = attributeReports[i];
|
|
835
|
+
if (attributeReport.attributeData === undefined) {
|
|
836
|
+
break; // No data report, so nothing more to search for
|
|
837
|
+
}
|
|
838
|
+
const {
|
|
839
|
+
path: { endpointId, clusterId, attributeId },
|
|
840
|
+
} = attributeReport.attributeData;
|
|
841
|
+
if (lastEndpointId === undefined && lastClusterId === undefined && lastAttributeId === undefined) {
|
|
842
|
+
// Remember path of the last attribute data entry and check if previous entries match
|
|
843
|
+
lastEndpointId = endpointId;
|
|
844
|
+
lastClusterId = clusterId;
|
|
845
|
+
lastAttributeId = attributeId;
|
|
846
|
+
}
|
|
847
|
+
if (
|
|
848
|
+
endpointId === lastEndpointId &&
|
|
849
|
+
clusterId === lastClusterId &&
|
|
850
|
+
attributeId === lastAttributeId
|
|
851
|
+
) {
|
|
852
|
+
lastAttributeDataIndex = i;
|
|
853
|
+
continue;
|
|
854
|
+
}
|
|
855
|
+
break; // We found an attribute that does not match the last one, so we are done
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
if (lastAttributeDataIndex > 0) {
|
|
859
|
+
return attributeReports.splice(lastAttributeDataIndex);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
};
|
|
863
|
+
|
|
864
|
+
const processDecodedReport = async (
|
|
865
|
+
decodedReport: DecodedDataReport,
|
|
866
|
+
result: DecodedDataReport | undefined,
|
|
867
|
+
) => {
|
|
868
|
+
if (!result) {
|
|
869
|
+
result = decodedReport;
|
|
870
|
+
} else {
|
|
871
|
+
if (!result.attributeReports) {
|
|
872
|
+
result.attributeReports = decodedReport.attributeReports;
|
|
873
|
+
} else {
|
|
874
|
+
result.attributeReports.push(...decodedReport.attributeReports);
|
|
875
|
+
}
|
|
876
|
+
if (Array.isArray(decodedReport.eventReports)) {
|
|
877
|
+
if (!result.eventReports) {
|
|
878
|
+
result.eventReports = decodedReport.eventReports;
|
|
879
|
+
} else {
|
|
880
|
+
result.eventReports.push(...decodedReport.eventReports);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
if (chunkListener !== undefined && decodedReport.attributeReports) {
|
|
886
|
+
for (const data of decodedReport.attributeReports) {
|
|
887
|
+
const {
|
|
888
|
+
path: { endpointId, clusterId },
|
|
889
|
+
} = data;
|
|
890
|
+
if (currentEndpointId !== endpointId || currentClusterId !== clusterId) {
|
|
891
|
+
// We switched the cluster, so we need to send the current chunk first
|
|
892
|
+
if (currentClusterChunk.length > 0) {
|
|
893
|
+
await chunkListener(currentClusterChunk);
|
|
894
|
+
currentClusterChunk.length = 0;
|
|
895
|
+
}
|
|
896
|
+
currentEndpointId = endpointId;
|
|
897
|
+
currentClusterId = clusterId;
|
|
898
|
+
}
|
|
899
|
+
currentClusterChunk.push(data);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
return result;
|
|
903
|
+
};
|
|
801
904
|
|
|
802
905
|
for await (const report of this.readDataReports()) {
|
|
803
906
|
if (expectedSubscriptionIds !== undefined) {
|
|
@@ -820,24 +923,25 @@ export class IncomingInteractionClientMessenger extends InteractionMessenger {
|
|
|
820
923
|
throw new UnexpectedDataError(`Invalid subscription ID ${report.subscriptionId} received`);
|
|
821
924
|
}
|
|
822
925
|
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
926
|
+
report.attributeReports = report.attributeReports ?? [];
|
|
927
|
+
pendingAttributeReports = handleAttributeReportEntries(report.attributeReports, pendingAttributeReports);
|
|
928
|
+
|
|
929
|
+
result = await processDecodedReport(DecodedDataReport(report), result);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
if (pendingAttributeReports?.length && result !== undefined) {
|
|
933
|
+
result = await processDecodedReport(
|
|
934
|
+
DecodedDataReport({
|
|
935
|
+
interactionModelRevision: result.interactionModelRevision,
|
|
936
|
+
attributeReports: pendingAttributeReports,
|
|
937
|
+
}),
|
|
938
|
+
result,
|
|
939
|
+
);
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
if (chunkListener !== undefined && currentClusterChunk.length > 0) {
|
|
943
|
+
await chunkListener(currentClusterChunk);
|
|
944
|
+
currentClusterChunk.length = 0;
|
|
841
945
|
}
|
|
842
946
|
|
|
843
947
|
if (result === undefined) {
|
|
@@ -1007,8 +1111,8 @@ export class InteractionClientMessenger extends IncomingInteractionClientMesseng
|
|
|
1007
1111
|
await this.send(MessageType.SubscribeRequest, request);
|
|
1008
1112
|
}
|
|
1009
1113
|
|
|
1010
|
-
async readAggregateSubscribeResponse() {
|
|
1011
|
-
const report = await this.readAggregateDataReport();
|
|
1114
|
+
async readAggregateSubscribeResponse(chunkListener?: (chunk: DecodedAttributeReportValue<any>[]) => Promise<void>) {
|
|
1115
|
+
const report = await this.readAggregateDataReport(chunkListener);
|
|
1012
1116
|
const { subscriptionId } = report;
|
|
1013
1117
|
|
|
1014
1118
|
if (subscriptionId === undefined) {
|
|
@@ -1077,15 +1181,23 @@ export class InteractionClientMessenger extends IncomingInteractionClientMesseng
|
|
|
1077
1181
|
request: RequestT,
|
|
1078
1182
|
expectedProcessingTimeMs?: number,
|
|
1079
1183
|
): Promise<void> {
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1184
|
+
try {
|
|
1185
|
+
await this.send(requestMessageType, requestSchema.encode(request), {
|
|
1186
|
+
expectAckOnly: true,
|
|
1187
|
+
expectedProcessingTimeMs,
|
|
1188
|
+
logContext: {
|
|
1189
|
+
invokeFlags: Diagnostic.asFlags({
|
|
1190
|
+
suppressResponse: true,
|
|
1191
|
+
}),
|
|
1192
|
+
},
|
|
1193
|
+
});
|
|
1194
|
+
} catch (e) {
|
|
1195
|
+
// If we got anything other than a standalone ack, we throw when receiving a status response, otherwise we ignore it
|
|
1196
|
+
// Mainly needed because of a Matter-SDK bug where a command response is sent even when suppressResponse is true
|
|
1197
|
+
UnexpectedMessageError.accept(e);
|
|
1198
|
+
const { receivedMessage } = e;
|
|
1199
|
+
this.throwIfErrorStatusMessage(receivedMessage);
|
|
1200
|
+
}
|
|
1089
1201
|
}
|
|
1090
1202
|
|
|
1091
1203
|
private async request<RequestT, ResponseT>(
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { Environment, Environmental, Logger, MaybePromise, Time, Timer } from "#general";
|
|
8
|
+
import { DecodedDataReport } from "#interaction/DecodedDataReport.js";
|
|
8
9
|
import { MessageExchange } from "#protocol/MessageExchange.js";
|
|
9
10
|
import { ProtocolHandler } from "#protocol/ProtocolHandler.js";
|
|
10
11
|
import { INTERACTION_PROTOCOL_ID } from "#types";
|
|
11
|
-
import {
|
|
12
|
+
import { IncomingInteractionClientMessenger } from "./InteractionMessenger.js";
|
|
12
13
|
|
|
13
14
|
const logger = Logger.get("SubscriptionClient");
|
|
14
15
|
|
|
@@ -16,7 +17,7 @@ export interface RegisteredSubscription {
|
|
|
16
17
|
id: number;
|
|
17
18
|
maximumPeerResponseTimeMs: number;
|
|
18
19
|
maxIntervalS: number;
|
|
19
|
-
onData: (dataReport:
|
|
20
|
+
onData: (dataReport: DecodedDataReport) => MaybePromise<void>;
|
|
20
21
|
onTimeout?: () => void;
|
|
21
22
|
}
|
|
22
23
|
|
|
@@ -28,7 +29,7 @@ export interface RegisteredSubscription {
|
|
|
28
29
|
export class SubscriptionClient implements ProtocolHandler {
|
|
29
30
|
readonly id = INTERACTION_PROTOCOL_ID;
|
|
30
31
|
readonly requiresSecureSession = true;
|
|
31
|
-
readonly #listeners = new Map<number, (dataReport:
|
|
32
|
+
readonly #listeners = new Map<number, (dataReport: DecodedDataReport) => MaybePromise<void>>();
|
|
32
33
|
readonly #timeouts = new Map<number, Timer>();
|
|
33
34
|
|
|
34
35
|
constructor() {}
|
|
@@ -80,10 +81,10 @@ export class SubscriptionClient implements ProtocolHandler {
|
|
|
80
81
|
async onNewExchange(exchange: MessageExchange) {
|
|
81
82
|
const messenger = new IncomingInteractionClientMessenger(exchange);
|
|
82
83
|
|
|
83
|
-
let dataReport:
|
|
84
|
+
let dataReport: DecodedDataReport;
|
|
84
85
|
try {
|
|
85
86
|
// TODO Adjust this to getting packages as callback when received to handle error cases and checks outside
|
|
86
|
-
dataReport = await messenger.readAggregateDataReport([...this.#listeners.keys()]);
|
|
87
|
+
dataReport = await messenger.readAggregateDataReport(undefined, [...this.#listeners.keys()]);
|
|
87
88
|
} finally {
|
|
88
89
|
messenger.close().catch(error => logger.info("Error closing client messenger", error));
|
|
89
90
|
}
|
package/src/mdns/MdnsScanner.ts
CHANGED
|
@@ -1042,8 +1042,7 @@ export class MdnsScanner implements Scanner {
|
|
|
1042
1042
|
if (this.#closing) return;
|
|
1043
1043
|
const message = DnsCodec.decode(messageBytes);
|
|
1044
1044
|
if (message === undefined) return; // The message cannot be parsed
|
|
1045
|
-
if (
|
|
1046
|
-
return;
|
|
1045
|
+
if (!DnsMessageType.isResponse(message.messageType)) return;
|
|
1047
1046
|
|
|
1048
1047
|
const answers = this.#structureAnswers([...message.answers, ...message.additionalRecords]);
|
|
1049
1048
|
|
package/src/mdns/MdnsServer.ts
CHANGED
|
@@ -100,8 +100,8 @@ export class MdnsServer {
|
|
|
100
100
|
const message = DnsCodec.decode(messageBytes);
|
|
101
101
|
if (message === undefined) return; // The message cannot be parsed
|
|
102
102
|
const { transactionId, messageType, queries, answers: knownAnswers } = message;
|
|
103
|
-
if (
|
|
104
|
-
if (queries.length === 0) return; //
|
|
103
|
+
if (!DnsMessageType.isQuery(messageType)) return;
|
|
104
|
+
if (queries.length === 0) return; // TODO correctly handle TruncatedQueries by waiting and combining multiple queries
|
|
105
105
|
for (const portRecords of records.values()) {
|
|
106
106
|
let answers = queries.flatMap(query => this.#queryRecords(query, portRecords));
|
|
107
107
|
if (answers.length === 0) continue;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { ReadScope } from "#action/client/ReadScope.js";
|
|
7
8
|
import { Construction, MaybePromise } from "#general";
|
|
8
9
|
import { DecodedAttributeReportValue } from "#interaction/AttributeDataDecoder.js";
|
|
9
10
|
import { AttributeId, ClusterId, EndpointNumber, EventNumber } from "#types";
|
|
@@ -27,7 +28,7 @@ export abstract class PeerDataStore {
|
|
|
27
28
|
abstract maxEventNumber: EventNumber;
|
|
28
29
|
abstract updateLastEventNumber(eventNumber: EventNumber): MaybePromise<void>;
|
|
29
30
|
|
|
30
|
-
abstract persistAttributes(attributes: DecodedAttributeReportValue<any>[]): MaybePromise<void>;
|
|
31
|
+
abstract persistAttributes(attributes: DecodedAttributeReportValue<any>[], scope: ReadScope): MaybePromise<void>;
|
|
31
32
|
|
|
32
33
|
// TODO: Find a maybe better way to achieve this without functions
|
|
33
34
|
abstract retrieveAttribute(
|
|
@@ -41,4 +42,5 @@ export abstract class PeerDataStore {
|
|
|
41
42
|
filterEndpointId?: EndpointNumber,
|
|
42
43
|
filterClusterId?: ClusterId,
|
|
43
44
|
): { endpointId: EndpointNumber; clusterId: ClusterId; dataVersion: number }[];
|
|
45
|
+
abstract cleanupAttributeData(endpointId: EndpointNumber, clusterIds?: ClusterId[]): MaybePromise<void>;
|
|
44
46
|
}
|
|
@@ -327,9 +327,10 @@ export class ExchangeManager {
|
|
|
327
327
|
return;
|
|
328
328
|
}
|
|
329
329
|
const { session } = exchange;
|
|
330
|
+
this.#exchanges.delete(exchangeIndex);
|
|
330
331
|
if (NodeSession.is(session) && session.closingAfterExchangeFinished) {
|
|
331
332
|
logger.debug(
|
|
332
|
-
`Exchange index ${exchangeIndex} Session ${session.name} is already marked for closure. Close session now.`,
|
|
333
|
+
`Exchange index ${exchangeIndex} on Session ${session.name} is already marked for closure. Close session now.`,
|
|
333
334
|
);
|
|
334
335
|
try {
|
|
335
336
|
await this.#closeSession(session);
|
|
@@ -337,7 +338,6 @@ export class ExchangeManager {
|
|
|
337
338
|
logger.error(`Error closing session ${session.name}. Ignoring.`, error);
|
|
338
339
|
}
|
|
339
340
|
}
|
|
340
|
-
this.#exchanges.delete(exchangeIndex);
|
|
341
341
|
}
|
|
342
342
|
|
|
343
343
|
async #closeSession(session: NodeSession) {
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
ObserverGroup,
|
|
22
22
|
StorageContext,
|
|
23
23
|
StorageManager,
|
|
24
|
+
toHex,
|
|
24
25
|
} from "#general";
|
|
25
26
|
import { Subscription } from "#interaction/Subscription.js";
|
|
26
27
|
import { Specification } from "#model";
|
|
@@ -76,6 +77,7 @@ type ResumptionStorageRecord = {
|
|
|
76
77
|
sharedSecret: Uint8Array;
|
|
77
78
|
resumptionId: Uint8Array;
|
|
78
79
|
fabricId: FabricId;
|
|
80
|
+
fabricIndex: FabricIndex;
|
|
79
81
|
peerNodeId: NodeId;
|
|
80
82
|
sessionParameters: {
|
|
81
83
|
idleIntervalMs: number;
|
|
@@ -545,21 +547,21 @@ export class SessionManager {
|
|
|
545
547
|
([
|
|
546
548
|
address,
|
|
547
549
|
{ sharedSecret, resumptionId, peerNodeId, fabric, sessionParameters, caseAuthenticatedTags },
|
|
548
|
-
]) =>
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
550
|
+
]): ResumptionStorageRecord => ({
|
|
551
|
+
nodeId: address.nodeId,
|
|
552
|
+
sharedSecret,
|
|
553
|
+
resumptionId,
|
|
554
|
+
fabricId: fabric.fabricId,
|
|
555
|
+
fabricIndex: fabric.fabricIndex,
|
|
556
|
+
peerNodeId: peerNodeId,
|
|
557
|
+
sessionParameters: {
|
|
558
|
+
...sessionParameters,
|
|
559
|
+
supportedTransports: sessionParameters.supportedTransports
|
|
560
|
+
? SupportedTransportsSchema.encode(sessionParameters.supportedTransports)
|
|
561
|
+
: undefined,
|
|
562
|
+
},
|
|
563
|
+
caseAuthenticatedTags,
|
|
564
|
+
}),
|
|
563
565
|
),
|
|
564
566
|
);
|
|
565
567
|
}
|
|
@@ -578,6 +580,7 @@ export class SessionManager {
|
|
|
578
580
|
sharedSecret,
|
|
579
581
|
resumptionId,
|
|
580
582
|
fabricId,
|
|
583
|
+
fabricIndex,
|
|
581
584
|
peerNodeId,
|
|
582
585
|
sessionParameters: {
|
|
583
586
|
idleIntervalMs,
|
|
@@ -592,19 +595,27 @@ export class SessionManager {
|
|
|
592
595
|
} = {},
|
|
593
596
|
caseAuthenticatedTags,
|
|
594
597
|
}) => {
|
|
595
|
-
const fabric = this.#context.fabrics.find(
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
peerNodeId,
|
|
601
|
-
"for fabric index",
|
|
602
|
-
fabric?.fabricIndex,
|
|
598
|
+
const fabric = this.#context.fabrics.find(
|
|
599
|
+
fabric =>
|
|
600
|
+
fabric.fabricId === fabricId &&
|
|
601
|
+
// Backward compatibility logic: fabricIndex was added later (0.15.5), so it might be undefined in older records
|
|
602
|
+
(fabricIndex === undefined || fabric.fabricIndex === fabricIndex),
|
|
603
603
|
);
|
|
604
604
|
if (!fabric) {
|
|
605
|
-
logger.
|
|
605
|
+
logger.warn(
|
|
606
|
+
`Ignoring resumption record for fabric 0x${toHex(fabricId)} and index ${fabricIndex} because we cannot find a matching fabric`,
|
|
607
|
+
);
|
|
606
608
|
return;
|
|
607
609
|
}
|
|
610
|
+
logger.info(
|
|
611
|
+
"restoring resumption record for node",
|
|
612
|
+
fabric.addressOf(nodeId).toString(),
|
|
613
|
+
"and peer node",
|
|
614
|
+
fabric.addressOf(peerNodeId).toString(),
|
|
615
|
+
"for fabric id",
|
|
616
|
+
`0x${toHex(fabric.fabricId)}`,
|
|
617
|
+
`(0x${toHex(fabric.rootVendorId)}, "${fabric?.label}")`,
|
|
618
|
+
);
|
|
608
619
|
this.#resumptionRecords.set(fabric.addressOf(nodeId), {
|
|
609
620
|
sharedSecret,
|
|
610
621
|
resumptionId,
|
|
@@ -68,7 +68,8 @@ export class PaseServer implements ProtocolHandler {
|
|
|
68
68
|
// successfully established a session, the Commissionee SHALL NOT accept any more requests for new PASE
|
|
69
69
|
// sessions until session establishment fails or the successfully established PASE session is terminated on
|
|
70
70
|
// the commissioning channel.
|
|
71
|
-
|
|
71
|
+
const paseSession = this.sessions.getPaseSession();
|
|
72
|
+
if (paseSession !== undefined && !paseSession.isClosing) {
|
|
72
73
|
logger.info("Pase server: Pairing already in progress (PASE session exists), ignoring new exchange.");
|
|
73
74
|
} else if (this.#pairingTimer?.isRunning) {
|
|
74
75
|
logger.info(
|