@matter/protocol 0.16.10 → 0.16.11-alpha.0-20260225-033797f3c
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/certificate/kinds/Certificate.js +5 -5
- package/dist/cjs/certificate/kinds/Certificate.js.map +1 -1
- package/dist/cjs/common/BleScanner.d.ts +38 -0
- package/dist/cjs/common/BleScanner.d.ts.map +1 -0
- package/dist/cjs/common/BleScanner.js +302 -0
- package/dist/cjs/common/BleScanner.js.map +6 -0
- package/dist/cjs/common/index.d.ts +1 -0
- package/dist/cjs/common/index.d.ts.map +1 -1
- package/dist/cjs/common/index.js +1 -0
- package/dist/cjs/common/index.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.js +9 -7
- package/dist/cjs/peer/ControllerCommissioningFlow.js.map +2 -2
- package/dist/cjs/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.js +1 -2
- package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
- package/dist/esm/certificate/kinds/Certificate.js +5 -5
- package/dist/esm/certificate/kinds/Certificate.js.map +1 -1
- package/dist/esm/common/BleScanner.d.ts +38 -0
- package/dist/esm/common/BleScanner.d.ts.map +1 -0
- package/dist/esm/common/BleScanner.js +293 -0
- package/dist/esm/common/BleScanner.js.map +6 -0
- package/dist/esm/common/index.d.ts +1 -0
- package/dist/esm/common/index.d.ts.map +1 -1
- package/dist/esm/common/index.js +1 -0
- package/dist/esm/common/index.js.map +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.js +9 -7
- package/dist/esm/peer/ControllerCommissioningFlow.js.map +2 -2
- package/dist/esm/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/esm/protocol/ExchangeManager.js +1 -2
- package/dist/esm/protocol/ExchangeManager.js.map +1 -1
- package/package.json +6 -6
- package/src/certificate/kinds/Certificate.ts +5 -5
- package/src/common/BleScanner.ts +387 -0
- package/src/common/index.ts +1 -0
- package/src/peer/ControllerCommissioningFlow.ts +6 -4
- package/src/protocol/ExchangeManager.ts +1 -2
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2026 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
Bytes,
|
|
9
|
+
ChannelType,
|
|
10
|
+
createPromise,
|
|
11
|
+
Diagnostic,
|
|
12
|
+
Duration,
|
|
13
|
+
Logger,
|
|
14
|
+
MaybePromise,
|
|
15
|
+
Millis,
|
|
16
|
+
Seconds,
|
|
17
|
+
Time,
|
|
18
|
+
Timer,
|
|
19
|
+
Timespan,
|
|
20
|
+
} from "#general";
|
|
21
|
+
import { VendorId } from "#types";
|
|
22
|
+
import { BleError } from "../ble/Ble.js";
|
|
23
|
+
import { BtpCodec } from "../codec/BtpCodec.js";
|
|
24
|
+
import { CommissionableDevice, CommissionableDeviceIdentifiers, Scanner } from "./Scanner.js";
|
|
25
|
+
|
|
26
|
+
const logger = Logger.get("BleScanner");
|
|
27
|
+
|
|
28
|
+
export interface BlePeripheral {
|
|
29
|
+
readonly address: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface BleScannerClient {
|
|
33
|
+
setDiscoveryCallback(callback: (peripheral: BlePeripheral, data: Bytes) => void): void;
|
|
34
|
+
startScanning(): Promise<void>;
|
|
35
|
+
stopScanning(): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type CommissionableDeviceData = CommissionableDevice & {
|
|
39
|
+
SD: number; // Additional Field for Short discriminator
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export type DiscoveredBleDevice = {
|
|
43
|
+
deviceData: CommissionableDeviceData;
|
|
44
|
+
peripheral: BlePeripheral;
|
|
45
|
+
hasAdditionalAdvertisementData: boolean;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export class BleScanner implements Scanner {
|
|
49
|
+
readonly type = ChannelType.BLE;
|
|
50
|
+
|
|
51
|
+
readonly #client: BleScannerClient;
|
|
52
|
+
readonly #recordWaiters = new Map<
|
|
53
|
+
string,
|
|
54
|
+
{
|
|
55
|
+
resolver: () => void;
|
|
56
|
+
timer?: Timer;
|
|
57
|
+
resolveOnUpdatedRecords: boolean;
|
|
58
|
+
cancelResolver?: (value: void) => void;
|
|
59
|
+
}
|
|
60
|
+
>();
|
|
61
|
+
readonly #discoveredMatterDevices = new Map<string, DiscoveredBleDevice>();
|
|
62
|
+
|
|
63
|
+
constructor(client: BleScannerClient) {
|
|
64
|
+
this.#client = client;
|
|
65
|
+
this.#client.setDiscoveryCallback((peripheral, manufacturerData) =>
|
|
66
|
+
this.#handleDiscoveredDevice(peripheral, manufacturerData),
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public getDiscoveredDevice(address: string): DiscoveredBleDevice {
|
|
71
|
+
const device = this.#discoveredMatterDevices.get(address);
|
|
72
|
+
if (device === undefined) {
|
|
73
|
+
throw new BleError(`No device found for address ${address}`);
|
|
74
|
+
}
|
|
75
|
+
return device;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Registers a deferred promise for a specific queryId together with a timeout and return the promise.
|
|
80
|
+
* The promise will be resolved when the timer runs out latest.
|
|
81
|
+
*/
|
|
82
|
+
async #registerWaiterPromise(
|
|
83
|
+
queryId: string,
|
|
84
|
+
timeout?: Duration,
|
|
85
|
+
resolveOnUpdatedRecords = true,
|
|
86
|
+
cancelResolver?: (value: void) => void,
|
|
87
|
+
) {
|
|
88
|
+
const { promise, resolver } = createPromise<void>();
|
|
89
|
+
let timer;
|
|
90
|
+
if (timeout) {
|
|
91
|
+
timer = Time.getTimer("BLE query timeout", timeout, () => {
|
|
92
|
+
cancelResolver?.();
|
|
93
|
+
this.#finishWaiter(queryId, true);
|
|
94
|
+
}).start();
|
|
95
|
+
}
|
|
96
|
+
this.#recordWaiters.set(queryId, { resolver, timer, resolveOnUpdatedRecords, cancelResolver });
|
|
97
|
+
logger.debug(
|
|
98
|
+
`Registered waiter for query ${queryId} with timeout ${timeout === undefined ? "(none)" : Duration.format(timeout)} ${
|
|
99
|
+
resolveOnUpdatedRecords ? "" : " (not resolving on updated records)"
|
|
100
|
+
}`,
|
|
101
|
+
);
|
|
102
|
+
await promise;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Remove a waiter promise for a specific queryId and stop the connected timer. If required also resolve the
|
|
107
|
+
* promise.
|
|
108
|
+
*/
|
|
109
|
+
#finishWaiter(queryId: string, resolvePromise: boolean, isUpdatedRecord = false) {
|
|
110
|
+
const waiter = this.#recordWaiters.get(queryId);
|
|
111
|
+
if (waiter === undefined) return;
|
|
112
|
+
const { timer, resolver, resolveOnUpdatedRecords } = waiter;
|
|
113
|
+
if (isUpdatedRecord && !resolveOnUpdatedRecords) return;
|
|
114
|
+
logger.debug(`Finishing waiter for query ${queryId}, resolving: ${resolvePromise}`);
|
|
115
|
+
timer?.stop();
|
|
116
|
+
if (resolvePromise) {
|
|
117
|
+
resolver();
|
|
118
|
+
}
|
|
119
|
+
this.#recordWaiters.delete(queryId);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
cancelCommissionableDeviceDiscovery(identifier: CommissionableDeviceIdentifiers, resolvePromise = true) {
|
|
123
|
+
const queryKey = this.#buildCommissionableQueryIdentifier(identifier);
|
|
124
|
+
if (queryKey === undefined) return;
|
|
125
|
+
const { cancelResolver } = this.#recordWaiters.get(queryKey) ?? {};
|
|
126
|
+
// Mark as canceled to not loop further in discovery, if cancel-resolver is used
|
|
127
|
+
cancelResolver?.();
|
|
128
|
+
this.#finishWaiter(queryKey, resolvePromise);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
#handleDiscoveredDevice(peripheral: BlePeripheral, manufacturerServiceData: Bytes) {
|
|
132
|
+
const address = peripheral.address;
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
const { discriminator, vendorId, productId, hasAdditionalAdvertisementData } =
|
|
136
|
+
BtpCodec.decodeBleAdvertisementServiceData(manufacturerServiceData);
|
|
137
|
+
|
|
138
|
+
const deviceData: CommissionableDeviceData = {
|
|
139
|
+
deviceIdentifier: address,
|
|
140
|
+
D: discriminator,
|
|
141
|
+
SD: (discriminator >> 8) & 0x0f,
|
|
142
|
+
VP: `${vendorId}+${productId}`,
|
|
143
|
+
CM: 1, // Can be no other mode,
|
|
144
|
+
addresses: [{ type: "ble", peripheralAddress: address }],
|
|
145
|
+
};
|
|
146
|
+
const deviceExisting = this.#discoveredMatterDevices.has(address);
|
|
147
|
+
|
|
148
|
+
logger.debug(
|
|
149
|
+
`${deviceExisting ? "Re-" : ""}Discovered device ${address} data: ${Diagnostic.json(deviceData)}`,
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
this.#discoveredMatterDevices.set(address, {
|
|
153
|
+
deviceData,
|
|
154
|
+
peripheral,
|
|
155
|
+
hasAdditionalAdvertisementData,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const queryKey = this.#findCommissionableQueryIdentifier(deviceData);
|
|
159
|
+
if (queryKey !== undefined) {
|
|
160
|
+
this.#finishWaiter(queryKey, true, deviceExisting);
|
|
161
|
+
}
|
|
162
|
+
} catch (error) {
|
|
163
|
+
logger.debug(
|
|
164
|
+
`Discovered device ${address} ${manufacturerServiceData === undefined ? undefined : Bytes.toHex(manufacturerServiceData)} does not seem to be a valid Matter device: ${error}`,
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
#findCommissionableQueryIdentifier(record: CommissionableDeviceData) {
|
|
170
|
+
const longDiscriminatorQueryId = this.#buildCommissionableQueryIdentifier({ longDiscriminator: record.D });
|
|
171
|
+
if (longDiscriminatorQueryId !== undefined && this.#recordWaiters.has(longDiscriminatorQueryId)) {
|
|
172
|
+
return longDiscriminatorQueryId;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const shortDiscriminatorQueryId = this.#buildCommissionableQueryIdentifier({ shortDiscriminator: record.SD });
|
|
176
|
+
if (shortDiscriminatorQueryId !== undefined && this.#recordWaiters.has(shortDiscriminatorQueryId)) {
|
|
177
|
+
return shortDiscriminatorQueryId;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (record.VP !== undefined) {
|
|
181
|
+
const vpParts = record.VP.split("+");
|
|
182
|
+
const vendorId = VendorId(parseInt(vpParts[0]));
|
|
183
|
+
const productId = vpParts[1] !== undefined ? parseInt(vpParts[1]) : undefined;
|
|
184
|
+
|
|
185
|
+
// Check vendorId+productId combo first (most specific)
|
|
186
|
+
if (productId !== undefined) {
|
|
187
|
+
const vendorProductQueryId = this.#buildCommissionableQueryIdentifier({
|
|
188
|
+
vendorId,
|
|
189
|
+
productId,
|
|
190
|
+
});
|
|
191
|
+
if (vendorProductQueryId !== undefined && this.#recordWaiters.has(vendorProductQueryId)) {
|
|
192
|
+
return vendorProductQueryId;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const vendorIdQueryId = this.#buildCommissionableQueryIdentifier({ vendorId });
|
|
197
|
+
if (vendorIdQueryId !== undefined && this.#recordWaiters.has(vendorIdQueryId)) {
|
|
198
|
+
return vendorIdQueryId;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (productId !== undefined) {
|
|
202
|
+
const productIdQueryId = this.#buildCommissionableQueryIdentifier({ productId });
|
|
203
|
+
if (productIdQueryId !== undefined && this.#recordWaiters.has(productIdQueryId)) {
|
|
204
|
+
return productIdQueryId;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (this.#recordWaiters.has("*")) {
|
|
210
|
+
return "*";
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Builds an identifier string for commissionable queries based on the given identifier object.
|
|
218
|
+
* Some identifiers are identical to the official DNS-SD identifiers, others are custom.
|
|
219
|
+
*/
|
|
220
|
+
#buildCommissionableQueryIdentifier(identifier: CommissionableDeviceIdentifiers) {
|
|
221
|
+
if ("instanceId" in identifier) {
|
|
222
|
+
// instanceId is not supported in BLE scanning
|
|
223
|
+
return undefined;
|
|
224
|
+
} else if ("longDiscriminator" in identifier) {
|
|
225
|
+
return `D:${identifier.longDiscriminator}`;
|
|
226
|
+
} else if ("shortDiscriminator" in identifier) {
|
|
227
|
+
return `SD:${identifier.shortDiscriminator}`;
|
|
228
|
+
} else if ("vendorId" in identifier && "productId" in identifier) {
|
|
229
|
+
return `VP:${identifier.vendorId}+${identifier.productId}`;
|
|
230
|
+
} else if ("vendorId" in identifier) {
|
|
231
|
+
return `V:${identifier.vendorId}`;
|
|
232
|
+
} else if ("deviceType" in identifier) {
|
|
233
|
+
// deviceType is not supported in BLE scanning
|
|
234
|
+
return undefined;
|
|
235
|
+
} else if ("productId" in identifier) {
|
|
236
|
+
// Custom identifier because normally productId is only included in TXT record
|
|
237
|
+
return `P:${identifier.productId}`;
|
|
238
|
+
} else return "*";
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
#getCommissionableDevices(identifier: CommissionableDeviceIdentifiers) {
|
|
242
|
+
const storedRecords = Array.from(this.#discoveredMatterDevices.values());
|
|
243
|
+
|
|
244
|
+
const foundRecords = new Array<DiscoveredBleDevice>();
|
|
245
|
+
if ("instanceId" in identifier || "deviceType" in identifier) {
|
|
246
|
+
// These identifier types are not supported in BLE scanning
|
|
247
|
+
return foundRecords;
|
|
248
|
+
} else if ("longDiscriminator" in identifier) {
|
|
249
|
+
foundRecords.push(...storedRecords.filter(({ deviceData: { D } }) => D === identifier.longDiscriminator));
|
|
250
|
+
} else if ("shortDiscriminator" in identifier) {
|
|
251
|
+
foundRecords.push(
|
|
252
|
+
...storedRecords.filter(({ deviceData: { SD } }) => SD === identifier.shortDiscriminator),
|
|
253
|
+
);
|
|
254
|
+
} else if ("vendorId" in identifier && "productId" in identifier) {
|
|
255
|
+
foundRecords.push(
|
|
256
|
+
...storedRecords.filter(
|
|
257
|
+
({ deviceData: { VP } }) => VP === `${identifier.vendorId}+${identifier.productId}`,
|
|
258
|
+
),
|
|
259
|
+
);
|
|
260
|
+
} else if ("vendorId" in identifier) {
|
|
261
|
+
foundRecords.push(
|
|
262
|
+
...storedRecords.filter(
|
|
263
|
+
({ deviceData: { VP } }) =>
|
|
264
|
+
VP === `${identifier.vendorId}` || VP?.startsWith(`${identifier.vendorId}+`),
|
|
265
|
+
),
|
|
266
|
+
);
|
|
267
|
+
} else if ("productId" in identifier) {
|
|
268
|
+
foundRecords.push(
|
|
269
|
+
...storedRecords.filter(({ deviceData: { VP } }) => VP?.endsWith(`+${identifier.productId}`)),
|
|
270
|
+
);
|
|
271
|
+
} else {
|
|
272
|
+
foundRecords.push(...storedRecords.filter(({ deviceData: { CM } }) => CM === 1 || CM === 2));
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return foundRecords;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
async findOperationalDevice(): Promise<undefined> {
|
|
279
|
+
logger.info(`skip BLE scan because scanning for operational devices is not supported`);
|
|
280
|
+
return undefined;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
getDiscoveredOperationalDevice(): undefined {
|
|
284
|
+
logger.info(`skip BLE scan because scanning for operational devices is not supported`);
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
async findCommissionableDevices(
|
|
289
|
+
identifier: CommissionableDeviceIdentifiers,
|
|
290
|
+
timeout = Seconds(10),
|
|
291
|
+
ignoreExistingRecords = false,
|
|
292
|
+
): Promise<CommissionableDevice[]> {
|
|
293
|
+
const queryKey = this.#buildCommissionableQueryIdentifier(identifier);
|
|
294
|
+
if (queryKey === undefined) {
|
|
295
|
+
return [];
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
let storedRecords = this.#getCommissionableDevices(identifier);
|
|
299
|
+
if (ignoreExistingRecords) {
|
|
300
|
+
// We want to have a fresh discovery result, so clear out the stored records because they might be outdated
|
|
301
|
+
for (const record of storedRecords) {
|
|
302
|
+
this.#discoveredMatterDevices.delete(record.peripheral.address);
|
|
303
|
+
}
|
|
304
|
+
storedRecords = [];
|
|
305
|
+
}
|
|
306
|
+
if (storedRecords.length === 0) {
|
|
307
|
+
await this.#client.startScanning();
|
|
308
|
+
await this.#registerWaiterPromise(queryKey, timeout);
|
|
309
|
+
|
|
310
|
+
storedRecords = this.#getCommissionableDevices(identifier);
|
|
311
|
+
await this.#client.stopScanning();
|
|
312
|
+
}
|
|
313
|
+
return storedRecords.map(({ deviceData }) => deviceData);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
async findCommissionableDevicesContinuously(
|
|
317
|
+
identifier: CommissionableDeviceIdentifiers,
|
|
318
|
+
callback: (device: CommissionableDevice) => void,
|
|
319
|
+
timeout?: Duration,
|
|
320
|
+
cancelSignal?: Promise<void>,
|
|
321
|
+
): Promise<CommissionableDevice[]> {
|
|
322
|
+
const queryKey = this.#buildCommissionableQueryIdentifier(identifier);
|
|
323
|
+
if (queryKey === undefined) {
|
|
324
|
+
return [];
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const discoveredDevices = new Set<string>();
|
|
328
|
+
|
|
329
|
+
const discoveryEndTime = timeout ? Time.nowMs + timeout : undefined;
|
|
330
|
+
await this.#client.startScanning();
|
|
331
|
+
|
|
332
|
+
let queryResolver: ((value: void) => void) | undefined;
|
|
333
|
+
if (cancelSignal === undefined) {
|
|
334
|
+
const { promise, resolver } = createPromise<void>();
|
|
335
|
+
cancelSignal = promise;
|
|
336
|
+
queryResolver = resolver;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
let canceled = false;
|
|
340
|
+
cancelSignal?.then(
|
|
341
|
+
() => {
|
|
342
|
+
canceled = true;
|
|
343
|
+
this.#finishWaiter(queryKey, true);
|
|
344
|
+
},
|
|
345
|
+
cause => {
|
|
346
|
+
logger.error("Unexpected error canceling commissioning", cause);
|
|
347
|
+
},
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
while (!canceled) {
|
|
351
|
+
this.#getCommissionableDevices(identifier).forEach(({ deviceData }) => {
|
|
352
|
+
const { deviceIdentifier } = deviceData;
|
|
353
|
+
if (!discoveredDevices.has(deviceIdentifier)) {
|
|
354
|
+
discoveredDevices.add(deviceIdentifier);
|
|
355
|
+
callback(deviceData);
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
let remainingTime;
|
|
360
|
+
if (discoveryEndTime !== undefined) {
|
|
361
|
+
remainingTime = Millis.ceil(Timespan(Time.nowMs, discoveryEndTime).duration);
|
|
362
|
+
if (remainingTime <= 0) {
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
await this.#registerWaiterPromise(queryKey, remainingTime, false, queryResolver);
|
|
368
|
+
}
|
|
369
|
+
await this.#client.stopScanning();
|
|
370
|
+
return this.#getCommissionableDevices(identifier).map(({ deviceData }) => deviceData);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
getDiscoveredCommissionableDevices(identifier: CommissionableDeviceIdentifiers): CommissionableDevice[] {
|
|
374
|
+
return this.#getCommissionableDevices(identifier).map(({ deviceData }) => deviceData);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
protected closeClient(): MaybePromise<void> {
|
|
378
|
+
return this.#client.stopScanning();
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
async close() {
|
|
382
|
+
await this.closeClient();
|
|
383
|
+
[...this.#recordWaiters.keys()].forEach(queryId =>
|
|
384
|
+
this.#finishWaiter(queryId, !!this.#recordWaiters.get(queryId)?.timer),
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
}
|
package/src/common/index.ts
CHANGED
|
@@ -1501,7 +1501,9 @@ export class ControllerCommissioningFlow {
|
|
|
1501
1501
|
);
|
|
1502
1502
|
|
|
1503
1503
|
if (addNetworkingStatus !== NetworkCommissioning.NetworkCommissioningStatus.Success) {
|
|
1504
|
-
throw new ThreadNetworkSetupFailedError(
|
|
1504
|
+
throw new ThreadNetworkSetupFailedError(
|
|
1505
|
+
`Commissionee failed to add Thread network: status=${NetworkCommissioning.NetworkCommissioningStatus[addNetworkingStatus]} (${addNetworkingStatus})${addDebugText ? ` ${addDebugText}` : ""}`,
|
|
1506
|
+
);
|
|
1505
1507
|
}
|
|
1506
1508
|
if (networkIndex === undefined) {
|
|
1507
1509
|
throw new ThreadNetworkSetupFailedError(`Commissionee did not return network index`);
|
|
@@ -1538,7 +1540,7 @@ export class ControllerCommissioningFlow {
|
|
|
1538
1540
|
|
|
1539
1541
|
await this.#ensureFailsafeTimerFor(Seconds(connectMaxTimeSeconds));
|
|
1540
1542
|
|
|
1541
|
-
const
|
|
1543
|
+
const { networkingStatus, debugText } = await this.#invokeCommand(
|
|
1542
1544
|
{
|
|
1543
1545
|
endpoint: RootEndpointNumber,
|
|
1544
1546
|
cluster: NetworkCommissioning.Complete,
|
|
@@ -1553,9 +1555,9 @@ export class ControllerCommissioningFlow {
|
|
|
1553
1555
|
},
|
|
1554
1556
|
);
|
|
1555
1557
|
|
|
1556
|
-
if (
|
|
1558
|
+
if (networkingStatus !== NetworkCommissioning.NetworkCommissioningStatus.Success) {
|
|
1557
1559
|
throw new ThreadNetworkSetupFailedError(
|
|
1558
|
-
`Commissionee failed to connect to Thread network: ${
|
|
1560
|
+
`Commissionee failed to connect to Thread network: status=${NetworkCommissioning.NetworkCommissioningStatus[networkingStatus]} (${networkingStatus})${debugText ? ` ${debugText}` : ""}`,
|
|
1559
1561
|
);
|
|
1560
1562
|
}
|
|
1561
1563
|
logger.debug(
|
|
@@ -445,9 +445,8 @@ export class ExchangeManager {
|
|
|
445
445
|
netInterface.onData((socket, data) => {
|
|
446
446
|
if (udpInterface && data.byteLength > socket.maxPayloadSize) {
|
|
447
447
|
logger.warn(
|
|
448
|
-
`
|
|
448
|
+
`Received UDP message from ${socket.name} with size ${data.byteLength}, which is larger than the maximum allowed size of ${socket.maxPayloadSize}`,
|
|
449
449
|
);
|
|
450
|
-
return;
|
|
451
450
|
}
|
|
452
451
|
|
|
453
452
|
this.#workers.add(this.#onMessage(socket, data));
|