@onekeyfe/hd-transport-react-native 1.2.0-alpha.130 → 1.2.0-alpha.131

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 CHANGED
@@ -53,6 +53,7 @@ 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;
56
57
  /** Consecutive wedged writes on one device before the BLE manager itself is recreated. */
57
58
  declare const BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD = 2;
58
59
  type ProtocolV2BleTuning = {
@@ -166,6 +167,8 @@ declare class ReactNativeBleTransport {
166
167
  stop(): void;
167
168
  disconnect(session: string): Promise<void>;
168
169
  private disconnectUnlocked;
170
+ private runNativeTeardown;
171
+ private runBestEffortNativeOperation;
169
172
  private runLifecycleOperation;
170
173
  cancel(): void;
171
174
  /** Run a native connect under the JS backstop budget. */
@@ -221,4 +224,4 @@ declare class ReactNativeBleTransport {
221
224
  getProtocolType(path: string): ProtocolType | undefined;
222
225
  }
223
226
 
224
- 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 };
227
+ export { BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD, BLE_CONNECT_TIMEOUT_MS, BLE_GATT_SETUP_TIMEOUT_MS, BLE_NATIVE_TEARDOWN_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 };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -277,6 +277,7 @@ 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;
280
281
  const WEDGED_WRITE_MESSAGE = 'BLE write timeout after';
281
282
  const isWedgedWriteError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleWriteCharacteristicError &&
282
283
  typeof (error === null || error === void 0 ? void 0 : error.message) === 'string' &&
@@ -1058,9 +1059,10 @@ class ReactNativeBleTransport {
1058
1059
  });
1059
1060
  }
