@onekeyfe/hd-transport-react-native 1.2.0-alpha.133 → 1.2.0-alpha.133-ok59992
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/index.d.ts +1 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -147
- package/package.json +5 -5
- package/src/__tests__/protocolV2Link.test.ts +0 -91
- package/src/index.ts +49 -168
package/dist/index.d.ts
CHANGED
|
@@ -53,7 +53,6 @@ declare const getFirmwareUploadWriteRetryType: (error: unknown) => FirmwareUploa
|
|
|
53
53
|
* A healthy packet completes in milliseconds, so this only fires on a dead link.
|
|
54
54
|
*/
|
|
55
55
|
declare const BLE_WRITE_PACKET_TIMEOUT_MS = 10000;
|
|
56
|
-
declare const BLE_NATIVE_TEARDOWN_TIMEOUT_MS = 3000;
|
|
57
56
|
/** Consecutive wedged writes on one device before the BLE manager itself is recreated. */
|
|
58
57
|
declare const BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD = 2;
|
|
59
58
|
type ProtocolV2BleTuning = {
|
|
@@ -133,8 +132,6 @@ declare class ReactNativeBleTransport {
|
|
|
133
132
|
private androidHighPriorityDevices;
|
|
134
133
|
private androidPriorityResetTimers;
|
|
135
134
|
private nextMonitorToken;
|
|
136
|
-
/** Serializes transport lifecycle changes for the same physical device. */
|
|
137
|
-
private lifecycleOperations;
|
|
138
135
|
constructor(options: TransportOptions);
|
|
139
136
|
init(logger: any, emitter: EventEmitter): void;
|
|
140
137
|
configure(signedData: any): void;
|
|
@@ -156,20 +153,14 @@ declare class ReactNativeBleTransport {
|
|
|
156
153
|
uuid: string;
|
|
157
154
|
protocolType: ProtocolType;
|
|
158
155
|
}>;
|
|
159
|
-
private acquireUnlocked;
|
|
160
156
|
_monitorCharacteristic(characteristic: Characteristic, uuid: string, monitorToken: number, notifyTransactionId: string): Subscription;
|
|
161
157
|
release(uuid: string, onclose?: boolean): Promise<boolean>;
|
|
162
|
-
private releaseUnlocked;
|
|
163
158
|
private releaseNative;
|
|
164
159
|
post(session: string, name: string, data: Record<string, unknown>): Promise<void>;
|
|
165
160
|
call(uuid: string, name: string, data: Record<string, unknown>, options?: TransportCallOptions): Promise<transport.MessageFromOneKey>;
|
|
166
161
|
private callProtocolV1;
|
|
167
162
|
stop(): void;
|
|
168
163
|
disconnect(session: string): Promise<void>;
|
|
169
|
-
private disconnectUnlocked;
|
|
170
|
-
private runNativeTeardown;
|
|
171
|
-
private runBestEffortNativeOperation;
|
|
172
|
-
private runLifecycleOperation;
|
|
173
164
|
cancel(): void;
|
|
174
165
|
/** Run a native connect under the JS backstop budget. */
|
|
175
166
|
private connectWithTimeout;
|
|
@@ -224,4 +215,4 @@ declare class ReactNativeBleTransport {
|
|
|
224
215
|
getProtocolType(path: string): ProtocolType | undefined;
|
|
225
216
|
}
|
|
226
217
|
|
|
227
|
-
export { BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD, BLE_CONNECT_TIMEOUT_MS, BLE_GATT_SETUP_TIMEOUT_MS,
|
|
218
|
+
export { BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD, BLE_CONNECT_TIMEOUT_MS, BLE_GATT_SETUP_TIMEOUT_MS, BLE_WRITE_PACKET_TIMEOUT_MS, BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD, IOneKeyDevice, PROTOCOL_REPROBE_FALLBACK_ATTEMPTS, ProtocolV2BleTuning, configureProtocolV2BleTuning, ReactNativeBleTransport as default, getFirmwareUploadWriteRetryType, getProtocolV2BleTuning, resetProtocolV2BleTuning };
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAIL,UAAU,IAAI,aAAa,EAG5B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,SAAS,EAAE,EAChB,KAAK,oBAAoB,EAIzB,KAAK,YAAY,EAKjB,KAAK,oBAAoB,EAI1B,MAAM,wBAAwB,CAAC;AA0BhC,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAI1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAgBjE,KAAK,4BAA4B,GAAG,WAAW,CAAC;AAChD,KAAK,0BAA0B,GAAG;IAChC,mBAAmB,EAAE,cAAc,CAAC;IACpC,oBAAoB,EAAE,cAAc,CAAC;CACtC,CAAC;AAkCF,eAAO,MAAM,+BAA+B,UACnC,OAAO,KACb,4BAA4B,GAAG,IAsBjC,CAAC;AAcF,eAAO,MAAM,2BAA2B,QAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -277,7 +277,6 @@ const resolveFirmwareUploadRetryDelay = (attempt, baseDelayMs = 200, maxDelayMs
|
|
|
277
277
|
const PROTOCOL_PROBE_TIMEOUT_MS = 3000;
|
|
278
278
|
const PROTOCOL_V2_PROBE_TIMEOUT_MS = 10000;
|
|
279
279
|
const BLE_WRITE_PACKET_TIMEOUT_MS = 10000;
|
|
280
|
-
const BLE_NATIVE_TEARDOWN_TIMEOUT_MS = 3000;
|
|
281
280
|
const WEDGED_WRITE_MESSAGE = 'BLE write timeout after';
|
|
282
281
|
const isWedgedWriteError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleWriteCharacteristicError &&
|
|
283
282
|
typeof (error === null || error === void 0 ? void 0 : error.message) === 'string' &&
|
|
@@ -435,7 +434,6 @@ class ReactNativeBleTransport {
|
|
|
435
434
|
this.androidHighPriorityDevices = new Set();
|
|
436
435
|
this.androidPriorityResetTimers = new Map();
|
|
437
436
|
this.nextMonitorToken = 1;
|
|
438
|
-
this.lifecycleOperations = new Map();
|
|
439
437
|
this.scanTimeout = (_a = options.scanTimeout) !== null && _a !== void 0 ? _a : DEVICE_SCAN_TIMEOUT_MS;
|
|
440
438
|
}
|
|
441
439
|
init(logger, emitter) {
|
|
@@ -793,18 +791,12 @@ class ReactNativeBleTransport {
|
|
|
793
791
|
});
|
|
794
792
|
}
|
|
795
793
|
acquire(input) {
|
|
794
|
+
var _a, _b;
|
|
796
795
|
return __awaiter(this, void 0, void 0, function* () {
|
|
797
|
-
const { uuid } = input;
|
|
796
|
+
const { uuid, forceCleanRunPromise, expectedProtocol } = input;
|
|
798
797
|
if (!uuid) {
|
|
799
798
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleRequiredUUID);
|
|
800
799
|
}
|
|
801
|
-
return this.runLifecycleOperation(uuid, () => this.acquireUnlocked(input));
|
|
802
|
-
});
|
|
803
|
-
}
|
|
804
|
-
acquireUnlocked(input) {
|
|
805
|
-
var _a, _b;
|
|
806
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
807
|
-
const { uuid, forceCleanRunPromise, expectedProtocol } = input;
|
|
808
800
|
const cachedTransport = transportCache[uuid];
|
|
809
801
|
if (cachedTransport) {
|
|
810
802
|
const cachedProtocol = this.deviceProtocol.get(uuid);
|
|
@@ -816,7 +808,7 @@ class ReactNativeBleTransport {
|
|
|
816
808
|
return { uuid, protocolType: cachedProtocol };
|
|
817
809
|
}
|
|
818
810
|
Log === null || Log === void 0 ? void 0 : Log.debug('transport not reusable, will release: ', uuid);
|
|
819
|
-
yield this.
|
|
811
|
+
yield this.release(uuid, true);
|
|
820
812
|
}
|
|
821
813
|
let device = null;
|
|
822
814
|
if (forceCleanRunPromise && this.runPromise) {
|
|
@@ -917,7 +909,7 @@ class ReactNativeBleTransport {
|
|
|
917
909
|
const protocolHint = expectedProtocol
|
|
918
910
|
? undefined
|
|
919
911
|
: (_b = (_a = input.protocolHint) !== null && _a !== void 0 ? _a : this.deviceProtocolHints.get(uuid)) !== null && _b !== void 0 ? _b : inferProtocolHintFromDeviceName(getDeviceDisplayName(acquiredDevice));
|
|
920
|
-
yield this.
|
|
912
|
+
yield this.release(uuid, true);
|
|
921
913
|
if (protocolHint) {
|
|
922
914
|
this.deviceProtocolHints.set(uuid, protocolHint);
|
|
923
915
|
}
|
|
@@ -937,7 +929,7 @@ class ReactNativeBleTransport {
|
|
|
937
929
|
return { uuid, protocolType };
|
|
938
930
|
}
|
|
939
931
|
catch (error) {
|
|
940
|
-
yield this.
|
|
932
|
+
yield this.release(uuid, true);
|
|
941
933
|
throw error;
|
|
942
934
|
}
|
|
943
935
|
});
|
|
@@ -1048,21 +1040,15 @@ class ReactNativeBleTransport {
|
|
|
1048
1040
|
return subscription;
|
|
1049
1041
|
}
|
|
1050
1042
|
release(uuid, onclose = false) {
|
|
1051
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1052
|
-
return this.runLifecycleOperation(uuid, () => this.releaseUnlocked(uuid, onclose));
|
|
1053
|
-
});
|
|
1054
|
-
}
|
|
1055
|
-
releaseUnlocked(uuid, onclose = false) {
|
|
1056
1043
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1057
1044
|
yield this.protocolV2Links.invalidateLink(uuid, 'React Native BLE transport released');
|
|
1058
1045
|
return this.releaseNative(uuid, onclose);
|
|
1059
1046
|
});
|
|
1060
1047
|
}
|
|
1061
1048
|
releaseNative(uuid, onclose = false) {
|
|
1062
|
-
var _a, _b, _c, _d, _e;
|
|
1049
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1063
1050
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1064
1051
|
const transport = transportCache[uuid];
|
|
1065
|
-
const manager = this.blePlxManager;
|
|
1066
1052
|
if (this.runPromise && this.runPromiseDeviceId === uuid) {
|
|
1067
1053
|
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
1068
1054
|
this.runPromise.reject(error);
|
|
@@ -1078,6 +1064,7 @@ class ReactNativeBleTransport {
|
|
|
1078
1064
|
this.resetProtocolV2Frames(uuid);
|
|
1079
1065
|
return Promise.resolve(true);
|
|
1080
1066
|
}
|
|
1067
|
+
yield this.restoreAndroidConnectionPriority(uuid, transport);
|
|
1081
1068
|
if (transport) {
|
|
1082
1069
|
if (this.monitorTokens.get(uuid) === transport.monitorToken) {
|
|
1083
1070
|
this.monitorTokens.delete(uuid);
|
|
@@ -1088,28 +1075,28 @@ class ReactNativeBleTransport {
|
|
|
1088
1075
|
Log === null || Log === void 0 ? void 0 : Log.debug('release: removing notify subscription, characteristic: ', (_c = transport.notifyCharacteristic) === null || _c === void 0 ? void 0 : _c.uuid);
|
|
1089
1076
|
(_d = transport.notifySubscription) === null || _d === void 0 ? void 0 : _d.remove();
|
|
1090
1077
|
transport.notifySubscription = undefined;
|
|
1091
|
-
if (
|
|
1092
|
-
|
|
1078
|
+
if (transport.notifyTransactionId) {
|
|
1079
|
+
try {
|
|
1080
|
+
yield ((_e = this.blePlxManager) === null || _e === void 0 ? void 0 : _e.cancelTransaction(transport.notifyTransactionId));
|
|
1081
|
+
}
|
|
1082
|
+
catch (e) {
|
|
1083
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('release: cancel notify transaction error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
|
|
1084
|
+
}
|
|
1093
1085
|
}
|
|
1086
|
+
delete transportCache[uuid];
|
|
1094
1087
|
}
|
|
1095
1088
|
this.protocolV2HighVolumeLogSignatures.delete(uuid);
|
|
1096
1089
|
this.deviceProtocol.delete(uuid);
|
|
1097
1090
|
this.probingProtocols.delete(uuid);
|
|
1098
|
-
(
|
|
1091
|
+
(_f = this.protocolV2Assemblers.get(uuid)) === null || _f === void 0 ? void 0 : _f.reset();
|
|
1099
1092
|
this.protocolV2Assemblers.delete(uuid);
|
|
1100
1093
|
this.resetProtocolV2Frames(uuid);
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
}
|
|
1108
|
-
if (manager) {
|
|
1109
|
-
operations.push(this.runBestEffortNativeOperation('release: cancel transaction', () => manager.cancelTransaction(uuid)));
|
|
1110
|
-
}
|
|
1111
|
-
yield Promise.all(operations);
|
|
1112
|
-
}));
|
|
1094
|
+
try {
|
|
1095
|
+
yield ((_g = this.blePlxManager) === null || _g === void 0 ? void 0 : _g.cancelTransaction(uuid));
|
|
1096
|
+
}
|
|
1097
|
+
catch (e) {
|
|
1098
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('release: cancel transaction error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
|
|
1099
|
+
}
|
|
1113
1100
|
return Promise.resolve(true);
|
|
1114
1101
|
});
|
|
1115
1102
|
}
|
|
@@ -1344,16 +1331,10 @@ class ReactNativeBleTransport {
|
|
|
1344
1331
|
this.stopped = true;
|
|
1345
1332
|
}
|
|
1346
1333
|
disconnect(session) {
|
|
1347
|
-
|
|
1348
|
-
return this.runLifecycleOperation(session, () => this.disconnectUnlocked(session));
|
|
1349
|
-
});
|
|
1350
|
-
}
|
|
1351
|
-
disconnectUnlocked(session) {
|
|
1352
|
-
var _a, _b, _c;
|
|
1334
|
+
var _a, _b, _c, _d, _e;
|
|
1353
1335
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1354
1336
|
yield this.protocolV2Links.invalidateLink(session, 'React Native BLE transport disconnected');
|
|
1355
1337
|
const transport = transportCache[session];
|
|
1356
|
-
const manager = this.blePlxManager;
|
|
1357
1338
|
const monitorToken = (_a = transport === null || transport === void 0 ? void 0 : transport.monitorToken) !== null && _a !== void 0 ? _a : this.monitorTokens.get(session);
|
|
1358
1339
|
if (transport === null || transport === void 0 ? void 0 : transport.disconnectSubscription) {
|
|
1359
1340
|
try {
|
|
@@ -1375,7 +1356,29 @@ class ReactNativeBleTransport {
|
|
|
1375
1356
|
Log === null || Log === void 0 ? void 0 : Log.error('disconnect: remove notify subscription error: ', e);
|
|
1376
1357
|
}
|
|
1377
1358
|
}
|
|
1378
|
-
if (
|
|
1359
|
+
if (session) {
|
|
1360
|
+
try {
|
|
1361
|
+
yield ((_c = this.blePlxManager) === null || _c === void 0 ? void 0 : _c.cancelTransaction(session));
|
|
1362
|
+
}
|
|
1363
|
+
catch (e) {
|
|
1364
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('resetSession: cancel transaction error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
if (transport === null || transport === void 0 ? void 0 : transport.device) {
|
|
1368
|
+
try {
|
|
1369
|
+
yield transport.device.cancelConnection();
|
|
1370
|
+
}
|
|
1371
|
+
catch (e) {
|
|
1372
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('resetSession: device.cancelConnection error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
try {
|
|
1376
|
+
yield ((_d = this.blePlxManager) === null || _d === void 0 ? void 0 : _d.cancelDeviceConnection(session));
|
|
1377
|
+
}
|
|
1378
|
+
catch (e) {
|
|
1379
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('resetSession: manager.cancelDeviceConnection error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
|
|
1380
|
+
}
|
|
1381
|
+
if (transportCache[session]) {
|
|
1379
1382
|
delete transportCache[session];
|
|
1380
1383
|
}
|
|
1381
1384
|
this.deviceProtocol.delete(session);
|
|
@@ -1386,7 +1389,7 @@ class ReactNativeBleTransport {
|
|
|
1386
1389
|
this.protocolV2Assemblers.delete(session);
|
|
1387
1390
|
this.resetProtocolV2Frames(session);
|
|
1388
1391
|
try {
|
|
1389
|
-
this.emitDeviceDisconnect(session, (
|
|
1392
|
+
this.emitDeviceDisconnect(session, (_e = transport === null || transport === void 0 ? void 0 : transport.device) === null || _e === void 0 ? void 0 : _e.name, monitorToken);
|
|
1390
1393
|
}
|
|
1391
1394
|
catch (e) {
|
|
1392
1395
|
Log === null || Log === void 0 ? void 0 : Log.error('resetSession: emit disconnect event error: ', e);
|
|
@@ -1394,81 +1397,9 @@ class ReactNativeBleTransport {
|
|
|
1394
1397
|
if (monitorToken !== undefined && this.monitorTokens.get(session) === monitorToken) {
|
|
1395
1398
|
this.monitorTokens.delete(session);
|
|
1396
1399
|
}
|
|
1397
|
-
yield this.runNativeTeardown(session, manager, () => __awaiter(this, void 0, void 0, function* () {
|
|
1398
|
-
const operations = [];
|
|
1399
|
-
if (manager) {
|
|
1400
|
-
operations.push(this.runBestEffortNativeOperation('disconnect: cancel transaction', () => manager.cancelTransaction(session)));
|
|
1401
|
-
operations.push(this.runBestEffortNativeOperation('disconnect: cancel device connection', () => manager.cancelDeviceConnection(session)));
|
|
1402
|
-
}
|
|
1403
|
-
if (transport === null || transport === void 0 ? void 0 : transport.device) {
|
|
1404
|
-
operations.push(this.runBestEffortNativeOperation('disconnect: device cancel connection', () => transport.device.cancelConnection()));
|
|
1405
|
-
}
|
|
1406
|
-
yield Promise.all(operations);
|
|
1407
|
-
}));
|
|
1408
1400
|
yield new Promise(resolve => setTimeout(() => resolve(), 100));
|
|
1409
1401
|
});
|
|
1410
1402
|
}
|
|
1411
|
-
runNativeTeardown(uuid, manager, teardown) {
|
|
1412
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1413
|
-
let timer;
|
|
1414
|
-
let timedOut = false;
|
|
1415
|
-
const pending = Promise.resolve()
|
|
1416
|
-
.then(teardown)
|
|
1417
|
-
.catch(error => {
|
|
1418
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('BLE native teardown error (ignored): ', (error === null || error === void 0 ? void 0 : error.message) || error);
|
|
1419
|
-
});
|
|
1420
|
-
try {
|
|
1421
|
-
yield Promise.race([
|
|
1422
|
-
pending,
|
|
1423
|
-
new Promise(resolve => {
|
|
1424
|
-
timer = setTimeout(() => {
|
|
1425
|
-
timedOut = true;
|
|
1426
|
-
resolve();
|
|
1427
|
-
}, BLE_NATIVE_TEARDOWN_TIMEOUT_MS);
|
|
1428
|
-
}),
|
|
1429
|
-
]);
|
|
1430
|
-
}
|
|
1431
|
-
finally {
|
|
1432
|
-
if (timer)
|
|
1433
|
-
clearTimeout(timer);
|
|
1434
|
-
}
|
|
1435
|
-
if (timedOut) {
|
|
1436
|
-
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE native teardown timed out:', uuid);
|
|
1437
|
-
if (this.blePlxManager === manager) {
|
|
1438
|
-
this.resetPlxManager();
|
|
1439
|
-
}
|
|
1440
|
-
}
|
|
1441
|
-
});
|
|
1442
|
-
}
|
|
1443
|
-
runBestEffortNativeOperation(label, operation) {
|
|
1444
|
-
return Promise.resolve()
|
|
1445
|
-
.then(operation)
|
|
1446
|
-
.catch(error => {
|
|
1447
|
-
Log === null || Log === void 0 ? void 0 : Log.debug(`${label} error (ignored): `, (error === null || error === void 0 ? void 0 : error.message) || error);
|
|
1448
|
-
});
|
|
1449
|
-
}
|
|
1450
|
-
runLifecycleOperation(uuid, operation) {
|
|
1451
|
-
var _a;
|
|
1452
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1453
|
-
const previousOperation = (_a = this.lifecycleOperations.get(uuid)) !== null && _a !== void 0 ? _a : Promise.resolve();
|
|
1454
|
-
let completeOperation;
|
|
1455
|
-
const operationGate = new Promise(resolve => {
|
|
1456
|
-
completeOperation = resolve;
|
|
1457
|
-
});
|
|
1458
|
-
const operationTail = previousOperation.catch(() => undefined).then(() => operationGate);
|
|
1459
|
-
this.lifecycleOperations.set(uuid, operationTail);
|
|
1460
|
-
yield previousOperation.catch(() => undefined);
|
|
1461
|
-
try {
|
|
1462
|
-
return yield operation();
|
|
1463
|
-
}
|
|
1464
|
-
finally {
|
|
1465
|
-
completeOperation();
|
|
1466
|
-
if (this.lifecycleOperations.get(uuid) === operationTail) {
|
|
1467
|
-
this.lifecycleOperations.delete(uuid);
|
|
1468
|
-
}
|
|
1469
|
-
}
|
|
1470
|
-
});
|
|
1471
|
-
}
|
|
1472
1403
|
cancel() {
|
|
1473
1404
|
Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native transport cancel');
|
|
1474
1405
|
if (this.runPromise) ;
|
|
@@ -1627,34 +1558,8 @@ class ReactNativeBleTransport {
|
|
|
1627
1558
|
resetPlxManager() {
|
|
1628
1559
|
const manager = this.blePlxManager;
|
|
1629
1560
|
this.blePlxManager = undefined;
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
var _a, _b, _c, _d;
|
|
1633
|
-
try {
|
|
1634
|
-
(_a = cachedTransport.disconnectSubscription) === null || _a === void 0 ? void 0 : _a.remove();
|
|
1635
|
-
}
|
|
1636
|
-
catch (error) {
|
|
1637
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('BLE manager reset disconnect subscription removal failed:', error);
|
|
1638
|
-
}
|
|
1639
|
-
cachedTransport.disconnectSubscription = undefined;
|
|
1640
|
-
try {
|
|
1641
|
-
(_b = cachedTransport.notifySubscription) === null || _b === void 0 ? void 0 : _b.remove();
|
|
1642
|
-
}
|
|
1643
|
-
catch (error) {
|
|
1644
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('BLE manager reset notify subscription removal failed:', error);
|
|
1645
|
-
}
|
|
1646
|
-
cachedTransport.notifySubscription = undefined;
|
|
1647
|
-
this.rejectProtocolV2Frames(uuid, new Error(reason));
|
|
1648
|
-
try {
|
|
1649
|
-
this.emitDeviceDisconnect(uuid, (_c = cachedTransport.device) === null || _c === void 0 ? void 0 : _c.name, (_d = cachedTransport.monitorToken) !== null && _d !== void 0 ? _d : this.monitorTokens.get(uuid));
|
|
1650
|
-
}
|
|
1651
|
-
catch (error) {
|
|
1652
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('BLE manager reset disconnect event failed:', error);
|
|
1653
|
-
}
|
|
1654
|
-
delete transportCache[uuid];
|
|
1655
|
-
});
|
|
1656
|
-
this.protocolV2Links.invalidateAllLinks(reason).catch(error => {
|
|
1657
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE manager link invalidation failed:', error);
|
|
1561
|
+
Object.keys(transportCache).forEach(key => {
|
|
1562
|
+
delete transportCache[key];
|
|
1658
1563
|
});
|
|
1659
1564
|
this.deviceProtocol.clear();
|
|
1660
1565
|
this.probingProtocols.clear();
|
|
@@ -2156,8 +2061,6 @@ class ReactNativeBleTransport {
|
|
|
2156
2061
|
}),
|
|
2157
2062
|
reset: (reason) => {
|
|
2158
2063
|
var _a;
|
|
2159
|
-
if (this.monitorTokens.get(uuid) !== generation)
|
|
2160
|
-
return;
|
|
2161
2064
|
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
2162
2065
|
this.rejectProtocolV2Frames(uuid, new Error(reason));
|
|
2163
2066
|
},
|
|
@@ -2174,7 +2077,6 @@ class ReactNativeBleTransport {
|
|
|
2174
2077
|
exports.BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD = BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD;
|
|
2175
2078
|
exports.BLE_CONNECT_TIMEOUT_MS = BLE_CONNECT_TIMEOUT_MS;
|
|
2176
2079
|
exports.BLE_GATT_SETUP_TIMEOUT_MS = BLE_GATT_SETUP_TIMEOUT_MS;
|
|
2177
|
-
exports.BLE_NATIVE_TEARDOWN_TIMEOUT_MS = BLE_NATIVE_TEARDOWN_TIMEOUT_MS;
|
|
2178
2080
|
exports.BLE_WRITE_PACKET_TIMEOUT_MS = BLE_WRITE_PACKET_TIMEOUT_MS;
|
|
2179
2081
|
exports.BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD = BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD;
|
|
2180
2082
|
exports.PROTOCOL_REPROBE_FALLBACK_ATTEMPTS = PROTOCOL_REPROBE_FALLBACK_ATTEMPTS;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-transport-react-native",
|
|
3
|
-
"version": "1.2.0-alpha.133",
|
|
3
|
+
"version": "1.2.0-alpha.133-ok59992",
|
|
4
4
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
"lint:fix": "eslint . --fix"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@onekeyfe/hd-core": "1.2.0-alpha.133",
|
|
24
|
-
"@onekeyfe/hd-shared": "1.2.0-alpha.133",
|
|
25
|
-
"@onekeyfe/hd-transport": "1.2.0-alpha.133",
|
|
23
|
+
"@onekeyfe/hd-core": "1.2.0-alpha.133-ok59992",
|
|
24
|
+
"@onekeyfe/hd-shared": "1.2.0-alpha.133-ok59992",
|
|
25
|
+
"@onekeyfe/hd-transport": "1.2.0-alpha.133-ok59992",
|
|
26
26
|
"@onekeyfe/react-native-ble-utils": "^0.1.6",
|
|
27
27
|
"react-native-ble-plx": "3.5.1"
|
|
28
28
|
},
|
|
29
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "521eb4523f54abc5ceca28a48b7120158fea1ac0"
|
|
30
30
|
}
|
|
@@ -7,7 +7,6 @@ import transportPackage, {
|
|
|
7
7
|
import { HardwareErrorCode, createDeferred } from '@onekeyfe/hd-shared';
|
|
8
8
|
|
|
9
9
|
import ReactNativeBleTransport, {
|
|
10
|
-
BLE_NATIVE_TEARDOWN_TIMEOUT_MS,
|
|
11
10
|
BLE_WRITE_PACKET_TIMEOUT_MS,
|
|
12
11
|
configureProtocolV2BleTuning,
|
|
13
12
|
getFirmwareUploadWriteRetryType,
|
|
@@ -175,8 +174,6 @@ const createHarness = ({
|
|
|
175
174
|
devices: jest.fn(() => Promise.resolve([device])),
|
|
176
175
|
connectedDevices: jest.fn(() => Promise.resolve([])),
|
|
177
176
|
cancelTransaction: jest.fn(() => Promise.resolve()),
|
|
178
|
-
cancelDeviceConnection: jest.fn(() => Promise.resolve()),
|
|
179
|
-
destroy: jest.fn(),
|
|
180
177
|
};
|
|
181
178
|
const transport = new ReactNativeBleTransport({ scanTimeout: 1 });
|
|
182
179
|
const emitter = new EventEmitter();
|
|
@@ -195,7 +192,6 @@ const createHarness = ({
|
|
|
195
192
|
logger,
|
|
196
193
|
uuid,
|
|
197
194
|
device,
|
|
198
|
-
bleManager,
|
|
199
195
|
sentSeqs,
|
|
200
196
|
writeCharacteristic,
|
|
201
197
|
setShouldRespond(value: boolean) {
|
|
@@ -424,93 +420,6 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
|
|
|
424
420
|
await transport.release(uuid, true);
|
|
425
421
|
});
|
|
426
422
|
|
|
427
|
-
test('waits for an in-flight release before reacquiring the same device', async () => {
|
|
428
|
-
const { transport, uuid } = createHarness();
|
|
429
|
-
await transport.acquire({ uuid, expectedProtocol: 'V2' });
|
|
430
|
-
const releaseGate = createDeferred<void>();
|
|
431
|
-
const releaseStarted = createDeferred<void>();
|
|
432
|
-
const { protocolV2Links } = transport as any;
|
|
433
|
-
const invalidateLink = protocolV2Links.invalidateLink.bind(protocolV2Links);
|
|
434
|
-
jest
|
|
435
|
-
.spyOn(protocolV2Links, 'invalidateLink')
|
|
436
|
-
.mockImplementationOnce(async (...args: unknown[]) => {
|
|
437
|
-
releaseStarted.resolve();
|
|
438
|
-
await releaseGate.promise;
|
|
439
|
-
return invalidateLink(...args);
|
|
440
|
-
});
|
|
441
|
-
|
|
442
|
-
const release = transport.release(uuid, true);
|
|
443
|
-
await releaseStarted.promise;
|
|
444
|
-
let reacquired = false;
|
|
445
|
-
const acquire = transport.acquire({ uuid, expectedProtocol: 'V2' }).then(result => {
|
|
446
|
-
reacquired = true;
|
|
447
|
-
return result;
|
|
448
|
-
});
|
|
449
|
-
|
|
450
|
-
await Promise.resolve();
|
|
451
|
-
expect(reacquired).toBe(false);
|
|
452
|
-
|
|
453
|
-
releaseGate.resolve();
|
|
454
|
-
await release;
|
|
455
|
-
await expect(acquire).resolves.toEqual({ uuid, protocolType: 'V2' });
|
|
456
|
-
await expect(transport.call(uuid, 'Ping', { message: 'after-release' })).resolves.toMatchObject(
|
|
457
|
-
{
|
|
458
|
-
type: 'Success',
|
|
459
|
-
message: { message: 'ok' },
|
|
460
|
-
}
|
|
461
|
-
);
|
|
462
|
-
});
|
|
463
|
-
|
|
464
|
-
test(
|
|
465
|
-
'releases the lifecycle queue when native teardown never settles',
|
|
466
|
-
async () => {
|
|
467
|
-
const { transport, uuid, device, bleManager } = createHarness();
|
|
468
|
-
await transport.acquire({ uuid, expectedProtocol: 'V2' });
|
|
469
|
-
const otherUuid = 'rn-pro2-other-id';
|
|
470
|
-
const otherDevice = {
|
|
471
|
-
...device,
|
|
472
|
-
id: otherUuid,
|
|
473
|
-
name: 'OneKey Pro 2 Other',
|
|
474
|
-
localName: 'OneKey Pro 2 Other',
|
|
475
|
-
};
|
|
476
|
-
await (transport as any).installTransportForAcquire(otherUuid, otherDevice);
|
|
477
|
-
(transport as any).deviceProtocol.set(otherUuid, 'V2');
|
|
478
|
-
const disconnectEvents: Array<{ connectId: string }> = [];
|
|
479
|
-
transport.emitter?.on(TRANSPORT_EVENT.DEVICE_DISCONNECT, event => {
|
|
480
|
-
disconnectEvents.push(event);
|
|
481
|
-
});
|
|
482
|
-
const stalledNativeCleanup = createDeferred<void>();
|
|
483
|
-
bleManager.cancelTransaction
|
|
484
|
-
.mockImplementationOnce(() => stalledNativeCleanup.promise)
|
|
485
|
-
.mockResolvedValue(undefined);
|
|
486
|
-
const resetPlxManager = jest.spyOn(transport as any, 'resetPlxManager');
|
|
487
|
-
const nextLifecycleOperation = jest.fn().mockResolvedValue('next-operation');
|
|
488
|
-
|
|
489
|
-
const release = transport.release(uuid, true);
|
|
490
|
-
const nextOperation = (transport as any).runLifecycleOperation(uuid, nextLifecycleOperation);
|
|
491
|
-
|
|
492
|
-
await expect(release).resolves.toBe(true);
|
|
493
|
-
await expect(nextOperation).resolves.toBe('next-operation');
|
|
494
|
-
expect(resetPlxManager).toHaveBeenCalledTimes(1);
|
|
495
|
-
expect(nextLifecycleOperation).toHaveBeenCalledTimes(1);
|
|
496
|
-
expect(disconnectEvents).toContainEqual(expect.objectContaining({ connectId: otherUuid }));
|
|
497
|
-
expect(() => (transport as any).getCachedTransport(otherUuid)).toThrow();
|
|
498
|
-
|
|
499
|
-
await (transport as any).installTransportForAcquire(uuid, device);
|
|
500
|
-
(transport as any).deviceProtocol.set(uuid, 'V2');
|
|
501
|
-
|
|
502
|
-
stalledNativeCleanup.resolve();
|
|
503
|
-
await Promise.resolve();
|
|
504
|
-
await expect(
|
|
505
|
-
transport.call(uuid, 'Ping', { message: 'after-stale-cleanup' })
|
|
506
|
-
).resolves.toMatchObject({
|
|
507
|
-
type: 'Success',
|
|
508
|
-
message: { message: 'ok' },
|
|
509
|
-
});
|
|
510
|
-
},
|
|
511
|
-
BLE_NATIVE_TEARDOWN_TIMEOUT_MS + 5_000
|
|
512
|
-
);
|
|
513
|
-
|
|
514
423
|
test('falls back to the other active probe on iOS when protocol metadata is absent', async () => {
|
|
515
424
|
const { transport, uuid } = createHarness({ deviceName: 'OneKey' });
|
|
516
425
|
const probeProtocolV1 = jest
|
package/src/index.ts
CHANGED
|
@@ -149,7 +149,6 @@ const PROTOCOL_V2_PROBE_TIMEOUT_MS = 10_000;
|
|
|
149
149
|
* A healthy packet completes in milliseconds, so this only fires on a dead link.
|
|
150
150
|
*/
|
|
151
151
|
export const BLE_WRITE_PACKET_TIMEOUT_MS = 10_000;
|
|
152
|
-
export const BLE_NATIVE_TEARDOWN_TIMEOUT_MS = 3_000;
|
|
153
152
|
const WEDGED_WRITE_MESSAGE = 'BLE write timeout after';
|
|
154
153
|
const isWedgedWriteError = (error: unknown): boolean =>
|
|
155
154
|
(error as { errorCode?: unknown })?.errorCode === HardwareErrorCode.BleWriteCharacteristicError &&
|
|
@@ -423,9 +422,6 @@ export default class ReactNativeBleTransport {
|
|
|
423
422
|
|
|
424
423
|
private nextMonitorToken = 1;
|
|
425
424
|
|
|
426
|
-
/** Serializes transport lifecycle changes for the same physical device. */
|
|
427
|
-
private lifecycleOperations: Map<string, Promise<void>> = new Map();
|
|
428
|
-
|
|
429
425
|
constructor(options: TransportOptions) {
|
|
430
426
|
this.scanTimeout = options.scanTimeout ?? DEVICE_SCAN_TIMEOUT_MS;
|
|
431
427
|
}
|
|
@@ -864,18 +860,12 @@ export default class ReactNativeBleTransport {
|
|
|
864
860
|
}
|
|
865
861
|
|
|
866
862
|
async acquire(input: BleAcquireInput) {
|
|
867
|
-
const { uuid } = input;
|
|
863
|
+
const { uuid, forceCleanRunPromise, expectedProtocol } = input;
|
|
868
864
|
|
|
869
865
|
if (!uuid) {
|
|
870
866
|
throw ERRORS.TypedError(HardwareErrorCode.BleRequiredUUID);
|
|
871
867
|
}
|
|
872
868
|
|
|
873
|
-
return this.runLifecycleOperation(uuid, () => this.acquireUnlocked(input));
|
|
874
|
-
}
|
|
875
|
-
|
|
876
|
-
private async acquireUnlocked(input: BleAcquireInput) {
|
|
877
|
-
const { uuid, forceCleanRunPromise, expectedProtocol } = input;
|
|
878
|
-
|
|
879
869
|
const cachedTransport = transportCache[uuid];
|
|
880
870
|
if (cachedTransport) {
|
|
881
871
|
const cachedProtocol = this.deviceProtocol.get(uuid);
|
|
@@ -894,7 +884,7 @@ export default class ReactNativeBleTransport {
|
|
|
894
884
|
* connection, clean it up before creating a new transport instance.
|
|
895
885
|
*/
|
|
896
886
|
Log?.debug('transport not reusable, will release: ', uuid);
|
|
897
|
-
await this.
|
|
887
|
+
await this.release(uuid, true);
|
|
898
888
|
}
|
|
899
889
|
|
|
900
890
|
let device: Device | null = null;
|
|
@@ -1020,7 +1010,7 @@ export default class ReactNativeBleTransport {
|
|
|
1020
1010
|
inferProtocolHintFromDeviceName(getDeviceDisplayName(acquiredDevice));
|
|
1021
1011
|
|
|
1022
1012
|
// release transport before new transport instance
|
|
1023
|
-
await this.
|
|
1013
|
+
await this.release(uuid, true);
|
|
1024
1014
|
if (protocolHint) {
|
|
1025
1015
|
this.deviceProtocolHints.set(uuid, protocolHint);
|
|
1026
1016
|
}
|
|
@@ -1046,7 +1036,7 @@ export default class ReactNativeBleTransport {
|
|
|
1046
1036
|
this.attachDisconnectSubscription(currentTransport, currentTransport.device, uuid);
|
|
1047
1037
|
return { uuid, protocolType };
|
|
1048
1038
|
} catch (error) {
|
|
1049
|
-
await this.
|
|
1039
|
+
await this.release(uuid, true);
|
|
1050
1040
|
throw error;
|
|
1051
1041
|
}
|
|
1052
1042
|
}
|
|
@@ -1191,17 +1181,12 @@ export default class ReactNativeBleTransport {
|
|
|
1191
1181
|
}
|
|
1192
1182
|
|
|
1193
1183
|
async release(uuid: string, onclose = false) {
|
|
1194
|
-
return this.runLifecycleOperation(uuid, () => this.releaseUnlocked(uuid, onclose));
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
|
-
private async releaseUnlocked(uuid: string, onclose = false) {
|
|
1198
1184
|
await this.protocolV2Links.invalidateLink(uuid, 'React Native BLE transport released');
|
|
1199
1185
|
return this.releaseNative(uuid, onclose);
|
|
1200
1186
|
}
|
|
1201
1187
|
|
|
1202
1188
|
private async releaseNative(uuid: string, onclose = false) {
|
|
1203
1189
|
const transport = transportCache[uuid];
|
|
1204
|
-
const manager = this.blePlxManager;
|
|
1205
1190
|
if (this.runPromise && this.runPromiseDeviceId === uuid) {
|
|
1206
1191
|
const error = ERRORS.TypedError(HardwareErrorCode.BleForceCleanRunPromise);
|
|
1207
1192
|
this.runPromise.reject(error);
|
|
@@ -1218,6 +1203,8 @@ export default class ReactNativeBleTransport {
|
|
|
1218
1203
|
return Promise.resolve(true);
|
|
1219
1204
|
}
|
|
1220
1205
|
|
|
1206
|
+
await this.restoreAndroidConnectionPriority(uuid, transport);
|
|
1207
|
+
|
|
1221
1208
|
if (transport) {
|
|
1222
1209
|
if (this.monitorTokens.get(uuid) === transport.monitorToken) {
|
|
1223
1210
|
this.monitorTokens.delete(uuid);
|
|
@@ -1235,9 +1222,16 @@ export default class ReactNativeBleTransport {
|
|
|
1235
1222
|
);
|
|
1236
1223
|
transport.notifySubscription?.remove();
|
|
1237
1224
|
transport.notifySubscription = undefined;
|
|
1238
|
-
|
|
1239
|
-
|
|
1225
|
+
|
|
1226
|
+
if (transport.notifyTransactionId) {
|
|
1227
|
+
try {
|
|
1228
|
+
await this.blePlxManager?.cancelTransaction(transport.notifyTransactionId);
|
|
1229
|
+
} catch (e) {
|
|
1230
|
+
Log?.debug('release: cancel notify transaction error (ignored): ', e?.message || e);
|
|
1231
|
+
}
|
|
1240
1232
|
}
|
|
1233
|
+
|
|
1234
|
+
delete transportCache[uuid];
|
|
1241
1235
|
}
|
|
1242
1236
|
|
|
1243
1237
|
this.protocolV2HighVolumeLogSignatures.delete(uuid);
|
|
@@ -1249,28 +1243,11 @@ export default class ReactNativeBleTransport {
|
|
|
1249
1243
|
this.protocolV2Assemblers.delete(uuid);
|
|
1250
1244
|
this.resetProtocolV2Frames(uuid);
|
|
1251
1245
|
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
];
|
|
1258
|
-
if (transport?.notifyTransactionId && manager) {
|
|
1259
|
-
operations.push(
|
|
1260
|
-
this.runBestEffortNativeOperation('release: cancel notify transaction', () =>
|
|
1261
|
-
manager.cancelTransaction(transport.notifyTransactionId as string)
|
|
1262
|
-
)
|
|
1263
|
-
);
|
|
1264
|
-
}
|
|
1265
|
-
if (manager) {
|
|
1266
|
-
operations.push(
|
|
1267
|
-
this.runBestEffortNativeOperation('release: cancel transaction', () =>
|
|
1268
|
-
manager.cancelTransaction(uuid)
|
|
1269
|
-
)
|
|
1270
|
-
);
|
|
1271
|
-
}
|
|
1272
|
-
await Promise.all(operations);
|
|
1273
|
-
});
|
|
1246
|
+
try {
|
|
1247
|
+
await this.blePlxManager?.cancelTransaction(uuid);
|
|
1248
|
+
} catch (e) {
|
|
1249
|
+
Log?.debug('release: cancel transaction error (ignored): ', e?.message || e);
|
|
1250
|
+
}
|
|
1274
1251
|
|
|
1275
1252
|
return Promise.resolve(true);
|
|
1276
1253
|
}
|
|
@@ -1575,13 +1552,8 @@ export default class ReactNativeBleTransport {
|
|
|
1575
1552
|
}
|
|
1576
1553
|
|
|
1577
1554
|
async disconnect(session: string) {
|
|
1578
|
-
return this.runLifecycleOperation(session, () => this.disconnectUnlocked(session));
|
|
1579
|
-
}
|
|
1580
|
-
|
|
1581
|
-
private async disconnectUnlocked(session: string) {
|
|
1582
1555
|
await this.protocolV2Links.invalidateLink(session, 'React Native BLE transport disconnected');
|
|
1583
1556
|
const transport = transportCache[session];
|
|
1584
|
-
const manager = this.blePlxManager;
|
|
1585
1557
|
const monitorToken = transport?.monitorToken ?? this.monitorTokens.get(session);
|
|
1586
1558
|
|
|
1587
1559
|
// Clean up disconnect subscription first to prevent onDisconnected callback
|
|
@@ -1610,8 +1582,33 @@ export default class ReactNativeBleTransport {
|
|
|
1610
1582
|
}
|
|
1611
1583
|
}
|
|
1612
1584
|
|
|
1585
|
+
// cancel the ble transaction
|
|
1586
|
+
if (session) {
|
|
1587
|
+
try {
|
|
1588
|
+
await this.blePlxManager?.cancelTransaction(session);
|
|
1589
|
+
} catch (e) {
|
|
1590
|
+
Log?.debug('resetSession: cancel transaction error (ignored): ', e?.message || e);
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
// disconnect the device via the device object
|
|
1595
|
+
if (transport?.device) {
|
|
1596
|
+
try {
|
|
1597
|
+
await transport.device.cancelConnection();
|
|
1598
|
+
} catch (e) {
|
|
1599
|
+
Log?.debug('resetSession: device.cancelConnection error (ignored): ', e?.message || e);
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1603
|
+
// disconnect the device via the ble manager
|
|
1604
|
+
try {
|
|
1605
|
+
await this.blePlxManager?.cancelDeviceConnection(session);
|
|
1606
|
+
} catch (e) {
|
|
1607
|
+
Log?.debug('resetSession: manager.cancelDeviceConnection error (ignored): ', e?.message || e);
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1613
1610
|
// clear the transport cache
|
|
1614
|
-
if (
|
|
1611
|
+
if (transportCache[session]) {
|
|
1615
1612
|
delete transportCache[session];
|
|
1616
1613
|
}
|
|
1617
1614
|
this.deviceProtocol.delete(session);
|
|
@@ -1631,97 +1628,10 @@ export default class ReactNativeBleTransport {
|
|
|
1631
1628
|
if (monitorToken !== undefined && this.monitorTokens.get(session) === monitorToken) {
|
|
1632
1629
|
this.monitorTokens.delete(session);
|
|
1633
1630
|
}
|
|
1634
|
-
|
|
1635
|
-
await this.runNativeTeardown(session, manager, async () => {
|
|
1636
|
-
const operations: Promise<unknown>[] = [];
|
|
1637
|
-
if (manager) {
|
|
1638
|
-
operations.push(
|
|
1639
|
-
this.runBestEffortNativeOperation('disconnect: cancel transaction', () =>
|
|
1640
|
-
manager.cancelTransaction(session)
|
|
1641
|
-
)
|
|
1642
|
-
);
|
|
1643
|
-
operations.push(
|
|
1644
|
-
this.runBestEffortNativeOperation('disconnect: cancel device connection', () =>
|
|
1645
|
-
manager.cancelDeviceConnection(session)
|
|
1646
|
-
)
|
|
1647
|
-
);
|
|
1648
|
-
}
|
|
1649
|
-
if (transport?.device) {
|
|
1650
|
-
operations.push(
|
|
1651
|
-
this.runBestEffortNativeOperation('disconnect: device cancel connection', () =>
|
|
1652
|
-
transport.device.cancelConnection()
|
|
1653
|
-
)
|
|
1654
|
-
);
|
|
1655
|
-
}
|
|
1656
|
-
await Promise.all(operations);
|
|
1657
|
-
});
|
|
1658
|
-
|
|
1659
1631
|
// eslint-disable-next-line no-promise-executor-return
|
|
1660
1632
|
await new Promise<void>(resolve => setTimeout(() => resolve(), 100));
|
|
1661
1633
|
}
|
|
1662
1634
|
|
|
1663
|
-
private async runNativeTeardown(
|
|
1664
|
-
uuid: string,
|
|
1665
|
-
manager: BlePlxManager | undefined,
|
|
1666
|
-
teardown: () => Promise<void>
|
|
1667
|
-
) {
|
|
1668
|
-
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
1669
|
-
let timedOut = false;
|
|
1670
|
-
const pending = Promise.resolve()
|
|
1671
|
-
.then(teardown)
|
|
1672
|
-
.catch(error => {
|
|
1673
|
-
Log?.debug('BLE native teardown error (ignored): ', error?.message || error);
|
|
1674
|
-
});
|
|
1675
|
-
try {
|
|
1676
|
-
await Promise.race([
|
|
1677
|
-
pending,
|
|
1678
|
-
new Promise<void>(resolve => {
|
|
1679
|
-
timer = setTimeout(() => {
|
|
1680
|
-
timedOut = true;
|
|
1681
|
-
resolve();
|
|
1682
|
-
}, BLE_NATIVE_TEARDOWN_TIMEOUT_MS);
|
|
1683
|
-
}),
|
|
1684
|
-
]);
|
|
1685
|
-
} finally {
|
|
1686
|
-
if (timer) clearTimeout(timer);
|
|
1687
|
-
}
|
|
1688
|
-
|
|
1689
|
-
if (timedOut) {
|
|
1690
|
-
Log?.error('[ReactNativeBleTransport] BLE native teardown timed out:', uuid);
|
|
1691
|
-
if (this.blePlxManager === manager) {
|
|
1692
|
-
this.resetPlxManager();
|
|
1693
|
-
}
|
|
1694
|
-
}
|
|
1695
|
-
}
|
|
1696
|
-
|
|
1697
|
-
private runBestEffortNativeOperation(label: string, operation: () => Promise<unknown>) {
|
|
1698
|
-
return Promise.resolve()
|
|
1699
|
-
.then(operation)
|
|
1700
|
-
.catch(error => {
|
|
1701
|
-
Log?.debug(`${label} error (ignored): `, error?.message || error);
|
|
1702
|
-
});
|
|
1703
|
-
}
|
|
1704
|
-
|
|
1705
|
-
private async runLifecycleOperation<T>(uuid: string, operation: () => Promise<T>): Promise<T> {
|
|
1706
|
-
const previousOperation = this.lifecycleOperations.get(uuid) ?? Promise.resolve();
|
|
1707
|
-
let completeOperation!: () => void;
|
|
1708
|
-
const operationGate = new Promise<void>(resolve => {
|
|
1709
|
-
completeOperation = resolve;
|
|
1710
|
-
});
|
|
1711
|
-
const operationTail = previousOperation.catch(() => undefined).then(() => operationGate);
|
|
1712
|
-
this.lifecycleOperations.set(uuid, operationTail);
|
|
1713
|
-
|
|
1714
|
-
await previousOperation.catch(() => undefined);
|
|
1715
|
-
try {
|
|
1716
|
-
return await operation();
|
|
1717
|
-
} finally {
|
|
1718
|
-
completeOperation();
|
|
1719
|
-
if (this.lifecycleOperations.get(uuid) === operationTail) {
|
|
1720
|
-
this.lifecycleOperations.delete(uuid);
|
|
1721
|
-
}
|
|
1722
|
-
}
|
|
1723
|
-
}
|
|
1724
|
-
|
|
1725
1635
|
cancel() {
|
|
1726
1636
|
Log?.debug('transport-react-native transport cancel');
|
|
1727
1637
|
if (this.runPromise) {
|
|
@@ -1930,37 +1840,9 @@ export default class ReactNativeBleTransport {
|
|
|
1930
1840
|
private resetPlxManager() {
|
|
1931
1841
|
const manager = this.blePlxManager;
|
|
1932
1842
|
this.blePlxManager = undefined;
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
// silently stale connection for an unrelated device.
|
|
1937
|
-
Object.entries(transportCache).forEach(([uuid, cachedTransport]) => {
|
|
1938
|
-
try {
|
|
1939
|
-
cachedTransport.disconnectSubscription?.remove();
|
|
1940
|
-
} catch (error) {
|
|
1941
|
-
Log?.debug('BLE manager reset disconnect subscription removal failed:', error);
|
|
1942
|
-
}
|
|
1943
|
-
cachedTransport.disconnectSubscription = undefined;
|
|
1944
|
-
try {
|
|
1945
|
-
cachedTransport.notifySubscription?.remove();
|
|
1946
|
-
} catch (error) {
|
|
1947
|
-
Log?.debug('BLE manager reset notify subscription removal failed:', error);
|
|
1948
|
-
}
|
|
1949
|
-
cachedTransport.notifySubscription = undefined;
|
|
1950
|
-
this.rejectProtocolV2Frames(uuid, new Error(reason));
|
|
1951
|
-
try {
|
|
1952
|
-
this.emitDeviceDisconnect(
|
|
1953
|
-
uuid,
|
|
1954
|
-
cachedTransport.device?.name,
|
|
1955
|
-
cachedTransport.monitorToken ?? this.monitorTokens.get(uuid)
|
|
1956
|
-
);
|
|
1957
|
-
} catch (error) {
|
|
1958
|
-
Log?.debug('BLE manager reset disconnect event failed:', error);
|
|
1959
|
-
}
|
|
1960
|
-
delete transportCache[uuid];
|
|
1961
|
-
});
|
|
1962
|
-
this.protocolV2Links.invalidateAllLinks(reason).catch(error => {
|
|
1963
|
-
Log?.debug('[ReactNativeBleTransport] BLE manager link invalidation failed:', error);
|
|
1843
|
+
// Every cached transport belongs to the destroyed manager's peripherals.
|
|
1844
|
+
Object.keys(transportCache).forEach(key => {
|
|
1845
|
+
delete transportCache[key];
|
|
1964
1846
|
});
|
|
1965
1847
|
this.deviceProtocol.clear();
|
|
1966
1848
|
this.probingProtocols.clear();
|
|
@@ -2562,7 +2444,6 @@ export default class ReactNativeBleTransport {
|
|
|
2562
2444
|
return rxFrame;
|
|
2563
2445
|
},
|
|
2564
2446
|
reset: (reason: string) => {
|
|
2565
|
-
if (this.monitorTokens.get(uuid) !== generation) return;
|
|
2566
2447
|
this.protocolV2Assemblers.get(uuid)?.reset();
|
|
2567
2448
|
this.rejectProtocolV2Frames(uuid, new Error(reason));
|
|
2568
2449
|
},
|