1060
1061
  releaseNative(uuid, onclose = false) {
1061
- var _a, _b, _c, _d, _e, _f, _g;
1062
+ var _a, _b, _c, _d, _e;
1062
1063
  return __awaiter(this, void 0, void 0, function* () {
1063
1064
  const transport = transportCache[uuid];
1065
+ const manager = this.blePlxManager;
1064
1066
  if (this.runPromise && this.runPromiseDeviceId === uuid) {
1065
1067
  const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
1066
1068
  this.runPromise.reject(error);
@@ -1076,7 +1078,6 @@ class ReactNativeBleTransport {
1076
1078
  this.resetProtocolV2Frames(uuid);
1077
1079
  return Promise.resolve(true);
1078
1080
  }
1079
- yield this.restoreAndroidConnectionPriority(uuid, transport);
1080
1081
  if (transport) {
1081
1082
  if (this.monitorTokens.get(uuid) === transport.monitorToken) {
1082
1083
  this.monitorTokens.delete(uuid);
@@ -1087,28 +1088,28 @@ class ReactNativeBleTransport {
1087
1088
  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);
1088
1089
  (_d = transport.notifySubscription) === null || _d === void 0 ? void 0 : _d.remove();
1089
1090
  transport.notifySubscription = undefined;
1090
- if (transport.notifyTransactionId) {
1091
- try {
1092
- yield ((_e = this.blePlxManager) === null || _e === void 0 ? void 0 : _e.cancelTransaction(transport.notifyTransactionId));
1093
- }
1094
- catch (e) {
1095
- 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);
1096
- }
1091
+ if (transportCache[uuid] === transport) {
1092
+ delete transportCache[uuid];
1097
1093
  }
1098
- delete transportCache[uuid];
1099
1094
  }
1100
1095
  this.protocolV2HighVolumeLogSignatures.delete(uuid);
1101
1096
  this.deviceProtocol.delete(uuid);
1102
1097
  this.probingProtocols.delete(uuid);
1103
- (_f = this.protocolV2Assemblers.get(uuid)) === null || _f === void 0 ? void 0 : _f.reset();
1098
+ (_e = this.protocolV2Assemblers.get(uuid)) === null || _e === void 0 ? void 0 : _e.reset();
1104
1099
  this.protocolV2Assemblers.delete(uuid);
1105
1100
  this.resetProtocolV2Frames(uuid);
1106
- try {
1107
- yield ((_g = this.blePlxManager) === null || _g === void 0 ? void 0 : _g.cancelTransaction(uuid));
1108
- }
1109
- catch (e) {
1110
- Log === null || Log === void 0 ? void 0 : Log.debug('release: cancel transaction error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
1111
- }
1101
+ yield this.runNativeTeardown(uuid, manager, () => __awaiter(this, void 0, void 0, function* () {
1102
+ const operations = [
1103
+ this.runBestEffortNativeOperation('release: restore connection priority', () => this.restoreAndroidConnectionPriority(uuid, transport)),
1104
+ ];
1105
+ if ((transport === null || transport === void 0 ? void 0 : transport.notifyTransactionId) && manager) {
1106
+ operations.push(this.runBestEffortNativeOperation('release: cancel notify transaction', () => manager.cancelTransaction(transport.notifyTransactionId)));
1107
+ }
1108
+ if (manager) {
1109
+ operations.push(this.runBestEffortNativeOperation('release: cancel transaction', () => manager.cancelTransaction(uuid)));
1110
+ }
1111
+ yield Promise.all(operations);
1112
+ }));
1112
1113
  return Promise.resolve(true);
1113
1114
  });
1114
1115
  }
@@ -1348,10 +1349,11 @@ class ReactNativeBleTransport {
1348
1349
  });
1349
1350
  }
1350
1351
  disconnectUnlocked(session) {
1351
- var _a, _b, _c, _d, _e;
1352
+ var _a, _b, _c;
1352
1353
  return __awaiter(this, void 0, void 0, function* () {
1353
1354
  yield this.protocolV2Links.invalidateLink(session, 'React Native BLE transport disconnected');
1354
1355
  const transport = transportCache[session];
1356
+ const manager = this.blePlxManager;
1355
1357
  const monitorToken = (_a = transport === null || transport === void 0 ? void 0 : transport.monitorToken) !== null && _a !== void 0 ? _a : this.monitorTokens.get(session);
1356
1358
  if (transport === null || transport === void 0 ? void 0 : transport.disconnectSubscription) {
1357
1359
  try {
@@ -1373,29 +1375,7 @@ class ReactNativeBleTransport {
1373
1375
  Log === null || Log === void 0 ? void 0 : Log.error('disconnect: remove notify subscription error: ', e);
1374
1376
  }
1375
1377
  }
1376
- if (session) {
1377
- try {
1378
- yield ((_c = this.blePlxManager) === null || _c === void 0 ? void 0 : _c.cancelTransaction(session));
1379
- }
1380
- catch (e) {
1381
- Log === null || Log === void 0 ? void 0 : Log.debug('resetSession: cancel transaction error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
1382
- }
1383
- }
1384
- if (transport === null || transport === void 0 ? void 0 : transport.device) {
1385
- try {
1386
- yield transport.device.cancelConnection();
1387
- }
1388
- catch (e) {
1389
- Log === null || Log === void 0 ? void 0 : Log.debug('resetSession: device.cancelConnection error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
1390
- }
1391
- }
1392
- try {
1393
- yield ((_d = this.blePlxManager) === null || _d === void 0 ? void 0 : _d.cancelDeviceConnection(session));
1394
- }
1395
- catch (e) {
1396
- Log === null || Log === void 0 ? void 0 : Log.debug('resetSession: manager.cancelDeviceConnection error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
1397
- }
1398
- if (transportCache[session]) {
1378
+ if (!transport || transportCache[session] === transport) {
1399
1379
  delete transportCache[session];
1400
1380
  }
1401
1381
  this.deviceProtocol.delete(session);
@@ -1406,7 +1386,7 @@ class ReactNativeBleTransport {
1406
1386
  this.protocolV2Assemblers.delete(session);
1407
1387
  this.resetProtocolV2Frames(session);
1408
1388
  try {
1409
- this.emitDeviceDisconnect(session, (_e = transport === null || transport === void 0 ? void 0 : transport.device) === null || _e === void 0 ? void 0 : _e.name, monitorToken);
1389
+ this.emitDeviceDisconnect(session, (_c = transport === null || transport === void 0 ? void 0 : transport.device) === null || _c === void 0 ? void 0 : _c.name, monitorToken);
1410
1390
  }
1411
1391
  catch (e) {
1412
1392
  Log === null || Log === void 0 ? void 0 : Log.error('resetSession: emit disconnect event error: ', e);
@@ -1414,9 +1394,59 @@ class ReactNativeBleTransport {
1414
1394
  if (monitorToken !== undefined && this.monitorTokens.get(session) === monitorToken) {
1415
1395
  this.monitorTokens.delete(session);
1416
1396
  }
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
+ }));
1417
1408
  yield new Promise(resolve => setTimeout(() => resolve(), 100));
1418
1409
  });
1419
1410
  }
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
+ }
1420
1450
  runLifecycleOperation(uuid, operation) {
1421
1451
  var _a;
1422
1452
  return __awaiter(this, void 0, void 0, function* () {
@@ -2100,6 +2130,8 @@ class ReactNativeBleTransport {
2100
2130
  }),
2101
2131
  reset: (reason) => {
2102
2132
  var _a;
2133
+ if (this.monitorTokens.get(uuid) !== generation)
2134
+ return;
2103
2135
  (_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
2104
2136
  this.rejectProtocolV2Frames(uuid, new Error(reason));
2105
2137
  },
@@ -2116,6 +2148,7 @@ class ReactNativeBleTransport {
2116
2148
  exports.BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD = BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD;
2117
2149
  exports.BLE_CONNECT_TIMEOUT_MS = BLE_CONNECT_TIMEOUT_MS;
2118
2150
  exports.BLE_GATT_SETUP_TIMEOUT_MS = BLE_GATT_SETUP_TIMEOUT_MS;
2151
+ exports.BLE_NATIVE_TEARDOWN_TIMEOUT_MS = BLE_NATIVE_TEARDOWN_TIMEOUT_MS;
2119
2152
  exports.BLE_WRITE_PACKET_TIMEOUT_MS = BLE_WRITE_PACKET_TIMEOUT_MS;
2120
2153
  exports.BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD = BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD;
2121
2154
  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.130",
3
+ "version": "1.2.0-alpha.131",
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.130",
24
- "@onekeyfe/hd-shared": "1.2.0-alpha.130",
25
- "@onekeyfe/hd-transport": "1.2.0-alpha.130",
23
+ "@onekeyfe/hd-core": "1.2.0-alpha.131",
24
+ "@onekeyfe/hd-shared": "1.2.0-alpha.131",
25
+ "@onekeyfe/hd-transport": "1.2.0-alpha.131",
26
26
  "@onekeyfe/react-native-ble-utils": "^0.1.6",
27
27
  "react-native-ble-plx": "3.5.1"
28
28
  },
29
- "gitHead": "287003096bc4df3a5824f2bea77e50f7fdc20565"
29
+ "gitHead": "81b472e983e80e6aa771b991dc9c0c9b1bdcf07b"
30
30
  }
@@ -7,6 +7,7 @@ import transportPackage, {
7
7
  import { HardwareErrorCode, createDeferred } from '@onekeyfe/hd-shared';
8
8
 
9
9
  import ReactNativeBleTransport, {
10
+ BLE_NATIVE_TEARDOWN_TIMEOUT_MS,
10
11
  BLE_WRITE_PACKET_TIMEOUT_MS,
11
12
  configureProtocolV2BleTuning,
12
13
  getFirmwareUploadWriteRetryType,
@@ -174,6 +175,8 @@ const createHarness = ({
174
175
  devices: jest.fn(() => Promise.resolve([device])),
175
176
  connectedDevices: jest.fn(() => Promise.resolve([])),
176
177
  cancelTransaction: jest.fn(() => Promise.resolve()),
178
+ cancelDeviceConnection: jest.fn(() => Promise.resolve()),
179
+ destroy: jest.fn(),
177
180
  };
178
181
  const transport = new ReactNativeBleTransport({ scanTimeout: 1 });
179
182
  const emitter = new EventEmitter();
@@ -192,6 +195,7 @@ const createHarness = ({
192
195
  logger,
193
196
  uuid,
194
197
  device,
198
+ bleManager,
195
199
  sentSeqs,
196
200
  writeCharacteristic,
197
201
  setShouldRespond(value: boolean) {
@@ -457,6 +461,41 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
457
461
  );
458
462
  });
459
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 stalledNativeCleanup = createDeferred<void>();
470
+ bleManager.cancelTransaction
471
+ .mockImplementationOnce(() => stalledNativeCleanup.promise)
472
+ .mockResolvedValue(undefined);
473
+ const resetPlxManager = jest.spyOn(transport as any, 'resetPlxManager');
474
+ const nextLifecycleOperation = jest.fn().mockResolvedValue('next-operation');
475
+
476
+ const release = transport.release(uuid, true);
477
+ const nextOperation = (transport as any).runLifecycleOperation(uuid, nextLifecycleOperation);
478
+
479
+ await expect(release).resolves.toBe(true);
480
+ await expect(nextOperation).resolves.toBe('next-operation');
481
+ expect(resetPlxManager).toHaveBeenCalledTimes(1);
482
+ expect(nextLifecycleOperation).toHaveBeenCalledTimes(1);
483
+
484
+ await (transport as any).installTransportForAcquire(uuid, device);
485
+ (transport as any).deviceProtocol.set(uuid, 'V2');
486
+
487
+ stalledNativeCleanup.resolve();
488
+ await Promise.resolve();
489
+ await expect(
490
+ transport.call(uuid, 'Ping', { message: 'after-stale-cleanup' })
491
+ ).resolves.toMatchObject({
492
+ type: 'Success',
493
+ message: { message: 'ok' },
494
+ });
495
+ },
496
+ BLE_NATIVE_TEARDOWN_TIMEOUT_MS + 5_000
497
+ );
498
+
460
499
  test('falls back to the other active probe on iOS when protocol metadata is absent', async () => {
461
500
  const { transport, uuid } = createHarness({ deviceName: 'OneKey' });
462
501
  const probeProtocolV1 = jest
package/src/index.ts CHANGED
@@ -149,6 +149,7 @@ 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;
152
153
  const WEDGED_WRITE_MESSAGE = 'BLE write timeout after';
153
154
  const isWedgedWriteError = (error: unknown): boolean =>
154
155
  (error as { errorCode?: unknown })?.errorCode === HardwareErrorCode.BleWriteCharacteristicError &&
@@ -1200,6 +1201,7 @@ export default class ReactNativeBleTransport {
1200
1201
 
1201
1202
  private async releaseNative(uuid: string, onclose = false) {
1202
1203
  const transport = transportCache[uuid];
1204
+ const manager = this.blePlxManager;
1203
1205
  if (this.runPromise && this.runPromiseDeviceId === uuid) {
1204
1206
  const error = ERRORS.TypedError(HardwareErrorCode.BleForceCleanRunPromise);
1205
1207
  this.runPromise.reject(error);
@@ -1216,8 +1218,6 @@ export default class ReactNativeBleTransport {
1216
1218
  return Promise.resolve(true);
1217
1219
  }
1218
1220
 
1219
- await this.restoreAndroidConnectionPriority(uuid, transport);
1220
-
1221
1221
  if (transport) {
1222
1222
  if (this.monitorTokens.get(uuid) === transport.monitorToken) {
1223
1223
  this.monitorTokens.delete(uuid);
@@ -1235,16 +1235,9 @@ export default class ReactNativeBleTransport {
1235
1235
  );
1236
1236
  transport.notifySubscription?.remove();
1237
1237
  transport.notifySubscription = undefined;
1238
-
1239
- if (transport.notifyTransactionId) {
1240
- try {
1241
- await this.blePlxManager?.cancelTransaction(transport.notifyTransactionId);
1242
- } catch (e) {
1243
- Log?.debug('release: cancel notify transaction error (ignored): ', e?.message || e);
1244
- }
1238
+ if (transportCache[uuid] === transport) {
1239
+ delete transportCache[uuid];
1245
1240
  }
1246
-
1247
- delete transportCache[uuid];
1248
1241
  }
1249
1242
 
1250
1243
  this.protocolV2HighVolumeLogSignatures.delete(uuid);
@@ -1256,11 +1249,28 @@ export default class ReactNativeBleTransport {
1256
1249
  this.protocolV2Assemblers.delete(uuid);
1257
1250
  this.resetProtocolV2Frames(uuid);
1258
1251
 
1259
- try {
1260
- await this.blePlxManager?.cancelTransaction(uuid);
1261
- } catch (e) {
1262
- Log?.debug('release: cancel transaction error (ignored): ', e?.message || e);
1263
- }
1252
+ await this.runNativeTeardown(uuid, manager, async () => {
1253
+ const operations: Promise<unknown>[] = [
1254
+ this.runBestEffortNativeOperation('release: restore connection priority', () =>
1255
+ this.restoreAndroidConnectionPriority(uuid, transport)
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
+ });
1264
1274
 
1265
1275
  return Promise.resolve(true);
1266
1276
  }
@@ -1571,6 +1581,7 @@ export default class ReactNativeBleTransport {
1571
1581
  private async disconnectUnlocked(session: string) {
1572
1582
  await this.protocolV2Links.invalidateLink(session, 'React Native BLE transport disconnected');
1573
1583
  const transport = transportCache[session];
1584
+ const manager = this.blePlxManager;
1574
1585
  const monitorToken = transport?.monitorToken ?? this.monitorTokens.get(session);
1575
1586
 
1576
1587
  // Clean up disconnect subscription first to prevent onDisconnected callback
@@ -1599,33 +1610,8 @@ export default class ReactNativeBleTransport {
1599
1610
  }
1600
1611
  }
1601
1612
 
1602
- // cancel the ble transaction
1603
- if (session) {
1604
- try {
1605
- await this.blePlxManager?.cancelTransaction(session);
1606
- } catch (e) {
1607
- Log?.debug('resetSession: cancel transaction error (ignored): ', e?.message || e);
1608
- }
1609
- }
1610
-
1611
- // disconnect the device via the device object
1612
- if (transport?.device) {
1613
- try {
1614
- await transport.device.cancelConnection();
1615
- } catch (e) {
1616
- Log?.debug('resetSession: device.cancelConnection error (ignored): ', e?.message || e);
1617
- }
1618
- }
1619
-
1620
- // disconnect the device via the ble manager
1621
- try {
1622
- await this.blePlxManager?.cancelDeviceConnection(session);
1623
- } catch (e) {
1624
- Log?.debug('resetSession: manager.cancelDeviceConnection error (ignored): ', e?.message || e);
1625
- }
1626
-
1627
1613
  // clear the transport cache
1628
- if (transportCache[session]) {
1614
+ if (!transport || transportCache[session] === transport) {
1629
1615
  delete transportCache[session];
1630
1616
  }
1631
1617
  this.deviceProtocol.delete(session);
@@ -1645,10 +1631,77 @@ export default class ReactNativeBleTransport {
1645
1631
  if (monitorToken !== undefined && this.monitorTokens.get(session) === monitorToken) {
1646
1632
  this.monitorTokens.delete(session);
1647
1633
  }
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
+
1648
1659
  // eslint-disable-next-line no-promise-executor-return
1649
1660
  await new Promise<void>(resolve => setTimeout(() => resolve(), 100));
1650
1661
  }
1651
1662
 
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
+
1652
1705
  private async runLifecycleOperation<T>(uuid: string, operation: () => Promise<T>): Promise<T> {
1653
1706
  const previousOperation = this.lifecycleOperations.get(uuid) ?? Promise.resolve();
1654
1707
  let completeOperation!: () => void;
@@ -2481,6 +2534,7 @@ export default class ReactNativeBleTransport {
2481
2534
  return rxFrame;
2482
2535
  },
2483
2536
  reset: (reason: string) => {
2537
+ if (this.monitorTokens.get(uuid) !== generation) return;
2484
2538
  this.protocolV2Assemblers.get(uuid)?.reset();
2485
2539
  this.rejectProtocolV2Frames(uuid, new Error(reason));
2486
2540
  },